Hello,
since my Call for Vote for OpenVAS Change Request #49 (see
http://www.openvas.org/openvas-cr-49.html) seems to have been too well hidden
in the patch discussion thread, let me remind you that the voting is still
open and currently at +2.
I'd like to encourage everybody to vote and to vote until next Tuesday so the
feature can make it's way into openvas-libraries soon if there is a positive
vote.
By popular (especially Jan's) demand, I have attached a cleaned up version of
my patch, now with complete with ChangeLog so you can get a better idea of
what I had to change without digging too deep into the code.
Feel free to ask any questions you may have about this feature or the patch.
Have a great weekend,
Michael
--
Michael Wiegand | Greenbone Networks GmbH | http://www.greenbone.net/
Neuer Graben 17, 49074 Osnabrück, Germany | AG Osnabrück, HR B 202460
Executive Directors: Lukas Grunwald, Dr. Jan-Oliver Wagner
#
# This script was written by Michel Arboi <[email protected]>
# Slight changes by Vlatko Kosturjak <[email protected]>
# Used for nmap network level scanning prototype by Michael Wiegand
<[email protected]>
# GPL
#
#
# Nmap can be found at :
# <http://www.insecure.org/nmap/>
#
if(description)
{
script_id(714259);
script_version ("1.19");
script_tag(name:"risk_factor", value:"High");
name = "Nmap NETWORK (NASL wrapper)";
script_name(name);
desc = "
This plugin runs nmap(1) on a network level to find open ports.
";
script_description(desc);
summary = "Performs NETWORK portscan / RPC scan";
script_summary(summary);
script_category(ACT_SCANNER);
script_copyright("This script is Copyright (C) 2004 Michel Arboi");
family = "Port scanners";
script_family(family);
exit(0);
}
function on_exit()
{
if (tmpfile && file_stat(tmpfile)) unlink(tmpfile);
}
tmpfile = NULL;
s = scan_phase ();
if (s == 1) {
netmask = network_netmask ();
i = 0;
argv[i++] = "nmap";
argv[i++] = "-sT";
argv[i++] = "-T5";
argv[i++] = "-oG";
tmpdir = get_tmp_dir();
if (tmpdir && strlen(tmpdir)) {
tmpfile = strcat(tmpdir, "nmap-network-", rand() );
fwrite(data:" ",file:tmpfile); # make sure that tmpfile could be created.
Then we can check that tmpfile exist with file_stat().
}
if (tmpfile && file_stat(tmpfile))
argv[i++] = tmpfile;
else
argv[i++] = "-";
argv[i++] = netmask;
scanner_status(current: 0, total: 65535);
res = pread(cmd: "nmap", argv: argv, cd: 1);
if (tmpfile && file_stat(tmpfile))
res = fread(tmpfile);
if (! res) exit(0); # error
lines = split (res, sep: '\n', keep: FALSE);
foreach blob (lines)
{
c = split(blob,sep:"Ports: ", keep: FALSE);
d = split(c[0],sep:" ", keep: FALSE);
e = split(c[1],sep:", ", keep: FALSE);
if (! isnull (e)) {
foreach f (e) {
g = split (f, sep:"/", keep: FALSE);
security_hole(port: 0, data: d[1] + "/Ports/tcp/" + g[0]);
set_kb_item(name: d[1] + "/Ports/tcp/" + g[0], value: 1);
}
}
}
scanner_status(current: 65535, total: 65535);
}
exit (0);
Index: nasl/nasl_scanner_glue.c
===================================================================
--- nasl/nasl_scanner_glue.c (Revision 9333)
+++ nasl/nasl_scanner_glue.c (Arbeitskopie)
@@ -609,6 +609,50 @@
return retc;
}
+tree_cell *
+scan_phase (lex_ctxt * lexic)
+{
+ struct arglist *script_infos = lexic->script_infos;
+ struct arglist *globals = arg_get_value (script_infos, "globals");
+ char *value;
+ tree_cell *retc = alloc_tree_cell (0, NULL);
+
+ retc->type = CONST_INT;
+ value = arg_get_value (globals, "network_scan_status");
+ if (value)
+ {
+ if (strcmp (value, "busy") == 0)
+ retc->x.i_val = 1;
+ else
+ retc->x.i_val = 2;
+ }
+ else
+ retc->x.i_val = 0;
+
+ return retc;
+}
+
+tree_cell *
+network_targets (lex_ctxt * lexic)
+{
+ struct arglist *script_infos = lexic->script_infos;
+ struct arglist *globals = arg_get_value (script_infos, "globals");
+ char *value;
+ tree_cell *retc;
+
+ value = arg_get_value (globals, "network_targets");
+ retc = alloc_typed_cell (CONST_DATA);
+ if (value)
+ {
+ retc->x.str_val = strdup (value);
+ retc->size = strlen (value);
+ }
+ else
+ return NULL;
+
+ return retc;
+}
+
/*--------------------[ KB ]---------------------------------------*/
#define SECRET_KB_PREFIX "Secret/"
Index: nasl/nasl_scanner_glue.h
===================================================================
--- nasl/nasl_scanner_glue.h (Revision 9333)
+++ nasl/nasl_scanner_glue.h (Arbeitskopie)
@@ -45,6 +45,8 @@
tree_cell *script_get_preference_file_content (lex_ctxt *);
tree_cell *script_get_preference_file_location (lex_ctxt *);
tree_cell *safe_checks (lex_ctxt *);
+tree_cell *scan_phase (lex_ctxt *);
+tree_cell *network_targets (lex_ctxt *);
tree_cell *get_kb_item (lex_ctxt *);
tree_cell *get_kb_fresh_item (lex_ctxt *);
tree_cell *get_kb_list (lex_ctxt *);
Index: nasl/nasl_init.c
===================================================================
--- nasl/nasl_init.c (Revision 9333)
+++ nasl/nasl_init.c (Arbeitskopie)
@@ -419,6 +419,9 @@
{"smb_file_trustee_rights", nasl_smb_file_trustee_rights, 0,
{"filename", "smb_handle", NULL}},
+ {"scan_phase", scan_phase, 0, {NULL}},
+ {"network_targets", network_targets, 0, {NULL}},
+
{NULL, NULL, 0, {NULL}}
};
Index: ChangeLog
===================================================================
--- ChangeLog (Revision 9333)
+++ ChangeLog (Arbeitskopie)
@@ -1,3 +1,16 @@
+2010-11-02 Michael Wiegand <[email protected]>
+
+ New functions for network level scans as described in OpenVAS Change
+ Request #49 (see http://www.openvas.org/openvas-cr-49.html).
+
+ * nasl/nasl_scanner_glue.c (scan_phase, network_targets): New
+ functions to retrieve the current scan phase and network targes from
+ the KB.
+
+ * nasl/nasl_scanner_glue.h: Updated.
+
+ * nasl/nasl_init.c: Exposed new functions.
+
2010-10-27 Michael Wiegand <[email protected]>
Post branch version bump.
Index: ChangeLog
===================================================================
--- ChangeLog (Revision 9333)
+++ ChangeLog (Arbeitskopie)
@@ -1,3 +1,32 @@
+2010-11-02 Michael Wiegand <[email protected]>
+
+ Added support for network level scans as described in OpenVAS Change
+ Request #49 (see http://www.openvas.org/openvas-cr-49.html).
+
+ * openvassd/preferences.c (preferences_network_scan): New function to
+ return the value of the network_scan preference as int.
+
+ * openvassd/preferences.h: Updated.
+
+ * openvassd/pluginscheduler.c (plugins_scheduler_init): Changed
+ function to accept an only_network switch. Remove NVTs in
+ ACT_GATHER_INFO and up from the schedule if only_network is set.
+
+ * openvassd/pluginscheduler.h: Updated.
+
+ * openvassd/save_kb.c (save_kb): Ensure the KB is saved during a
+ network level scan so we can us it later.
+
+ * openvassd/attack.c (launch_plugin): Write to the network KB if we
+ are scanning on the network level.
+ (init_host_kb): If we are in the network scan phase, return a new
+ network KB. If we have completed the network scan, get the relevant
+ items from the network KB and use them in the host KB.
+ (attack_host): Close the correct KB when an attack has finished.
+ (attack_start): Check preferences to see if a network level scan has
+ been requested and make the necessary preparations if this is the
+ case.
+
2010-10-29 Michael Wiegand <[email protected]>
Post-release version bump.
Index: openvassd/preferences.c
===================================================================
--- openvassd/preferences.c (Revision 9333)
+++ openvassd/preferences.c (Arbeitskopie)
@@ -794,6 +794,32 @@
return yes;
}
+int
+preferences_network_scan (struct arglist *preferences)
+{
+ static int yes = -1;
+ char *pref;
+
+ if (!preferences)
+ {
+ yes = -1;
+ return -1;
+ }
+
+
+ if (yes >= 0)
+ return yes;
+
+
+ pref = arg_get_value (preferences, "network_scan");
+ if (pref && !strcmp (pref, "yes"))
+ yes = 1;
+ else
+ yes = 0;
+
+ return yes;
+}
+
/**
* @return NULL if pref is set to "no", preference value otherwise.
*/
Index: openvassd/pluginscheduler.h
===================================================================
--- openvassd/pluginscheduler.h (Revision 9333)
+++ openvassd/pluginscheduler.h (Arbeitskopie)
@@ -113,7 +113,7 @@
void plugin_set_running_state (plugins_scheduler_t, struct scheduler_plugin *,
int);
-plugins_scheduler_t plugins_scheduler_init (struct arglist *, int, int);
+plugins_scheduler_t plugins_scheduler_init (struct arglist *, int, int, int);
struct scheduler_plugin *plugins_scheduler_next (plugins_scheduler_t);
void plugins_scheduler_free (plugins_scheduler_t);
Index: openvassd/preferences.h
===================================================================
--- openvassd/preferences.h (Revision 9333)
+++ openvassd/preferences.h (Arbeitskopie)
@@ -56,5 +56,6 @@
int preferences_silent_dependencies (struct arglist *);
int preferences_nasl_no_signature_check (struct arglist *);
int preferences_drop_privileges (struct arglist *, char *);
+int preferences_network_scan (struct arglist *);
#endif
Index: openvassd/attack.c
===================================================================
--- openvassd/attack.c (Revision 9333)
+++ openvassd/attack.c (Arbeitskopie)
@@ -316,7 +316,16 @@
else
{
kb_item_add_int (kb, asc_id, 1);
- save_kb_write_int (globals, hostname, asc_id, 1);
+ gchar *network_scan_status = arg_get_value (globals, "network_scan_status");
+ if (network_scan_status != NULL)
+ {
+ if (g_ascii_strcasecmp (network_scan_status, "busy") == 0)
+ {
+ save_kb_write_int (globals, "network", asc_id, 1);
+ }
+ }
+ else
+ save_kb_write_int (globals, hostname, asc_id, 1);
}
}
@@ -569,7 +578,30 @@
struct kb_item **kb;
(*new_kb) = FALSE;
char *vhosts = (char *) arg_get_value (hostinfos, "VHOSTS");
+ struct kb_item **network_kb;
+ struct kb_item *host_network_results;
+ struct kb_item *result_iter;
+ gchar *network_scan_status = (gchar *) arg_get_value (globals, "network_scan_status");
+ if (network_scan_status != NULL)
+ {
+ if (g_ascii_strcasecmp (network_scan_status, "done") == 0)
+ {
+ gchar *hostname_pattern = g_strdup_printf ("%s/*", hostname);
+ network_kb = save_kb_load_kb (globals, "network");
+ host_network_results = kb_item_get_pattern (network_kb, hostname_pattern);
+ }
+ if (g_ascii_strcasecmp (network_scan_status, "busy") == 0)
+ {
+ arg_add_value (globals, "CURRENTLY_TESTED_HOST", ARG_STRING,
+ strlen ("network"), "network");
+ save_kb_new (globals, "network");
+ kb = kb_new ();
+ (*new_kb) = TRUE;
+ return kb;
+ }
+ }
+
// Check if kb should be saved.
if (save_kb (globals))
{
@@ -612,6 +644,23 @@
g_strfreev (vhosts_array);
}
+ result_iter = host_network_results;
+ while (result_iter != NULL)
+ {
+ char *newname = strstr (result_iter->name, "/") + 1;
+ if (result_iter->type == KB_TYPE_STR)
+ {
+ kb_item_add_str (kb, newname, result_iter->v.v_str);
+ save_kb_write_str (globals, hostname, newname, result_iter->v.v_str);
+ }
+ else if (result_iter->type == KB_TYPE_INT)
+ {
+ kb_item_add_int (kb, newname, result_iter->v.v_int);
+ save_kb_write_int (globals, hostname, newname, result_iter->v.v_int);
+ }
+ result_iter = result_iter->next;
+ }
+
return kb;
}
@@ -736,8 +785,18 @@
pluginlaunch_stop ();
plugins_scheduler_free (sched);
- if (new_kb == TRUE)
- save_kb_close (globals, hostname);
+ gchar *network_scan_status = arg_get_value (globals, "network_scan_status");
+ if (network_scan_status != NULL)
+ {
+ if (g_ascii_strcasecmp (network_scan_status, "busy") == 0)
+ {
+ save_kb_close (globals, "network");
+ }
+ }
+ else
+ if (new_kb == TRUE)
+ save_kb_close (globals, hostname);
+
}
/**
@@ -896,11 +955,36 @@
inaddrs_t addrs;
char buffer[INET6_ADDRSTRLEN];
+ int network_phase = 0;
+ gchar *network_targets;
+ int do_network_scan = 0;
+
gettimeofday (&then, NULL);
host_ip = in6addr_any;
preferences = arg_get_value (globals, "preferences");
+ do_network_scan = preferences_network_scan (preferences);
+ log_write ("do_network_scan is %d", do_network_scan);
+ network_targets = arg_get_value (preferences, "network_targets");
+ arg_add_value (globals, "network_targets", ARG_STRING,
+ strlen (network_targets), network_targets);
+ if (do_network_scan)
+ {
+ gchar *network_scan_status = arg_get_value (globals, "network_scan_status");
+ if (network_scan_status != NULL)
+ if (g_ascii_strcasecmp (network_scan_status, "done") == 0)
+ network_phase = 0;
+ else
+ network_phase = 1;
+ else
+ {
+ arg_add_value (globals, "network_scan_status", ARG_STRING,
+ strlen ("busy"), "busy");
+ network_phase = 1;
+ }
+ }
+
num_tested = 0;
global_socket = GPOINTER_TO_SIZE (arg_get_value (globals, "global_socket"));
@@ -938,16 +1022,36 @@
sched =
plugins_scheduler_init (plugins,
preferences_autoload_dependencies (preferences),
- preferences_silent_dependencies (preferences));
+ preferences_silent_dependencies (preferences),
+ network_phase);
hg_flags = preferences_get_host_expansion (preferences);
max_hosts = get_max_hosts_number (globals, preferences);
int max_checks = get_max_checks_number (globals, preferences);
- log_write
- ("user %s starts a new scan. Target(s) : %s, with max_hosts = %d and max_checks = %d\n",
- attack_user_name (globals), hostlist, max_hosts, max_checks);
+ if (network_phase)
+ {
+ network_targets = arg_get_value (preferences, "network_targets");
+ if (network_targets == NULL)
+ {
+ log_write ("WARNING: In network phase, but without targets! Stopping.\n");
+ hg_res = -1;
+ }
+ else
+ {
+ log_write
+ ("user %s starts a new scan. Target(s) : %s, in network phase with target %s\n",
+ attack_user_name (globals), hostlist, network_targets);
+ }
+ }
+ else
+ {
+ log_write
+ ("user %s starts a new scan. Target(s) : %s, with max_hosts = %d and max_checks = %d\n",
+ attack_user_name (globals), hostlist, max_hosts, max_checks);
+ }
+
/* Initialize the hosts_gatherer library. */
if (preferences_get_slice_network_addresses (preferences) != 0)
hg_flags |= HG_DISTRIBUTE;
@@ -975,54 +1079,57 @@
{
nthread_t pid;
- /* openvassd offers the ability to either test
- * only the hosts we tested in the past, or only
- * the hosts we never tested (or both, of course) */
- if (save_kb (globals))
+ if (! network_phase)
{
- if (save_kb_pref_tested_hosts_only (globals))
+ /* openvassd offers the ability to either test
+ * only the hosts we tested in the past, or only
+ * the hosts we never tested (or both, of course) */
+ if (save_kb (globals))
{
- if (!save_kb_exists (globals, hostname))
+ if (save_kb_pref_tested_hosts_only (globals))
{
- log_write
- ("user %s : not testing %s because it has never been tested before\n",
- attack_user_name (globals), hostname);
- hg_res =
- hg_next_host (hg_globals, &host_ip, hostname,
- sizeof (hostname));
+ if (!save_kb_exists (globals, hostname))
+ {
+ log_write
+ ("user %s : not testing %s because it has never been tested before\n",
+ attack_user_name (globals), hostname);
+ hg_res =
+ hg_next_host (hg_globals, &host_ip, hostname,
+ sizeof (hostname));
- if (tested != NULL)
- {
- while (hg_res >= 0
- && g_hash_table_lookup (tested, hostname) != 0)
- hg_res =
- hg_next_host (hg_globals, &host_ip, hostname,
- sizeof (hostname));
+ if (tested != NULL)
+ {
+ while (hg_res >= 0
+ && g_hash_table_lookup (tested, hostname) != 0)
+ hg_res =
+ hg_next_host (hg_globals, &host_ip, hostname,
+ sizeof (hostname));
+ }
+ continue;
}
- continue;
}
- }
- else if (save_kb_pref_untested_hosts_only (globals))
- {
- /* XXX */
- if (save_kb_exists (globals, hostname))
+ else if (save_kb_pref_untested_hosts_only (globals))
{
- log_write
- ("user %s : not testing %s because it has already been tested before\n",
- attack_user_name (globals), hostname);
- hg_res =
- hg_next_host (hg_globals, &host_ip, hostname,
- sizeof (hostname));
- // If some hosts were tested already, jump over them.
- if (tested != NULL)
+ /* XXX */
+ if (save_kb_exists (globals, hostname))
{
- while (hg_res >= 0
- && g_hash_table_lookup (tested, hostname) != 0)
- hg_res =
- hg_next_host (hg_globals, &host_ip, hostname,
- sizeof (hostname));
+ log_write
+ ("user %s : not testing %s because it has already been tested before\n",
+ attack_user_name (globals), hostname);
+ hg_res =
+ hg_next_host (hg_globals, &host_ip, hostname,
+ sizeof (hostname));
+ // If some hosts were tested already, jump over them.
+ if (tested != NULL)
+ {
+ while (hg_res >= 0
+ && g_hash_table_lookup (tested, hostname) != 0)
+ hg_res =
+ hg_next_host (hg_globals, &host_ip, hostname,
+ sizeof (hostname));
+ }
+ continue;
}
- continue;
}
}
}
@@ -1103,27 +1210,41 @@
}
hosts_set_pid (hostname, pid);
- log_write ("user %s : testing %s (%s) [%d]\n",
- attack_user_name (globals), hostname, inet_ntop (AF_INET6,
- &args.
- hostip,
- buffer,
- sizeof
- (buffer)),
- pid);
+ if (network_phase)
+ log_write ("user %s : testing %s (network level) [%d]\n",
+ attack_user_name (globals), network_targets,
+ pid);
+ else
+ log_write ("user %s : testing %s (%s) [%d]\n",
+ attack_user_name (globals), hostname, inet_ntop (AF_INET6,
+ &args.
+ hostip,
+ buffer,
+ sizeof
+ (buffer)),
+ pid);
if (MAC != NULL)
efree (&MAC);
}
num_tested++;
- hg_res = hg_next_host (hg_globals, &host_ip, hostname, sizeof (hostname));
- if (tested != NULL)
+
+ if (network_phase)
{
- while (hg_res >= 0 && g_hash_table_lookup (tested, hostname))
+ hg_res = -1;
+ arg_set_value (globals, "network_scan_status", strlen ("done"), "done");
+ }
+ else
+ {
+ hg_res = hg_next_host (hg_globals, &host_ip, hostname, sizeof (hostname));
+ if (tested != NULL)
{
- hg_res =
- hg_next_host (hg_globals, &host_ip, hostname,
- sizeof (hostname));
+ while (hg_res >= 0 && g_hash_table_lookup (tested, hostname))
+ {
+ hg_res =
+ hg_next_host (hg_globals, &host_ip, hostname,
+ sizeof (hostname));
+ }
}
}
}
@@ -1181,5 +1302,8 @@
log_write ("Total time to scan all hosts : %ld seconds\n",
now.tv_sec - then.tv_sec);
+ if (do_network_scan && network_phase)
+ return attack_network (globals);
+
return 0;
}
Index: openvassd/save_kb.c
===================================================================
--- openvassd/save_kb.c (Revision 9333)
+++ openvassd/save_kb.c (Arbeitskopie)
@@ -750,6 +750,10 @@
if (!globals)
return 0;
+ value = arg_get_value (globals, "network_scan_status");
+ if (value && !strcmp (value, "busy"))
+ return 1;
+
preferences = arg_get_value (globals, "preferences");
if (!preferences)
return 0;
Index: openvassd/pluginscheduler.c
===================================================================
--- openvassd/pluginscheduler.c (Revision 9333)
+++ openvassd/pluginscheduler.c (Arbeitskopie)
@@ -534,7 +534,7 @@
plugins_scheduler_t
plugins_scheduler_init (struct arglist *plugins, int autoload,
- int silent_dependencies)
+ int silent_dependencies, int only_network)
{
plugins_scheduler_t ret = emalloc (sizeof (*ret));
struct arglist *arg;
@@ -637,6 +637,13 @@
}
}
+ if (only_network)
+ {
+ for (i = ACT_GATHER_INFO; i <= ACT_LAST; i++)
+ {
+ ret->list[i] = NULL;
+ }
+ }
return ret;
}
_______________________________________________
Openvas-devel mailing list
[email protected]
http://lists.wald.intevation.org/mailman/listinfo/openvas-devel