mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-01 00:19:33 +00:00
383 lines
9.8 KiB
Lua
383 lines
9.8 KiB
Lua
--
|
|
-- (C) 2013-23 - ntop.org
|
|
--
|
|
|
|
--
|
|
-- This file implements some utility functions used by the REST API
|
|
-- in the vulnerability pages
|
|
--
|
|
--
|
|
-- https://geekflare.com/nmap-vulnerability-scan/
|
|
-- cd /usr/share/nmap/scripts/
|
|
-- git clone https://github.com/scipag/vulscan.git
|
|
-- ln -s `pwd`/scipag_vulscan /usr/share/nmap/scripts/vulscan
|
|
-- cd vulscan/utilities/updater/
|
|
-- chmod +x updateFiles.sh
|
|
-- ./updateFiles.sh
|
|
--
|
|
-- Example:
|
|
-- nmap -sV --script vulscan --script-args vulscandb=openvas.csv <target> -p 80,233
|
|
--
|
|
--
|
|
-- exploitdb.csv
|
|
-- osvdb.csv
|
|
-- securitytracker.csv
|
|
-- openvas.csv
|
|
-- scipvuldb.csv
|
|
-- xforce.csv
|
|
-- securityfocus.csv
|
|
-- cve.csv
|
|
--
|
|
|
|
-- **********************************************************
|
|
|
|
local dirs = ntop.getDirs()
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|
package.path = dirs.installdir .. "/scripts/lua/pro/modules/?.lua;" .. package.path
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/vulnerability_scan/?.lua;" .. package.path
|
|
|
|
require "lua_utils" -- used by tprint (debug)
|
|
|
|
local host_to_scan_key = "ntopng.prefs.host_to_scan"
|
|
local host_scan_queue_key = "ntopng.vs_scan_queue"
|
|
|
|
|
|
local json = require("dkjson")
|
|
local format_utils = require("format_utils")
|
|
|
|
local vs_utils = {}
|
|
|
|
-- **********************************************************
|
|
|
|
local function get_report_path(scan_type, ip)
|
|
local base_dir = dirs.workingdir .. "/-1/vulnerability_scan"
|
|
ntop.mkdir(base_dir)
|
|
local ret = base_dir .. "/"..ip.."_"..scan_type..".txt"
|
|
|
|
return(ret)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function lines(str)
|
|
local result = {}
|
|
|
|
for line in str:gmatch '[^\n]+' do
|
|
table.insert(result, line)
|
|
end
|
|
return result
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- remove the first/last few lines that contain nmap information that change at each scan
|
|
function vs_utils.cleanup_nmap_result(scan_result)
|
|
scan_result = scan_result:gsub("|", "")
|
|
|
|
scan_result = lines(scan_result)
|
|
|
|
for i=1,4 do
|
|
table.remove(scan_result, 1)
|
|
end
|
|
|
|
for i=1,3 do
|
|
table.remove(scan_result, #scan_result)
|
|
end
|
|
|
|
scan_result = table.concat(scan_result, "\n")
|
|
|
|
return(scan_result)
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Function to save host configuration
|
|
function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time, last_duration, is_ok_last_scan, ports)
|
|
local saved_hosts_string = ntop.getCache(host_to_scan_key)
|
|
local saved_hosts = {}
|
|
|
|
if not isEmptyString(saved_hosts_string) then
|
|
saved_hosts = json.decode(saved_hosts_string)
|
|
local index_to_remove = 0
|
|
|
|
for index,value in ipairs(saved_hosts) do
|
|
if value.host == host and value.scan_type == scan_type then
|
|
index_to_remove = index
|
|
end
|
|
end
|
|
|
|
if index_to_remove ~= 0 then
|
|
table.remove(saved_hosts, index_to_remove)
|
|
end
|
|
end
|
|
|
|
local new_item = {
|
|
host=host,
|
|
scan_type=scan_type,
|
|
ports=ports
|
|
}
|
|
|
|
if last_scan_time or last_duration then
|
|
local time_formatted = format_utils.formatPastEpochShort(last_scan_time)
|
|
if last_duration <= 0 then
|
|
last_duration = 1
|
|
end
|
|
last_duration = secondsToTime(last_duration)
|
|
new_item.last_scan = {
|
|
epoch = last_scan_time,
|
|
time = time_formatted,
|
|
duration = last_duration
|
|
}
|
|
|
|
if is_ok_last_scan then
|
|
new_item.is_ok_last_scan = is_ok_last_scan
|
|
end
|
|
end
|
|
|
|
if(scan_result ~= nil) then
|
|
local handle = io.open(get_report_path(scan_type, host), "w")
|
|
local result = handle:write(scan_result)
|
|
handle:close()
|
|
end
|
|
|
|
saved_hosts[#saved_hosts+1] = new_item
|
|
|
|
ntop.setCache(host_to_scan_key, json.encode(saved_hosts))
|
|
return 1
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Function to retrieve hosts list to scan
|
|
function vs_utils.retrieve_hosts_to_scan()
|
|
local res_string = ntop.getCache(host_to_scan_key)
|
|
|
|
if not isEmptyString(res_string) and res_string ~= "[[]]" and res_string ~= "[]" then
|
|
return json.decode(res_string)
|
|
else
|
|
return {}
|
|
end
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Function to retrieve last host scan result
|
|
function vs_utils.retrieve_hosts_scan_result(scan_type, host)
|
|
local path = get_report_path(scan_type, host)
|
|
|
|
if(ntop.exists(path)) then
|
|
local handle = io.open(path, "r")
|
|
local result = handle:read("*a")
|
|
handle:close()
|
|
|
|
return result
|
|
else
|
|
return ""
|
|
end
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Function to delete host to scan
|
|
function vs_utils.delete_host_to_scan(host, scan_type, all)
|
|
local saved_hosts_string = ntop.getCache(host_to_scan_key)
|
|
local saved_hosts = {}
|
|
|
|
if all then
|
|
|
|
ntop.delCache(host_to_scan_key)
|
|
else
|
|
if not isEmptyString(saved_hosts_string) then
|
|
saved_hosts = json.decode(saved_hosts_string)
|
|
local index_to_remove = 0
|
|
for index,value in ipairs(saved_hosts) do
|
|
if value.host == host and value.scan_type == scan_type then
|
|
index_to_remove = index
|
|
end
|
|
end
|
|
|
|
if index_to_remove ~= 0 then
|
|
table.remove(saved_hosts, index_to_remove)
|
|
end
|
|
|
|
end
|
|
|
|
ntop.setCache(host_to_scan_key, json.encode(saved_hosts))
|
|
end
|
|
|
|
return 1
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Function to retrieve scan types list
|
|
function vs_utils.retrieve_scan_types()
|
|
local scan_types = vs_utils.list_scan_modules()
|
|
local ret = {}
|
|
|
|
for _,scan_type in ipairs(scan_types) do
|
|
table.insert(ret, { id = scan_type, label = i18n("hosts_stats.page_scan_hosts.scan_type_list."..scan_type) })
|
|
end
|
|
|
|
return ret
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
function vs_utils.list_scan_modules()
|
|
local dirs = ntop.getDirs()
|
|
local basedir = dirs.scriptdir .. "/lua/modules/vulnerability_scan/modules"
|
|
local modules = {}
|
|
|
|
for name in pairs(ntop.readdir(basedir)) do
|
|
if(ends(name, ".lua")) then
|
|
name = string.sub(name, 1, string.len(name)-4) -- remove .lua trailer
|
|
local m = vs_utils.load_module(name)
|
|
|
|
if(m:is_enabled()) then
|
|
table.insert(modules, name)
|
|
end
|
|
end
|
|
end
|
|
|
|
return(modules)
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
function vs_utils.load_module(name)
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/vulnerability_scan/modules/?.lua;".. package.path
|
|
return(require(name):new())
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Function to exec single host scan
|
|
function vs_utils.scan_host(scan_type, host, ports)
|
|
local scan_module = vs_utils.load_module(scan_type)
|
|
local result,duration,scan_result = scan_module:scan_host(host, ports)
|
|
|
|
vs_utils.save_host_to_scan(scan_type, host, result, now, duration, scan_result, ports)
|
|
|
|
return true
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Function to update single host status
|
|
function vs_utils.set_status_scan(scan_type, host, ports)
|
|
|
|
local saved_hosts_string = ntop.getCache(host_to_scan_key)
|
|
local saved_hosts = {}
|
|
|
|
if not isEmptyString(saved_hosts_string) then
|
|
saved_hosts = json.decode(saved_hosts_string)
|
|
local index_to_update = 0
|
|
local value_to_update = {}
|
|
|
|
for index,value in ipairs(saved_hosts) do
|
|
if value.host == host and value.scan_type == scan_type then
|
|
index_to_update = index
|
|
value.is_ok_last_scan = 4
|
|
value_to_update = value
|
|
|
|
end
|
|
end
|
|
|
|
if index_to_update ~= 0 then
|
|
table.remove(saved_hosts, index_to_update)
|
|
table.insert(saved_hosts, index_to_update, value_to_update)
|
|
end
|
|
end
|
|
|
|
ntop.setCache(host_to_scan_key, json.encode(saved_hosts))
|
|
|
|
return true
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
function vs_utils.schedule_host_scan(scan_type, host, ports)
|
|
local scan = { scan_type = scan_type, host = host, ports = ports }
|
|
vs_utils.set_status_scan(scan_type, host, ports)
|
|
|
|
ntop.rpushCache(host_scan_queue_key, json.encode(scan))
|
|
|
|
return true
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
function vs_utils.schedule_all_hosts_scan(scan_type, host, ports)
|
|
local host_to_scan_list = vs_utils.retrieve_hosts_to_scan()
|
|
|
|
if #host_to_scan_list > 0 then
|
|
for _,scan_info in ipairs(host_to_scan_list) do
|
|
local scan_type = scan_info.scan_type
|
|
local host = scan_info.host
|
|
local scan = { scan_type = scan_type, host = host, ports = ports }
|
|
|
|
ntop.rpushCache(host_scan_queue_key, json.encode(scan))
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Process a single host scan request that has been queued
|
|
function vs_utils.process_oldest_scheduled_scan()
|
|
local elem = ntop.lpopCache(host_scan_queue_key)
|
|
|
|
if((elem ~= nil) and (elem ~= "")) then
|
|
local elem = json.decode(elem)
|
|
|
|
vs_utils.scan_host(elem.scan_type, elem.host, elem.ports)
|
|
|
|
return true
|
|
else
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Process a single host scan request that has been queued
|
|
function vs_utils.process_all_scheduled_scans(max_num_scans)
|
|
local num = 0
|
|
|
|
if(max_num_scans == nil) then max_num_scans = 9999 end
|
|
|
|
while(max_num_scans > 0) do
|
|
local res = vs_utils.process_oldest_scheduled_scan()
|
|
|
|
if(res == false) then
|
|
break
|
|
else
|
|
max_num_scans = max_num_scans - 1
|
|
num = num + 1
|
|
end
|
|
end
|
|
|
|
return num
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
-- Process to retrieve list of ports using nmap
|
|
function vs_utils.get_ports(host)
|
|
-- FIXME
|
|
-- must returns array of object {key: port_id}
|
|
local result = {}
|
|
|
|
result[#result+1] = {
|
|
key = 22
|
|
}
|
|
|
|
return result
|
|
end
|
|
|
|
-- **********************************************************
|
|
|
|
return vs_utils
|