Add port service name and fix alerts (#7859)

This commit is contained in:
Nicolo Maio 2023-10-02 18:40:48 +02:00
parent 254ed7fac9
commit 225cd81bcb
8 changed files with 250 additions and 40 deletions

View file

@ -123,6 +123,97 @@ local function lines(str)
return result
end
-- ##############################################
local function format_port_list_to_string(ports)
local scan_ports = ""
if (#ports > 0) then
for index,port in ipairs(ports) do
if (index == 1) then
scan_ports = ""..port
else
scan_ports = scan_ports .. ","..port
end
end
end
return scan_ports
end
-- ##############################################
local function find_port(port, port_list)
local found = false
for _,item in ipairs(port_list) do
if (item == port) then
found = true
break
end
end
return found
end
local function check_ports_diffences(num_old_ports, old_ports, num_new_ports, new_ports)
local rsp = {
trigger = true
}
if (num_old_ports == 0 and num_new_ports ~= 0) then
rsp.open_ports = new_ports
rsp.open_ports_num = num_new_ports
rsp.closed_ports_num = 0
rsp.case = 'new_ports'
elseif(num_old_ports ~= 0 and num_new_ports == 0) then
rsp.open_ports_num = 0
rsp.closed_ports_num = num_old_ports
rsp.closed_ports = old_ports
rsp.case = 'ports_closed'
elseif(num_old_ports ~= 0 and num_new_ports ~= 0) then
local closed_ports = {}
local open_ports = {}
local diff = false
for _, item in ipairs(old_ports) do
local is_open = find_port(item, new_ports)
if (not is_open) then
closed_ports[#closed_ports+1] = item
diff = true
end
end
for _, item in ipairs(new_ports) do
local is_open = find_port(item, old_ports)
if (not is_open) then
open_ports[#open_ports+1] = item
diff = true
end
end
if((not diff) and (num_old_ports == num_new_ports)) then
rsp.trigger = false
else
rsp.open_ports = open_ports
rsp.open_ports_num = #open_ports
rsp.closed_ports = closed_ports
rsp.closed_ports_num = #closed_ports
if (#open_ports ~= 0 and #closed_ports == 0) then
rsp.case = 'new_ports'
elseif (#open_ports == 0 and #closed_ports ~= 0) then
rsp.case = 'ports_closed'
else
rsp.case = 'ports_open_and_closed'
end
end
else
rsp.trigger = false
end
return rsp
end
-- ##############################################
-- This function checks the differences between an old and a new host scan
@ -169,6 +260,38 @@ local function check_differences(host, host_name, scan_type, old_data, new_data)
end
end
-- Checking old_open_tcp_ports and new_open_tcp_ports
local tcp_old_ports = {}
local tcp_new_ports = {}
if (debug_print) then
tprint("OLD_DATA_TCP_PORTS")
tprint(old_data.tcp_ports)
tprint("NEW_DATA_TCP_PORTS")
tprint(new_data.tcp_ports)
end
if (old_data.tcp_ports and old_data.tcp_ports.num_ports ~= 0) then
tcp_old_ports = split(old_data.tcp_ports.ports,",")
if (debug_print) then
tprint(tcp_old_ports)
end
end
if (new_data.tcp_ports.num_ports ~= 0) then
tcp_new_ports = split(new_data.tcp_ports.ports, ",")
if (debug_print) then
tprint(tcp_new_ports)
end
end
local ports_differences = check_ports_diffences(#tcp_old_ports, tcp_old_ports,
#tcp_new_ports, tcp_new_ports)
if num_cve_solved > 0 then
rsp["num_cve_solved"] = num_cve_solved
rsp["cve_solved"] = cve_solved
@ -179,6 +302,31 @@ local function check_differences(host, host_name, scan_type, old_data, new_data)
rsp["new_cve"] = new_cve
end
if (ports_differences.trigger) then
if (debug_print) then
tprint("found ports differences")
tprint(ports_differences)
end
rsp["open_ports"] = {
num = ports_differences.open_ports_num,
ports = format_port_list_to_string(ports_differences.open_ports)
}
rsp["closed_ports"] = {
num = ports_differences.closed_ports_num,
ports = format_port_list_to_string(ports_differences.closed_ports)
}
rsp["tcp_ports_case"] = ports_differences.case
if (debug_print) then
tprint(ports_differences.case)
end
elseif (debug_print) then
tprint("IS IT TRIGGERED: ")
tprint(ports_differences.trigger)
end
if table.empty(rsp) then
rsp = nil
else
@ -342,23 +490,30 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
end
-- In case the alert needs to be triggered, save the differences in order to lessen
-- the info dropped on redis
if trigger_alert and old_data then
-- If this host was already scanned in the past, then it needs to have some of these data
local already_scanned = (old_data.ports) or (old_data.num_open_ports)
or (old_data.num_vulnerabilities_found)
-- if is_ok_last_scan is nil then no prior scan was done, so do not trigger the alert
if trigger_alert and old_data and (not is_edit) then
local already_scanned = (old_data.last_scan and old_data.last_scan.epoch)
if already_scanned then
local host_info_to_cache = check_differences(host, host_name,
scan_type,
{
vulnerabilities = old_data.num_vulnerabilities_found,
ports = old_data.num_open_ports,
cve = old_data.cve,
},
{
vulnerabilities = num_vulnerabilities_found,
ports = num_open_ports,
cve = cve,
})
if(debug_print) then
tprint("ALREADY PRESENT-> CHECKING DIFF")
end
local host_info_to_cache = check_differences(host, host_name,
scan_type,
{
vulnerabilities = old_data.num_vulnerabilities_found,
ports = old_data.num_open_ports,
cve = old_data.cve,
tcp_ports = {num_ports = old_data.tcp_ports, ports = old_data.tcp_ports_list },
},
{
vulnerabilities = num_vulnerabilities_found,
ports = num_open_ports,
cve = cve,
tcp_ports = tcp_ports
})
if host_info_to_cache then
ntop.rpushCache(scanned_hosts_changes_key, json.encode(host_info_to_cache))
end
@ -723,26 +878,14 @@ function vs_utils.load_module(name)
return(require(name):new())
end
local function format_port_list_to_string(ports)
local scan_ports
for index,port in ipairs(ports) do
if (index == 1) then
scan_ports = ""..port
else
scan_ports = scan_ports .. ","..port
end
end
return scan_ports
end
function vs_utils.discover_open_ports(host)
local result,duration,scan_result,num_open_ports,num_vulnerabilities_found, cve, udp_ports, tcp_ports, scan_ports
local result,duration,scan_result,num_open_ports,num_vulnerabilities_found, cve, udp_ports, tcp_ports, scan_ports, network_alert_store,now
local scan_module = vs_utils.load_module("tcp_openports")
result,duration,scan_result,num_open_ports,num_vulnerabilities_found, cve, udp_ports, tcp_ports = scan_module:scan_host(host, ports)
now,result,duration,scan_result,num_open_ports,num_vulnerabilities_found, cve, udp_ports, tcp_ports = scan_module:scan_host(host, ports)
-- FIX ME -> only tcp for now
@ -754,7 +897,11 @@ end
-- Function to exec single host scan
function vs_utils.scan_host(scan_type, host, ports, scan_id)
if debug_print then
traceError(TRACE_NORMAL,TRACE_CONSOLE,"Scanning Host ".. host .. " on Ports: " .. ports .. "\n")
if (ports ~= nil) then
traceError(TRACE_NORMAL,TRACE_CONSOLE,"Scanning Host ".. host .. " on Ports: " .. ports .. "\n")
else
traceError(TRACE_NORMAL,TRACE_CONSOLE,"Scanning Host ".. host.."\n")
end
end
local ports_scan_param = ports
@ -762,14 +909,18 @@ function vs_utils.scan_host(scan_type, host, ports, scan_id)
ports = vs_utils.discover_open_ports(host)
end
vs_utils.set_status_scan(scan_type, host, ports, id, nil, vs_utils.scan_status.scanning)
vs_utils.set_status_scan(scan_type, host, ports_scan_param, id, nil, vs_utils.scan_status.scanning)
local scan_module = vs_utils.load_module(scan_type)
local now,result,duration,scan_result,num_open_ports,num_vulnerabilities_found, cve, udp_ports, tcp_ports = scan_module:scan_host(host, ports)
-- FIX HERE UDP ports
tcp_ports = {ports = format_port_list_to_string(tcp_ports), num_ports = #tcp_ports}
if(tcp_ports ~= nil) then
tcp_ports = {ports = format_port_list_to_string(tcp_ports), num_ports = #tcp_ports}
else
tcp_ports = {ports = ports, num_ports = num_open_ports}
end
if scan_result then
scan_result = vs_utils.scan_status.ok