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

Reply via email to