From 338bcbea6ef2c2bb649b8e9bfd72ed102eb7ea4b 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 | 98 +++++++++++++++++++++++++++++++++++++++++--- src/utils.h | 6 +++ 4 files changed, 119 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..86f41f386 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,88 @@ 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); +} + +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