[VS] Add UDP port handler and implement numerous fixes.

This commit is contained in:
Nicolo Maio 2023-10-12 15:17:05 +02:00
parent bbf9b71add
commit 3d44707cc8
13 changed files with 670 additions and 332 deletions

View file

@ -50,7 +50,7 @@ local format_utils = require("format_utils")
local recipients = require("recipients")
local cve_utils = require("cve_utils")
local debug_print = false
local debug_print = true
local vs_utils = {}
-- **********************************************************
@ -69,7 +69,7 @@ vs_utils.scan_status = {
scanning = 4
}
vs_utils.tcp_ports_diff_case = {
vs_utils.ports_diff_case = {
no_diff = 2, -- case 1 or 2 (combined)
ntopng_more_t_vs = 3,
vs_more_t_ntopng = 4
@ -217,12 +217,65 @@ local function check_ports_diffences(num_old_ports, old_ports, num_new_ports, ne
else
rsp.trigger = false
end
return rsp
end
-- ##############################################
local function split_port_list(data, is_tcp)
if (is_tcp) then
if (data.tcp_ports and data.tcp_ports.num_ports ~= 0) then
return split(data.tcp_ports.ports,",")
end
else
if(data.udp_ports and data.udp_ports.num_ports ~= 0) then
return split(data.udp_ports.ports, ",")
end
end
return {}
end
-- ##############################################
local function analyze_ports_diff(ports_difference)
local rsp = {}
if (ports_difference.trigger) then
if (debug_print) then
tprint("found ports differences")
tprint(ports_difference)
end
rsp["open_ports"] = {
num = ports_difference.open_ports_num,
ports = format_port_list_to_string(ports_difference.open_ports)
}
rsp["closed_ports"] = {
num = ports_difference.closed_ports_num,
ports = format_port_list_to_string(ports_difference.closed_ports)
}
rsp["ports_case"] = ports_difference.case
if (debug_print) then
tprint(ports_difference.case)
end
elseif (debug_print) then
tprint("IS IT TRIGGERED: ")
tprint(ports_difference.trigger)
end
rsp["triggered"] = ports_difference.trigger
return rsp
end
-- ##############################################
-- This function checks the differences between an old and a new host scan
-- and return a table containing those differences
local function check_differences(host, host_name, scan_type, old_data, new_data)
@ -243,8 +296,12 @@ local function check_differences(host, host_name, scan_type, old_data, new_data)
local num_new_cve_issues = 0
local cve_solved = {}
local new_cve = {}
-- Checking the solved vulnerabilities
for _, cve in ipairs(old_data.cve or {}) do
-- the old cves have the score
cve = split(cve,"|")[1]
-- If the new table does not contains the cve it means that it is solved
if not (table.contains(new_data.cve or {}, cve)) then
num_cve_solved = num_cve_solved + 1
@ -269,68 +326,67 @@ local function check_differences(host, host_name, scan_type, old_data, new_data)
-- Checking old_open_tcp_ports and new_open_tcp_ports
local tcp_old_ports = {}
local udp_old_ports = {}
local tcp_new_ports = {}
local udp_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 (scan_type == "tcp_portscan" or scan_type == "tcp_openports") then
tcp_old_ports = split_port_list(old_data, true)
tcp_new_ports = split_port_list(new_data, true)
if (debug_print) then
tprint("TCP OLD PORTS: ")
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: ")
tprint(tcp_new_ports)
end
local tcp_ports_differences = check_ports_diffences( #tcp_old_ports, tcp_old_ports,
#tcp_new_ports, tcp_new_ports)
local rsp_tcp_diff = analyze_ports_diff(tcp_ports_differences)
if (rsp_tcp_diff.triggered) then
rsp["tcp_open_ports"] = rsp_tcp_diff.open_ports
rsp["tcp_closed_ports"] = rsp_tcp_diff.closed_ports
rsp["tcp_ports_case"] = rsp_tcp_diff.ports_case
end
rsp["measurement"] = "ports_changes_detected"
elseif (scan_type == "udp_portscan") then
udp_old_ports = split_port_list(old_data, false)
udp_new_ports = split_port_list(new_data, false)
if (debug_print) then
tprint("UDP OLD PORTS: ")
tprint(udp_old_ports)
tprint("UDP NEW PORTS")
tprint(udp_new_ports)
end
local udp_ports_differences = check_ports_diffences( #udp_old_ports, udp_old_ports,
#udp_new_ports, udp_new_ports)
local rsp_udp_diff = analyze_ports_diff(udp_ports_differences)
if (rsp_udp_diff.triggered) then
rsp["udp_open_ports"] = rsp_udp_diff.open_ports
rsp["udp_closed_ports"] = rsp_udp_diff.closed_ports
rsp["udp_ports_case"] = rsp_udp_diff.ports_case
end
rsp["measurement"] = "ports_changes_detected"
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
rsp["measurement"] = "cve_changes_detected"
end
if num_new_cve_issues > 0 then
rsp["num_new_cve_issues"] = num_new_cve_issues
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)
rsp["measurement"] = "cve_changes_detected"
end
@ -560,19 +616,26 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
tprint("ALREADY PRESENT-> CHECKING DIFF")
end
local old_cve_no_score = {}
for _,cve in ipairs(old_data.cve) do
old_cve_no_score[#old_cve_no_score+1] = split(cve,"|")[1]
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,
cve = old_cve_no_score,
tcp_ports = {num_ports = old_data.tcp_ports, ports = old_data.tcp_ports_list },
udp_ports = {num_ports = old_data.udp_ports, ports = old_data.udp_ports_list}
},
{
vulnerabilities = num_vulnerabilities_found,
ports = num_open_ports,
cve = cve,
tcp_ports = tcp_ports
tcp_ports = tcp_ports,
udp_ports = udp_ports
})
if host_info_to_cache then
ntop.rpushCache(scanned_hosts_changes_key, json.encode(host_info_to_cache))
@ -593,8 +656,8 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
is_ok_last_scan = vs_utils.scan_status.not_scanned
end
local cve_formatted, max_score_cve = get_cve_with_score(cve)
local new_item = {
host = host,
host_name = host_name,
@ -615,7 +678,9 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
end
if udp_ports ~= nil then
new_item.udp_ports = #udp_ports
new_item.udp_ports = udp_ports.num_ports
new_item.udp_ports_list = udp_ports.ports
end
if (udp_ports == nil and tcp_ports == nil) then
@ -660,10 +725,15 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
local result = 1 -- success
if(not isAlreadyPresent(new_item)) then
if (debug_print) then
tprint("SAVING HOST: "..new_item.host)
end
--saved_hosts[#saved_hosts+1] = new_item
ntop.setHashCache(host_to_scan_key, host_hash_key, json.encode(new_item))
elseif not isEmptyString(id) then
if (debug_print) then
tprint("UPDATING HOST: "..new_item.host)
end
-- edit case
ntop.setHashCache(host_to_scan_key, host_hash_key, json.encode(new_item))
else
@ -717,6 +787,9 @@ function vs_utils.update_ts_counters()
end
-- **********************************************************
-- Function to send notification after periodicity scan
function vs_utils.notify_end_periodicity()
local periodicity_scan_in_progress = ntop.getCache(host_to_scan_periodicity_key) == "1"
@ -987,11 +1060,12 @@ function vs_utils.scan_host(scan_type, host, ports, scan_id)
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
if (udp_ports ~= nil) then
udp_ports = {ports = format_port_list_to_string(udp_ports), num_ports = #udp_ports}
end
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
@ -1215,6 +1289,7 @@ function vs_utils.retrieve_detected_ports(host)
local host_info = interface.getHostInfo(host)
local tcp_ports_detected = {}
local udp_ports_detected = {}
local host_in_mem = false
if (host_info and host_info.used_ports and host_info.used_ports.local_server_ports) then
for port, l7_proto in pairs(host_info.used_ports.local_server_ports) do
@ -1225,11 +1300,15 @@ function vs_utils.retrieve_detected_ports(host)
if (l4_proto == 'tcp') then
tcp_ports_detected[#tcp_ports_detected+1] = id_port
end
if (l4_proto == 'udp') then
udp_ports_detected[#udp_ports_detected+1] = id_port
end
end
host_in_mem = true
end
return tcp_ports_detected, host_in_mem
return tcp_ports_detected, host_in_mem, udp_ports_detected
end
-- Search port in ports list
@ -1264,11 +1343,11 @@ function vs_utils.compare_ports(vs_scan_port_string_list, ntopng_ports)
local diff_case
if (not_found_a_port) then
diff_case = vs_utils.tcp_ports_diff_case.vs_more_t_ntopng
diff_case = vs_utils.ports_diff_case.vs_more_t_ntopng
end
if (#vs_scan_ports == #ntopng_ports) then
diff_case = vs_utils.tcp_ports_diff_case.no_diff
diff_case = vs_utils.ports_diff_case.no_diff
else
local filtered = false
@ -1280,7 +1359,7 @@ function vs_utils.compare_ports(vs_scan_port_string_list, ntopng_ports)
end
if (filtered) then
diff_case = vs_utils.tcp_ports_diff_case.ntopng_more_t_vs
diff_case = vs_utils.ports_diff_case.ntopng_more_t_vs
end
end