Hello, As you may know, scanning virtual hosts on a web server can be very difficult if not downright impossible with the current OpenVAS-Scanner.
I have attached a patch which may help to solve this issue with minimal changes to existing NVTs. You can test this feature by setting the new scanner preferences "vhosts" or "vhosts_ip". Setting can be done by either putting them in the openvassd.conf in the scanner or in the appropriate openvasrc on the client. If either one of this preferences is not set, the scanner behaviour will not change. "vhosts_ip" must contain the IP of the host where the web server serving the virtual hosts resides, whereas "vhosts" must contain a comma separated list of virtual hosts: vhosts_ip = 192.168.1.2 vhosts = virtual1,virtual2 You now should see the results for all virtual hosts in the scan result. Please note however: - NVTs currently do not report on which virtual hosts a result was found. Changing this will require changes to NVTs. - NASL developers: The function get_host_name () may now fork if there is more than one virtual host defined. This means that get_host_name should be called if you are acting on an open socket or other resources. In other words, send(socket:soc,data:'GET / HTTP/1.1\r\nHost: '+get_host_name()+'\r\n\r\n'); is bad style and will not work with more than one vhost. Do this instead: req='GET / HTTP/1.1\r\nHost: '+get_host_name()+'\r\n\r\n'; and later: send(socket:soc, data:req); This makes sure you are on the correct side of the fork and have all resources at your disposal. If you are using http_get to create your http request (as you should), you don't need to worry about anything. - There could be side effects for NVTs using get_host_name for tests unrelated to (virtual) web hosts. So far, I have not observed any such effects, please do report them if you encounter them. Have fun testing, I'm looking forward to your feedback and questions. Regards, 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
Index: misc/plugutils.c =================================================================== --- misc/plugutils.c (Revision 8141) +++ misc/plugutils.c (Arbeitskopie) @@ -819,7 +819,14 @@ { struct arglist *hinfos = arg_get_value (desc, "HOSTNAME"); if (hinfos) - return ((char *) arg_get_value (hinfos, "FQDN")); + { + int type; + char *vhosts = plug_get_key (desc, "hostinfos/vhosts", &type); + if (vhosts) + return vhosts; + else + return ((char *) arg_get_value (hinfos, "FQDN")); + } else return (NULL); }
Index: openvassd/attack.c =================================================================== --- openvassd/attack.c (Revision 8141) +++ openvassd/attack.c (Arbeitskopie) @@ -134,14 +134,63 @@ * - NAME (string, The hostname parameter) * - MAC (string, The mac parameter if non-NULL) * - IP (*in_adrr, The ip parameter) + * - VHOSTS (string, comma separated list of vhosts for this IP) * * @param mac MAC- adress of host or NULL. * @param hostname Hostname to be set. * @param ip in_adress struct to be set. + * @param vhosts vhosts list to be set * * @return A 'hostinfo' arglist. */ static struct arglist * +attack_init_hostinfos_vhosts (char *mac, char *hostname, struct in6_addr *ip, char *vhosts) +{ + struct arglist *hostinfos; + + hostinfos = emalloc (sizeof (struct arglist)); + if (!hg_valid_ip_addr (hostname)) + { + char f[1024]; + hg_get_name_from_ip (ip, f, sizeof (f)); + arg_add_value (hostinfos, "FQDN", ARG_STRING, strlen (f), estrdup (f)); + } + else + arg_add_value (hostinfos, "FQDN", ARG_STRING, strlen (hostname), + estrdup (hostname)); + + if (mac) + { + arg_add_value (hostinfos, "NAME", ARG_STRING, strlen (mac), mac); + arg_add_value (hostinfos, "MAC", ARG_STRING, strlen (mac), mac); + } + else + arg_add_value (hostinfos, "NAME", ARG_STRING, strlen (hostname), + estrdup (hostname)); + + arg_add_value (hostinfos, "IP", ARG_PTR, sizeof (struct in6_addr), ip); + if (vhosts) + arg_add_value (hostinfos, "VHOSTS", ARG_STRING, strlen (vhosts), + estrdup (vhosts)); + return (hostinfos); +} + +/** + * @brief Inits an arglist which can be used by the plugins. + * + * The arglist will have following keys and (type, value): + * - FQDN (string, Fully qualified domain name, e.g. host.domain.net) + * - NAME (string, The hostname parameter) + * - MAC (string, The mac parameter if non-NULL) + * - IP (*in_adrr, The ip parameter) + * + * @param mac MAC- adress of host or NULL. + * @param hostname Hostname to be set. + * @param ip in_adress struct to be set. + * + * @return A 'hostinfo' arglist. + */ +static struct arglist * attack_init_hostinfos (char *mac, char *hostname, struct in6_addr *ip) { struct arglist *hostinfos; @@ -515,10 +564,11 @@ * @see fill_host_kb_ssh_credentials */ static struct kb_item ** -init_host_kb (struct arglist *globals, char *hostname, gboolean * new_kb) +init_host_kb (struct arglist *globals, char *hostname, struct arglist *hostinfos, gboolean * new_kb) { struct kb_item **kb; (*new_kb) = FALSE; + char *vhosts = (char *) arg_get_value (hostinfos, "VHOSTS"); // Check if kb should be saved. if (save_kb (globals)) @@ -548,6 +598,19 @@ // Add local check (SSH)- related knowledge base items fill_host_kb_ssh_credentials (kb, globals, hostname); + // If vhosts is set, split it and put it in the KB + if (vhosts) + { + gchar **vhosts_array = g_strsplit (vhosts, ",", 0); + guint i = 0; + while (vhosts_array[i] != NULL) + { + kb_item_add_str (kb, "hostinfos/vhosts", vhosts_array[i]); + save_kb_write_str (globals, hostname, "hostinfos/vhosts", vhosts_array[i]); + i++; + } + g_strfreev (vhosts_array); + } return kb; } @@ -571,7 +634,7 @@ setproctitle ("testing %s", (char *) arg_get_value (hostinfos, "NAME")); - kb = init_host_kb (globals, hostname, &new_kb); + kb = init_host_kb (globals, hostname, hostinfos, &new_kb); num_plugs = get_active_plugins_number (plugins); @@ -692,6 +755,8 @@ struct arglist *preferences = arg_get_value (globals, "preferences"); char *non_simult = arg_get_value (preferences, "non_simult_ports"); + char *vhosts = arg_get_value (preferences, "vhosts"); + char *vhosts_ip = arg_get_value (preferences, "vhosts_ip"); int thread_socket = args->thread_socket; int soc; struct timeval then, now; @@ -730,7 +795,24 @@ arg_add_value (globals, "confirm", ARG_INT, sizeof (int), (void *) 1); soc = thread_socket; - hostinfos = attack_init_hostinfos (mac, hostname, hostip); + if (vhosts == NULL || vhosts_ip == NULL) + hostinfos = attack_init_hostinfos (mac, hostname, hostip); + else + { + char *txt_ip; + struct in_addr inaddr; + char name[512]; + inaddr.s_addr = hostip->s6_addr32[3]; + + if (IN6_IS_ADDR_V4MAPPED (hostip)) + txt_ip = estrdup (inet_ntoa (inaddr)); + else + txt_ip = estrdup (inet_ntop (AF_INET6, hostip, name, sizeof (name))); + if (strcmp (vhosts_ip, txt_ip) != 0) + vhosts = NULL; + hostinfos = attack_init_hostinfos_vhosts (mac, hostname, hostip, vhosts); + } + if (mac) hostname = mac;
Index: scripts/http_func.inc =================================================================== --- scripts/http_func.inc (Revision 8141) +++ scripts/http_func.inc (Arbeitskopie) @@ -117,6 +117,8 @@ if (! get_port_state(default)) exit(0); + req='GET / HTTP/1.1\r\nHost: ' + get_host_name() + '\r\n\r\n'; + soc = http_open_socket(default); if ( ! soc ) { @@ -124,7 +126,7 @@ exit(0); } - send(socket:soc, data:'GET / HTTP/1.1\r\nHost: ' + get_host_name() + '\r\n\r\n'); + send(socket:soc, data:req); r = recv_line(socket:soc, length:4096); close(soc); now = unixtime();
_______________________________________________ Openvas-devel mailing list Openvas-devel@wald.intevation.org http://lists.wald.intevation.org/mailman/listinfo/openvas-devel