mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-29 07:29:32 +00:00
[VS] Add discrepancy info on email notification. (#8048)
This commit is contained in:
parent
fb0ff0850c
commit
5a3d1543b0
2 changed files with 173 additions and 55 deletions
|
|
@ -789,7 +789,7 @@ end
|
|||
|
||||
-- Function to update counters of periodically scan or scan all
|
||||
-- @param is_periodic (true -> is a periodic scan, false -> is a scan all)
|
||||
local function update_scan_info_for_report(type_of_scan_execution, new_item, host_hash_key)
|
||||
local function update_scan_info_for_report(type_of_scan_execution, new_item, host_hash_key, discrepancies)
|
||||
-- select correctly redis keys
|
||||
local redis_info_key = get_counter_periodic_all_scan_keys(type_of_scan_execution)
|
||||
|
||||
|
|
@ -831,19 +831,102 @@ local function update_scan_info_for_report(type_of_scan_execution, new_item, hos
|
|||
end
|
||||
end
|
||||
|
||||
if (info_json ~= {} and info_json.scanned_hosts ~= nil) then
|
||||
if (new_item.is_ok_last_scan == vs_utils.scan_status.ok) then
|
||||
if (new_item.is_ok_last_scan == vs_utils.scan_status.ok) then
|
||||
if (info_json ~= {} and info_json.scanned_hosts ~= nil) then
|
||||
-- count just in success case
|
||||
info_json.scanned_hosts = tonumber(info_json.scanned_hosts) + 1
|
||||
else
|
||||
info_json.scanned_hosts = 1
|
||||
end
|
||||
elseif (new_item.is_ok_last_scan == vs_utils.scan_status.failed) then
|
||||
|
||||
if (info_json ~= {} and info_json.not_scanned_hosts ~= nil) then
|
||||
-- count just in success case
|
||||
info_json.scanned_hosts = tonumber(info_json.scanned_hosts) + 1
|
||||
end
|
||||
else
|
||||
info_json.scanned_hosts = 1
|
||||
info_json.not_scanned_hosts = tonumber(info_json.not_scanned_hosts) + 1
|
||||
else
|
||||
info_json.not_scanned_hosts = 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if (info_json ~= {} and info_json.begin_epoch == nil) then
|
||||
info_json.begin_epoch = os.time()
|
||||
end
|
||||
|
||||
|
||||
if discrepancies then
|
||||
-- HAD DISCREPANCY INFO TO EMAIL REPORT
|
||||
local cve_case = false
|
||||
if (info_json ~= {} and info_json.num_cve_solved ~= nil and new_item.scan_type == 'cve') then
|
||||
info_json.num_cve_solved = tonumber(info_json.num_cve_solved or 0) + tonumber(discrepancies.num_cve_solved or 0)
|
||||
cve_case = true
|
||||
else
|
||||
info_json.num_cve_solved = 0
|
||||
end
|
||||
|
||||
if ((info_json ~= {} and info_json.new_open_ports ~= nil) and (new_item.scan_type == 'tcp_portscan' or new_item.scan_type == 'tcp_openports') and discrepancies.tcp_open_ports and discrepancies.tcp_open_ports.num and discrepancies.tcp_open_ports.num>0) then
|
||||
info_json.new_open_ports = tonumber(info_json.new_open_ports or 0) + tonumber(discrepancies.tcp_open_ports.num)
|
||||
else
|
||||
info_json.new_open_ports = 0
|
||||
end
|
||||
|
||||
if (info_json ~= {} and info_json.new_open_ports ~= nil and new_item.scan_type == 'udp_portscan' and discrepancies.udp_open_ports and discrepancies.udp_open_ports.num and discrepancies.udp_open_ports.num>0) then
|
||||
info_json.new_open_ports = tonumber(info_json.new_open_ports or 0) + tonumber(discrepancies.udp_open_ports.num or 0)
|
||||
else
|
||||
info_json.new_open_ports = 0
|
||||
end
|
||||
|
||||
|
||||
local host_discrepancies_details = ""
|
||||
local port_type = "TCP"
|
||||
local prefix_key = "tcp_"
|
||||
if (new_item.scan_type == 'udp_portscan' and info_json ~= {}) then
|
||||
port_type = "UDP"
|
||||
prefix_key = "udp_"
|
||||
end
|
||||
|
||||
if (not cve_case and info_json ~= {}) then
|
||||
-- DISCREPANCY PORTS CASES
|
||||
info_json.discrepancy_case = 'ports'
|
||||
|
||||
if (tonumber(discrepancies[prefix_key.."open_ports"].num or 0) > 0) then
|
||||
-- take only open ports not the closed ports
|
||||
info_json.new_open_ports = tonumber(info_json.new_open_ports or 0) + tonumber(discrepancies[prefix_key.."open_ports"].num or 0)
|
||||
|
||||
host_discrepancies_details = string.format("<br>Host %s has these %s ports open: %s.</br>",new_item.host,port_type,discrepancies[prefix_key.."open_ports"].ports)
|
||||
|
||||
if (isEmptyString(info_json.hosts_discrepancies_details)) then
|
||||
info_json.hosts_discrepancies_details = host_discrepancies_details
|
||||
else
|
||||
info_json.hosts_discrepancies_details = string.format("%s%s",info_json.hosts_discrepancies_details,host_discrepancies_details)
|
||||
end
|
||||
else
|
||||
info_json.new_open_ports = tonumber(info_json.new_open_ports or 0)
|
||||
end
|
||||
end
|
||||
|
||||
if (cve_case and info_json ~= {} and info_json.num_cve_solved and info_json.num_cve_solved > 0) then
|
||||
-- DISCREPANCY CVE CASE
|
||||
info_json.discrepancy_case = 'cves'
|
||||
|
||||
local cve_string = format_port_list_to_string(discrepancies.cve_solved)
|
||||
host_discrepancies_details = string.format("<br>Host %s has solved these CVEs: %s.</br>",new_item.host,cve_string)
|
||||
|
||||
if (isEmptyString(info_json.hosts_discrepancies_details)) then
|
||||
info_json.hosts_discrepancies_details = host_discrepancies_details
|
||||
else
|
||||
info_json.hosts_discrepancies_details = string.format("%s%s",info_json.hosts_discrepancies_details,host_discrepancies_details)
|
||||
end
|
||||
end
|
||||
|
||||
if (debug_me) then
|
||||
if (info_json) then
|
||||
tprint(info_json.hosts_discrepancies_details)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ntop.setCache(redis_info_key, json.encode(info_json))
|
||||
end
|
||||
|
||||
|
|
@ -1107,15 +1190,7 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
|
|||
|
||||
local counts = vs_utils.update_ts_counters()
|
||||
|
||||
if (new_item.is_periodicity) then
|
||||
update_scan_info_for_report(vs_utils.scan_in_exec_type.periodic_scan, new_item, host_hash_key)
|
||||
end
|
||||
|
||||
if (new_item.is_all) then
|
||||
update_scan_info_for_report(vs_utils.scan_in_exec_type.scan_all, new_item, host_hash_key)
|
||||
end
|
||||
|
||||
remove_scanning_host({host=host, scan_type=scan_type, ports=ports})
|
||||
|
||||
|
||||
-- save on db here
|
||||
|
||||
|
|
@ -1134,6 +1209,7 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
|
|||
vs_db_utils.save_vs_result(scan_type, host, new_item.last_scan.epoch, json.encode(new_item), scan_result)
|
||||
end
|
||||
|
||||
local host_info_differences
|
||||
if trigger_alert and old_data and (not is_edit) then
|
||||
local already_scanned = (old_data.last_scan and old_data.last_scan.epoch)
|
||||
|
||||
|
|
@ -1168,6 +1244,7 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
|
|||
|
||||
})
|
||||
if host_info_to_cache then
|
||||
host_info_differences = host_info_to_cache
|
||||
|
||||
if debug_me then
|
||||
traceError(TRACE_NORMAL,TRACE_CONSOLE, "Vulnerability Scan detected change: enqueueing event to vulnerability_scan check\n")
|
||||
|
|
@ -1177,6 +1254,17 @@ function vs_utils.save_host_to_scan(scan_type, host, scan_result, last_scan_time
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (new_item.is_periodicity) then
|
||||
update_scan_info_for_report(vs_utils.scan_in_exec_type.periodic_scan, new_item, host_hash_key, host_info_differences)
|
||||
end
|
||||
|
||||
if (new_item.is_all) then
|
||||
update_scan_info_for_report(vs_utils.scan_in_exec_type.scan_all, new_item, host_hash_key, host_info_differences)
|
||||
end
|
||||
|
||||
remove_scanning_host({host=host, scan_type=scan_type, ports=ports})
|
||||
|
||||
return result, new_item.id
|
||||
end
|
||||
|
||||
|
|
@ -1256,7 +1344,17 @@ local function format_num_for_email(num, case)
|
|||
local formatted_num = format_high_num_value_for_tables({num = num}, "num")
|
||||
return(i18n("hosts_stats.page_scan_hosts.email.num_scanned_hosts", {num = formatted_num}))
|
||||
end
|
||||
elseif (case == 4) then
|
||||
-- not scanned_hosts --> hosts unreachable
|
||||
|
||||
if (num == 0) then
|
||||
return(i18n("hosts_stats.page_scan_hosts.email.no_scanned_hosts"))
|
||||
else
|
||||
local formatted_num = format_high_num_value_for_tables({num = num}, "num")
|
||||
return(i18n("hosts_stats.page_scan_hosts.email.num_failed_scanned_hosts", {num = formatted_num}))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- **********************************************************
|
||||
|
|
@ -1276,16 +1374,31 @@ local function retrieve_email_info(exec_type)
|
|||
tcp_ports = 0
|
||||
}
|
||||
end
|
||||
|
||||
if(debug_me) then
|
||||
tprint(info_json)
|
||||
end
|
||||
|
||||
local email_info = {
|
||||
cve_num = tonumber(info_json.cves) or 0,
|
||||
udp_ports = tonumber(info_json.udp_ports) or 0,
|
||||
tcp_ports = tonumber(info_json.tcp_ports) or 0,
|
||||
scanned_hosts = tonumber(info_json.scanned_hosts) or 0,
|
||||
not_scanned_hosts = tonumber(info_json.not_scanned_hosts) or 0,
|
||||
begin_epoch_t = tonumber(info_json.begin_epoch),
|
||||
end_epoch_t = os.time(),
|
||||
report_type = exec_type
|
||||
report_type = exec_type,
|
||||
-- has_dicrepancy must be true only if there are new open ports or cves fixed
|
||||
has_discrepancy = ((info_json.new_open_ports or 0) > 0) or ((info_json.num_cve_solved or 0) > 0)
|
||||
}
|
||||
|
||||
if (email_info.has_discrepancy) then
|
||||
email_info.new_open_ports = info_json.new_open_ports or 0
|
||||
email_info.fixed_cves = info_json.num_cve_solved or 0
|
||||
local string_hosts_discrepancies_details = tostring(info_json.hosts_discrepancies_details)
|
||||
email_info.discrepancies_details = string_hosts_discrepancies_details:gsub("%|","\n")
|
||||
end
|
||||
|
||||
email_info.duration = email_info.end_epoch_t - email_info.begin_epoch_t
|
||||
|
||||
ntop.setCache(info_redis_key,json.encode({
|
||||
|
|
@ -1293,7 +1406,8 @@ local function retrieve_email_info(exec_type)
|
|||
udp_ports = 0,
|
||||
tcp_ports = 0,
|
||||
begin_epoch = 0,
|
||||
scanned_hosts = 0
|
||||
scanned_hosts = 0,
|
||||
not_scanned_hosts = 0
|
||||
}))
|
||||
return email_info
|
||||
end
|
||||
|
|
@ -1306,6 +1420,7 @@ local function retrieve_report_info(date)
|
|||
tcp_ports = 0,
|
||||
udp_ports = 0,
|
||||
scanned_hosts = 0,
|
||||
not_scanned_hosts = 0
|
||||
}
|
||||
for _, item in ipairs(host_scanned_info) do
|
||||
if (not isEmptyString(item.num_vulnerabilities_found)) then
|
||||
|
|
@ -1314,7 +1429,10 @@ local function retrieve_report_info(date)
|
|||
|
||||
info.tcp_ports = info.tcp_ports + tonumber(item.tcp_ports)
|
||||
info.udp_ports = info.udp_ports + tonumber(item.udp_ports)
|
||||
|
||||
-- plus 1 because start from 0
|
||||
info.scanned_hosts = info.scanned_hosts + 1
|
||||
info.not_scanned_hosts = info.not_scanned_hosts + 1
|
||||
end
|
||||
|
||||
if (date) then
|
||||
|
|
@ -1369,43 +1487,40 @@ function vs_utils.notify_scan_results(exec_type, periodicity)
|
|||
|
||||
ntop.setCache(hosts_scan_last_report_dates, json.encode({start_date = start_date_formatted, end_date = end_date_formatted}))
|
||||
|
||||
local email_body_i18n_key
|
||||
if (periodicity and periodicity == "1day") then
|
||||
notification_message = i18n("hosts_stats.page_scan_hosts.email.periodicity_scan_1_day_ended", {
|
||||
cves = format_num_for_email(email_info.cve_num,0),
|
||||
udp_ports = format_num_for_email(email_info.udp_ports,1),
|
||||
tcp_ports = format_num_for_email(email_info.tcp_ports,2),
|
||||
scanned_hosts = format_num_for_email(email_info.scanned_hosts, 3),
|
||||
url = string.format(getHttpHost() .. ntop.getHttpPrefix() .. "/lua/enterprise/vulnerability_scan_report.lua?epoch_end=%u&epoch_begin=%u",report_date,report_date),
|
||||
duration = duration_label,
|
||||
start_date = start_date_formatted,
|
||||
end_date = end_date_formatted
|
||||
})
|
||||
-- 1 day scan case
|
||||
email_body_i18n_key = "hosts_stats.page_scan_hosts.email.periodicity_scan_1_day_ended"
|
||||
elseif (periodicity and periodicity == "1week") then
|
||||
notification_message = i18n("hosts_stats.page_scan_hosts.email.periodicity_scan_1_week_ended", {
|
||||
cves = format_num_for_email(email_info.cve_num,0),
|
||||
udp_ports = format_num_for_email(email_info.udp_ports,1),
|
||||
tcp_ports = format_num_for_email(email_info.tcp_ports,2),
|
||||
scanned_hosts = format_num_for_email(email_info.scanned_hosts, 3),
|
||||
url = string.format(getHttpHost() .. ntop.getHttpPrefix() .. "/lua/enterprise/vulnerability_scan_report.lua?epoch_end=%u&epoch_begin=%u",report_date,report_date),
|
||||
duration = duration_label,
|
||||
start_date = start_date_formatted,
|
||||
end_date = end_date_formatted
|
||||
})
|
||||
-- 1 week scan case
|
||||
email_body_i18n_key = "hosts_stats.page_scan_hosts.email.periodicity_scan_1_week_ended"
|
||||
else
|
||||
-- on demand scan
|
||||
notification_message = i18n("hosts_stats.page_scan_hosts.email.scan_all_ended", {
|
||||
cves = format_num_for_email(email_info.cve_num,0),
|
||||
udp_ports = format_num_for_email(email_info.udp_ports,1),
|
||||
tcp_ports = format_num_for_email(email_info.tcp_ports,2),
|
||||
scanned_hosts = format_num_for_email(email_info.scanned_hosts, 3),
|
||||
url = string.format(getHttpHost() .. ntop.getHttpPrefix() .. "/lua/enterprise/vulnerability_scan_report.lua?epoch_end=%u&epoch_begin=%u",report_date,report_date),
|
||||
duration = duration_label,
|
||||
start_date = start_date_formatted,
|
||||
end_date = end_date_formatted,
|
||||
|
||||
})
|
||||
-- on demand case
|
||||
email_body_i18n_key = "hosts_stats.page_scan_hosts.email.scan_all_ended"
|
||||
end
|
||||
|
||||
|
||||
notification_message = i18n(email_body_i18n_key, {
|
||||
cves = format_num_for_email(email_info.cve_num,0),
|
||||
udp_ports = format_num_for_email(email_info.udp_ports,1),
|
||||
tcp_ports = format_num_for_email(email_info.tcp_ports,2),
|
||||
scanned_hosts = format_num_for_email(email_info.scanned_hosts, 3),
|
||||
not_scanned_hosts = format_num_for_email(email_info.not_scanned_hosts, 4),
|
||||
url = string.format(getHttpHost() .. ntop.getHttpPrefix() .. "/lua/enterprise/vulnerability_scan_report.lua?epoch_end=%u&epoch_begin=%u",report_date,report_date),
|
||||
duration = duration_label,
|
||||
start_date = start_date_formatted,
|
||||
end_date = end_date_formatted,
|
||||
|
||||
})
|
||||
|
||||
if (email_info.has_discrepancy) then
|
||||
local discrepancies_info = i18n("hosts_stats.page_scan_hosts.email.discrepancy", {
|
||||
new_ports_open = ternary(email_info.new_open_ports ~= 0, format_high_num_value_for_tables({num = email_info.new_open_ports}, "num"),"0"),
|
||||
cves_fixed = ternary(email_info.fixed_cves ~= 0, format_high_num_value_for_tables({num = email_info.fixed_cves }, "num"),"0"),
|
||||
hosts_discrepancy_details = email_info.discrepancies_details
|
||||
})
|
||||
notification_message = string.format("%s\n\n%s",notification_message,discrepancies_info)
|
||||
end
|
||||
if verbose then
|
||||
traceError(TRACE_NORMAL,TRACE_CONSOLE, "Vulnerability Scan completed. Sending " .. title .."\n")
|
||||
end
|
||||
|
|
@ -2019,7 +2134,8 @@ function vs_utils.schedule_periodic_scan(periodicity)
|
|||
udp_ports = 0,
|
||||
tcp_ports = 0,
|
||||
begin_epoch = os.time(),
|
||||
scanned_hosts = 0
|
||||
scanned_hosts = 0,
|
||||
not_scanned_hosts = 0
|
||||
}))
|
||||
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue