mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-29 07:29:32 +00:00
This commit is contained in:
parent
9668851b9c
commit
2519a8acb2
6 changed files with 211 additions and 109 deletions
|
|
@ -74,6 +74,7 @@ local vs_rest_utils = require("vs_rest_utils")
|
|||
-- redis-cli set "ntopng.prefs.vs.debug_enabled" "1"
|
||||
-- systemctl restart ntopng
|
||||
local debug_me = ntop.getCache("ntopng.prefs.vs.debug_enabled") == "1"
|
||||
local test_me = false
|
||||
local verbose = false
|
||||
|
||||
local vs_utils = {}
|
||||
|
|
@ -282,23 +283,91 @@ end
|
|||
|
||||
-- ##############################################
|
||||
|
||||
local function analyze_ports_diff(ports_difference)
|
||||
local function save_last_result(scan_result, scan_type,host,epoch)
|
||||
if(scan_result ~= nil and not ntop.isClickHouseEnabled()) then
|
||||
local handle = io.open(get_report_path(scan_type, host), "a")
|
||||
local result = handle:write("\n"..i18n("hosts_stats.page_scan_hosts.inconsistency_state").."\n"..scan_result)
|
||||
handle:close()
|
||||
end
|
||||
|
||||
if (scan_result ~= nil and ntop.isClickHouseEnabled()) then
|
||||
vs_db_utils.update_last_result(scan_result, scan_type, host, epoch)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function verify_status_ports(possible_changed_ports, host, scan_type, open_ports_case, epoch)
|
||||
local real_ports = {}
|
||||
local scan_module = vs_utils.load_module(scan_type)
|
||||
if (test_me) then
|
||||
tprint("TROVATA inconsistent")
|
||||
ntop.msleep(10000)
|
||||
tprint("RESCANNING")
|
||||
end
|
||||
for _,possible_changed_port in ipairs(possible_changed_ports) do
|
||||
local now,result,duration,scan_result,num_open_ports,num_vulnerabilities_found, cve, udp_ports, tcp_ports = scan_module:scan_host(host, possible_changed_port)
|
||||
save_last_result(result, scan_type, host, epoch)
|
||||
if debug_me then
|
||||
tprint("SCANNED AGAIN HOST: "..host.." ON PORT: "..possible_changed_port)
|
||||
end
|
||||
if (open_ports_case and num_open_ports > 0) then
|
||||
-- case open port and num_open_ports is > 0 so is a real open port
|
||||
real_ports[#real_ports+1] = possible_changed_port
|
||||
if debug_me then
|
||||
tprint("IS A REAL OPEN")
|
||||
end
|
||||
elseif (open_ports_case == false and num_open_ports == 0) then
|
||||
-- case closed port and num_open_ports is 0 so is a real closed port
|
||||
real_ports[#real_ports+1] = possible_changed_port
|
||||
if debug_me then
|
||||
tprint("IS A REAL CLOSED")
|
||||
end
|
||||
end
|
||||
end
|
||||
return real_ports
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function analyze_ports_diff(ports_difference, host, scan_type, epoch)
|
||||
local rsp = {}
|
||||
local need_to_trigger_alert_after_changes_verification = ports_difference.trigger
|
||||
if (ports_difference.trigger) then
|
||||
if (debug_me) then
|
||||
tprint("found ports differences")
|
||||
tprint(ports_difference)
|
||||
end
|
||||
local open_ports_case = true
|
||||
|
||||
local real_open_ports = verify_status_ports(ports_difference.open_ports or {}, host, scan_type, open_ports_case, epoch )
|
||||
local real_open_port_num = ternary(real_open_ports ~= nil and next(real_open_ports), #real_open_ports, 0)
|
||||
rsp["open_ports"] = {
|
||||
num = ports_difference.open_ports_num,
|
||||
ports = format_port_list_to_string(ports_difference.open_ports)
|
||||
num = real_open_port_num,
|
||||
ports = format_port_list_to_string(real_open_ports)
|
||||
}
|
||||
open_ports_case = false
|
||||
local real_closed_ports = verify_status_ports(ports_difference.closed_ports or {}, host, scan_type, open_ports_case, epoch)
|
||||
local real_closed_ports_num = ternary(real_closed_ports ~= nil and next(real_closed_ports), #real_closed_ports, 0)
|
||||
|
||||
rsp["closed_ports"] = {
|
||||
num = ports_difference.closed_ports_num,
|
||||
ports = format_port_list_to_string(ports_difference.closed_ports)
|
||||
num = real_closed_ports_num,
|
||||
ports = format_port_list_to_string(real_closed_ports)
|
||||
}
|
||||
rsp["ports_case"] = ports_difference.case
|
||||
|
||||
if ((real_closed_ports_num == ports_difference.closed_ports_num) and (real_open_port_num == ports_difference.open_ports_num)) then
|
||||
|
||||
-- case ok we can trigger alert
|
||||
else
|
||||
-- false positive detected
|
||||
if (debug_me) then
|
||||
tprint("IT'S A FALSE POSITIVE!!!")
|
||||
end
|
||||
|
||||
need_to_trigger_alert_after_changes_verification = false
|
||||
end
|
||||
if (debug_me) then
|
||||
tprint(ports_difference.case)
|
||||
end
|
||||
|
|
@ -307,7 +376,45 @@ local function analyze_ports_diff(ports_difference)
|
|||
tprint(ports_difference.trigger)
|
||||
end
|
||||
|
||||
rsp["triggered"] = ports_difference.trigger
|
||||
rsp["triggered"] = need_to_trigger_alert_after_changes_verification
|
||||
|
||||
return rsp
|
||||
end
|
||||
|
||||
local function get_ports_changes(host, scan_type, old_data, new_data)
|
||||
|
||||
local is_tcp = false
|
||||
local scan_type_log_label = "UDP"
|
||||
|
||||
local rsp = {}
|
||||
|
||||
if(scan_type == 'tcp_portscan' or scan_type == 'tcp_openports') then
|
||||
is_tcp = true
|
||||
scan_type_log_label = "TCP"
|
||||
end
|
||||
|
||||
local old_ports = split_port_list(old_data, is_tcp)
|
||||
local new_ports = split_port_list(new_data, is_tcp)
|
||||
|
||||
if (debug_me) then
|
||||
tprint(scan_type_log_label.." OLD PORTS: ")
|
||||
tprint(old_ports)
|
||||
tprint(scan_type_log_label.." NEW PORTS: ")
|
||||
tprint(new_ports)
|
||||
end
|
||||
|
||||
local ports_differences = check_ports_diffences(#old_ports, old_ports,
|
||||
#new_ports, new_ports)
|
||||
local rsp_diff = analyze_ports_diff(ports_differences, host, scan_type, new_data.last_scan_time)
|
||||
if (rsp_diff.triggered) then
|
||||
rsp["open_ports"] = rsp_diff.open_ports
|
||||
rsp["closed_ports"] = rsp_diff.closed_ports
|
||||
rsp["ports_case"] = rsp_diff.ports_case
|
||||
|
||||
end
|
||||
rsp["triggered"] = rsp_diff.triggered
|
||||
|
||||
rsp["measurement"] = "ports_changes_detected"
|
||||
|
||||
return rsp
|
||||
end
|
||||
|
|
@ -324,6 +431,11 @@ local function check_differences(host, host_name, scan_type, old_data, new_data)
|
|||
return nil
|
||||
end
|
||||
|
||||
-- retrocompatibility check
|
||||
if (scan_type == 'tcp_openports') then
|
||||
scan_type = 'tcp_portscan'
|
||||
end
|
||||
|
||||
--[[
|
||||
if tonumber(old_data.ports or 0) ~= tonumber(new_data.ports or 0) then
|
||||
rsp["num_ports"] = {
|
||||
|
|
@ -363,59 +475,23 @@ 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 udp_old_ports = {}
|
||||
|
||||
local tcp_new_ports = {}
|
||||
local udp_new_ports = {}
|
||||
-- ***************************************************************
|
||||
|
||||
-- Checking differences beetwen old and new open ports and old and new closed ports
|
||||
local differences = get_ports_changes(host, scan_type, old_data, new_data)
|
||||
rsp["triggered"] = differences.triggered
|
||||
rsp["measurement"] = "ports_changes_detected"
|
||||
local prefix_key = "udp_"
|
||||
if (scan_type == "tcp_portscan") then
|
||||
tcp_old_ports = split_port_list(old_data, true)
|
||||
tcp_new_ports = split_port_list(new_data, true)
|
||||
if (debug_me) then
|
||||
tprint("TCP OLD PORTS: ")
|
||||
tprint(tcp_old_ports)
|
||||
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["triggered"] = rsp_tcp_diff.triggered
|
||||
|
||||
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_me) 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["triggered"] = rsp_udp_diff.triggered
|
||||
|
||||
rsp["measurement"] = "ports_changes_detected"
|
||||
|
||||
prefix_key = "tcp_"
|
||||
end
|
||||
if (differences.triggered) then
|
||||
rsp[prefix_key.."open_ports"] = differences.open_ports
|
||||
rsp[prefix_key.."closed_ports"] = differences.closed_ports
|
||||
rsp[prefix_key.."ports_case"] = differences.ports_case
|
||||
end
|
||||
|
||||
-- ***************************************************************
|
||||
|
||||
if num_cve_solved > 0 then
|
||||
rsp["num_cve_solved"] = num_cve_solved
|
||||
|
|
@ -859,48 +935,7 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
|
|||
-- In case the alert needs to be triggered, save the differences in order to lessen
|
||||
-- the info dropped on redis
|
||||
-- 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
|
||||
|
||||
if debug_me then
|
||||
-- traceError(TRACE_NORMAL,TRACE_CONSOLE, "Vulnerability Scan: checking for changes in host")
|
||||
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_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,
|
||||
udp_ports = udp_ports,
|
||||
last_scan_time = last_scan_time
|
||||
|
||||
})
|
||||
if host_info_to_cache then
|
||||
|
||||
if debug_me then
|
||||
traceError(TRACE_NORMAL,TRACE_CONSOLE, "Vulnerability Scan detected change: enqueueing event to vulnerability_scan check\n")
|
||||
end
|
||||
|
||||
ntop.rpushCache(scanned_hosts_changes_queue_key, json.encode(host_info_to_cache))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local epoch_id = 0
|
||||
if isEmptyString(id) then
|
||||
|
|
@ -950,7 +985,8 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
|
|||
new_item.last_scan = {
|
||||
epoch = last_scan_time,
|
||||
--time = time_formatted,
|
||||
duration = last_duration
|
||||
duration = last_duration,
|
||||
duration_epoch = last_duration
|
||||
}
|
||||
|
||||
if is_ok_last_scan == vs_utils.scan_status.ok then
|
||||
|
|
@ -994,16 +1030,16 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
|
|||
local compare_info = vs_rest_utils.compare_scan_info_ntopng_info(host, scan_type, new_item.tcp_ports_list, new_item.udp_ports_list)
|
||||
|
||||
new_item.host_in_mem = compare_info.host_in_mem
|
||||
local prefix_key = "udp_"
|
||||
if (scan_type == "tcp_portscan" or scan_type == "tcp_openports") then
|
||||
new_item.tcp_ports_unused = compare_info.tcp_ports_unused
|
||||
new_item.tcp_ports_filtered = compare_info.tcp_ports_filtered
|
||||
new_item.tcp_ports_case = compare_info.tcp_ports_case
|
||||
elseif (scan_type == "udp_portscan") then
|
||||
new_item.udp_ports_unused = compare_info.udp_ports_unused
|
||||
new_item.udp_ports_filtered = compare_info.udp_ports_filtered
|
||||
new_item.udp_ports_case = compare_info.udp_ports_case
|
||||
prefix_key = "tcp_"
|
||||
end
|
||||
end
|
||||
|
||||
new_item[prefix_key.."ports_unused"] = compare_info[prefix_key.."ports_unused"]
|
||||
new_item[prefix_key.."ports_filtered"] = compare_info[prefix_key.."ports_filtered"]
|
||||
new_item[prefix_key.."ports_case"] = compare_info[prefix_key.."ports_case"]
|
||||
|
||||
end
|
||||
-- edit case
|
||||
ntop.setHashCache(host_to_scan_key, host_hash_key, json.encode(new_item))
|
||||
|
||||
|
|
@ -1035,6 +1071,50 @@ end
|
|||
|
||||
vs_db_utils.save_vs_result(scan_type, host, new_item.last_scan.epoch, json.encode(new_item), scan_result)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
if debug_me then
|
||||
-- traceError(TRACE_NORMAL,TRACE_CONSOLE, "Vulnerability Scan: checking for changes in host")
|
||||
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_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},
|
||||
old_epoch = old_data.last_scan.epoch
|
||||
},
|
||||
{
|
||||
vulnerabilities = num_vulnerabilities_found,
|
||||
ports = num_open_ports,
|
||||
cve = cve,
|
||||
tcp_ports = tcp_ports,
|
||||
udp_ports = udp_ports,
|
||||
last_scan_time = last_scan_time
|
||||
|
||||
})
|
||||
if host_info_to_cache then
|
||||
|
||||
if debug_me then
|
||||
traceError(TRACE_NORMAL,TRACE_CONSOLE, "Vulnerability Scan detected change: enqueueing event to vulnerability_scan check\n")
|
||||
end
|
||||
|
||||
ntop.rpushCache(scanned_hosts_changes_queue_key, json.encode(host_info_to_cache))
|
||||
end
|
||||
end
|
||||
end
|
||||
return result, new_item.id
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue