From 4437b29706a7ea28838304d08d98e9f69543d495 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Tue, 7 Jan 2025 13:14:18 -0300 Subject: [PATCH] Add: report_scripts openvas setting Stores in a file the script run duration in json format. This option expects a valid path to store a file with scripts stats. Script run durations are collected only if the log_whole_attack setting is set to 'yes'. For testing, set the setting in openvas.conf with a valid path and set log_whole_attack setting to yes. A json file will be created containing script run duration for each host as json objects. --- doc/man/openvas.8.in | 3 ++ src/attack.c | 21 +++++++-- src/utils.c | 105 ++++++++++++++++++++++++++++++++++++++++--- src/utils.h | 6 +++ 4 files changed, 126 insertions(+), 9 deletions(-) diff --git a/doc/man/openvas.8.in b/doc/man/openvas.8.in index 70a1f20ec..afb2cd1a8 100644 --- a/doc/man/openvas.8.in +++ b/doc/man/openvas.8.in @@ -76,6 +76,9 @@ so you need to find a balance between these two options. Note that launching too .IP log_whole_attack If this option is set to 'yes', openvas will store the name, pid, date and target of each plugin launched. This is helpful for monitoring and debugging purpose, however this option might make openvas fill your disk rather quickly. +.IP report_scripts +Stores in a file the script run duration in json format. This option expects a valid path to store a file with scripts stats. Script run durations are collected only if the log_whole_attack setting is set to 'yes'. This is helpful for monitoring and debugging purpose, however this option might make openvas fill your disk rather quickly. + .IP debug_tls This is an scanner-only option which allows you to set the TLS log level. The level is an integer between 0 and 9. Higher values mean more verbosity and diff --git a/src/attack.c b/src/attack.c index b3d1cc1fb..898d0f19b 100644 --- a/src/attack.c +++ b/src/attack.c @@ -44,6 +44,7 @@ #include /* for nvticache_t */ #include #include +#include #include /* for strlen() */ #include /* for waitpid() */ #include /* for close() */ @@ -702,6 +703,7 @@ attack_host (struct scan_globals *globals, struct in6_addr *ip, pluginlaunch_stop (); plugins_scheduler_free (args->sched); host_set_time (get_main_kb (), ip_str, "HOST_END"); + write_host_stats (args->host_kb, globals->scan_id, ip_str); } /* @@ -1355,6 +1357,7 @@ attack_network (struct scan_globals *globals) alive_hosts_list = gvm_hosts_new (gvm_host_value_str (host)); } + write_script_stats ("{\"hosts\": {", globals->scan_id, 2); /* * Start the attack ! */ @@ -1545,10 +1548,20 @@ attack_network (struct scan_globals *globals) gettimeofday (&now, NULL); if (test_alive_hosts_only) - g_message ("Vulnerability scan %s finished in %ld seconds: " - "%d alive hosts of %d", - globals->scan_id, now.tv_sec - then.tv_sec, - gvm_hosts_count (alive_hosts_list), gvm_hosts_count (hosts)); + { + char *buff; + g_message ("Vulnerability scan %s finished in %ld seconds: " + "%d alive hosts of %d", + globals->scan_id, now.tv_sec - then.tv_sec, + gvm_hosts_count (alive_hosts_list), gvm_hosts_count (hosts)); + + buff = + g_strdup_printf ("},\"scan_time\": {\"start\": %ld, \"stop\": %ld}}", + then.tv_sec, now.tv_sec); + write_script_stats (buff, globals->scan_id, 1); + + g_free (buff); + } else g_message ("Vulnerability scan %s finished in %ld seconds: %d hosts", globals->scan_id, now.tv_sec - then.tv_sec, diff --git a/src/utils.c b/src/utils.c index 1d2f9a481..918fafa29 100644 --- a/src/utils.c +++ b/src/utils.c @@ -14,14 +14,17 @@ #include "../misc/plugutils.h" /* for kb_item_set_int_with_main_kb_check */ #include "../misc/scanneraux.h" /* for struct scan_globals */ +#include "base/networking.h" -#include /* for errno() */ +#include /* for errno() */ +#include #include /* for prefs_get() */ #include /* for is_host_alive() */ -#include /* for atoi() */ -#include /* for strcmp() */ -#include /* for ioctl() */ -#include /* for waitpid() */ +#include +#include /* for atoi() */ +#include /* for strcmp() */ +#include /* for ioctl() */ +#include /* for waitpid() */ extern int global_max_hosts; extern int global_max_checks; @@ -254,3 +257,95 @@ is_scanner_only_pref (const char *pref) return 1; return 0; } + +/** @brief Writes scripts stats into a file. + * + * @param buf String to write. + * @param scan_id Scan ID for the file name. + * @param mode 2 to create the file, 0 to append text to the file, + * 1 to finish the json list removing the trailing comma before + * appending the last text in the buffer. + * + */ +void +write_script_stats (const char *buf, const char *scan_id, int mode) +{ + char *p = NULL; + FILE *path = NULL; + if (!prefs_get ("report_scripts")) + return; + p = + g_strdup_printf ("%s/%s-stats.json", prefs_get ("report_scripts"), scan_id); + + if (mode == 0) + path = fopen (p, "a"); + else if (mode == 1) + path = fopen (p, "r+"); + else if (mode == 2) + path = fopen (p, "w"); + + if (path == NULL) + { + g_warning ("%s: Error opening FILE for script stats: %d - %s", __func__, + errno, strerror (errno)); + return; + } + + if (mode == 1) + { + int ch; + while ((ch = fgetc (path)) != EOF) + ; + + fseek (path, -1, SEEK_CUR); + long end = ftell (path); + g_message ("CURRENT POSITION : %ld", end); + } + fprintf (path, "%s", buf); + fflush (path); + fclose (path); +} + +/** @brief Reads the script stats from the kb and generate a string in json + format to be stored in the disk. + * + * @param kb the host knowledge base to get the information from. + * @param scan_id Scan ID for the file name. + * @param ip target IP address. + */ +void +write_host_stats (kb_t kb, const char *scan_id, const char *ip) +{ + GString *data = g_string_new (""); + struct kb_item *stats = NULL, *stats_tmp = NULL; + int firstvt = 1; + + stats = kb_item_get_pattern (kb, "general/script_stats*"); + stats_tmp = stats; + + g_string_append_printf (data, "\"%s\": [", ip); + while (stats_tmp) + { + char **spl = g_strsplit (stats_tmp->v_str, "/", 0); + char *buf = NULL; + + if (!firstvt) + g_string_append_c (data, ','); + + buf = g_strdup_printf ("{\"%s\": {\"start\": %s, \"stop\": %s}}", spl[0], + spl[1], spl[2]); + + g_string_append (data, buf); + g_strfreev (spl); + g_free (buf); + + stats_tmp = stats_tmp->next; + if (firstvt) + firstvt = 0; + } + g_string_append (data, "],"); + + kb_item_free (stats); + write_script_stats (data->str, scan_id, 0); + g_string_free (data, TRUE); +} diff --git a/src/utils.h b/src/utils.h index c63a7b691..c47ecdbcb 100644 --- a/src/utils.h +++ b/src/utils.h @@ -40,4 +40,10 @@ store_file (struct scan_globals *globals, const char *file, int check_host_still_alive (kb_t, const char *); + +void +write_script_stats (const char *, const char *, int); + +void +write_host_stats (kb_t, const char *, const char *); #endif