Nmap Development mailing list archives

[PATCH] New --version-ports option


From: Kris Katterjohn <katterjohn () gmail com>
Date: Thu, 14 Feb 2008 13:33:55 -0600

Hey everyone!

I've attached a patch to add a new option: --version-ports. This is an option I've wanted for a while and just drew up a patch for.

It allows you to select the ports you want the service/version detection to probe. A lot of times I want to know all of the open ports on a host and the versions of just a *few* of them. This is useful when scanning the default 1715 ports and only wanting to know the versions of 2-3 (or however many) of those ports. Without this option, a lot of extra ports will have version detection run against them--which wastes traffic and a lot of time.

It supports the same syntax as -p, so "--version-ports T:22,80,110,U:53" will work as expected.

My first instinct was to add a S: directive to -p, but that would call for possibly duplicating ports you want to scan which could lead to confusion (e.g. "-p T:22-25,80,110,S:22,80"). It is simpler though.

I find this very useful, and I think others may as well.

Please test it and let me know what you think.

Thanks,
Kris Katterjohn
Index: service_scan.cc
===================================================================
--- service_scan.cc     (revision 6829)
+++ service_scan.cc     (working copy)
@@ -1634,6 +1634,8 @@
       continue;
     }
     while((nxtport = Targets[targetno]->ports.nextPort(nxtport, TCPANDUDP, PORT_OPEN))) {
+      if (!nxtport->servicescan) /* Check if we run service scan on this port */
+        continue;
       svc = new ServiceNFO(AP);
       svc->target = Targets[targetno];
       svc->portno = nxtport->portno;
@@ -1652,6 +1654,8 @@
       continue;
     }
     while((nxtport = Targets[targetno]->ports.nextPort(nxtport, TCPANDUDP, PORT_OPENFILTERED))) {
+      if (!nxtport->servicescan) /* Check if we run service scan on this port */
+        continue;
       svc = new ServiceNFO(AP);
       svc->target = Targets[targetno];
       svc->portno = nxtport->portno;
Index: Target.h
===================================================================
--- Target.h    (revision 6829)
+++ Target.h    (working copy)
@@ -244,6 +244,8 @@
   int osscanPerformed(void);
   void osscanSetFlag(int flag);
 
+  void setServicePorts(struct scan_lists *);
+
   struct seq_info seq;
   int distance;
   FingerPrintResults *FPR1; /* FP results get by the old OS scan system. */
Index: nmap.cc
===================================================================
--- nmap.cc     (revision 6829)
+++ nmap.cc     (working copy)
@@ -254,6 +254,8 @@
        "  --version-light: Limit to most likely probes (intensity 2)\n"
        "  --version-all: Try every single probe (intensity 9)\n"
        "  --version-trace: Show detailed version scan activity (for debugging)\n"
+       "  --version-ports <ports>: Only run version detection on specified ports\n"
+       "      (uses same syntax as -p)\n"
 #ifndef NOLUA
        "SCRIPT SCAN:\n"
        "  -sC: equivalent to --script=safe,intrusive\n"
@@ -477,7 +479,7 @@
   struct tm *tm;
   HostGroupState *hstate = NULL;
   char *endptr = NULL;
-  struct scan_lists *ports = NULL;
+  struct scan_lists *ports = NULL, *serviceports = NULL;
   TargetGroup *exclude_group = NULL;
   Traceroute *troute = NULL;
   char myname[MAXHOSTNAMELEN + 1];
@@ -493,6 +495,7 @@
   Target *currenths;
   vector<Target *> Targets;
   char *portlist = NULL; /* Ports list specified by user */
+  char *serviceportlist = NULL;
   int sourceaddrwarning = 0; /* Have we warned them yet about unguessable
                                source addresses? */
   unsigned int ideal_scan_group_sz = 0;
@@ -613,6 +616,8 @@
       {"version-light", no_argument, 0, 0},
       {"version_all", no_argument, 0, 0},
       {"version-all", no_argument, 0, 0},
+      {"version-ports", required_argument, 0, 0},
+      {"version_ports", required_argument, 0, 0},
       {"system_dns", no_argument, 0, 0},
       {"system-dns", no_argument, 0, 0},
       {"log_errors", no_argument, 0, 0},
@@ -766,6 +771,10 @@
         o.version_intensity = 2;
       } else if (optcmp(long_options[option_index].name, "version-all") == 0) {
         o.version_intensity = 9;
+      } else if (optcmp(long_options[option_index].name, "version-ports") == 0) {
+       if (serviceportlist)
+         fatal("Only 1 --version-ports option allowed, separate multiple ranges with commas.");
+       serviceportlist = strdup(optarg);
       } else if (optcmp(long_options[option_index].name, "scan-delay") == 0) {
        l = tval2msecs(optarg);
        if (l < 0) fatal("Bogus --scan-delay argument specified.");
@@ -1295,6 +1304,13 @@
     portlist = NULL;
   }
 
+  if (serviceportlist) {
+    serviceports = getpts(serviceportlist);
+    free(serviceportlist);
+    if (!serviceports)
+      fatal("Your version port specification string is not parseable");
+  }
+
   // Uncomment the following line to use the common lisp port spec test suite
   //printf("port spec: (%d %d %d)\n", ports->tcp_count, ports->udp_count, ports->prot_count); exit(0);
 
@@ -1727,6 +1743,9 @@
       o.scriptversion = 1;
 #endif
 
+      for (targetno = 0; targetno < Targets.size(); targetno++)
+          Targets[targetno]->setServicePorts(serviceports);
+
       keyWasPressed(); // Check if a status message should be printed
       service_scan(Targets);
     }
Index: portlist.h
===================================================================
--- portlist.h  (revision 6829)
+++ portlist.h  (working copy)
@@ -227,6 +227,8 @@
   int confidence; /* How sure are we about the state? */
   state_reason_t reason;
 
+  bool servicescan; /* Do we run service/version detection on this port? */
+
 #ifndef NOLUA
   ScriptResults scriptResults;
 #endif
Index: nse_main.cc
===================================================================
--- nse_main.cc (revision 6829)
+++ nse_main.cc (working copy)
@@ -581,6 +581,10 @@
        struct run_record rr;
        unsigned int i;
 
+       if (!o.script && o.scriptversion)
+               if (!port->servicescan)
+                       return SCRIPT_ENGINE_SUCCESS;
+
        for(i = 1; i <= rules_count; i++) {
                lua_rawgeti(l, -2, i);
 
Index: portlist.cc
===================================================================
--- portlist.cc (revision 6829)
+++ portlist.cc (working copy)
@@ -122,6 +122,7 @@
   rpc_program = rpc_lowver = rpc_highver = 0;
   state = confidence = 0;
   next = NULL;
+  servicescan = false;
   serviceprobe_results = PROBESTATE_INITIAL;
   serviceprobe_service = NULL;
   serviceprobe_product = serviceprobe_version = serviceprobe_extrainfo = NULL;
@@ -180,7 +181,6 @@
 
 }
 
-
 // pass in an allocated struct serviceDeductions (don't worry about
 // initializing, and you don't have to free any internal ptrs.  See the
 // serviceDeductions definition for the fields that are populated.
Index: Target.cc
===================================================================
--- Target.cc   (revision 6829)
+++ Target.cc   (working copy)
@@ -475,3 +475,39 @@
                osscan_flag = flag;
 }
 
+static void setServiceFlag(Port *p, struct scan_lists *srvports)
+{
+       int i;
+
+       if (!srvports) {
+               p->servicescan = true;
+               return;
+       }
+
+       if (p->proto == IPPROTO_TCP) {
+               for (i = 0; i < srvports->tcp_count; i++) {
+                       if (srvports->tcp_ports[i] == p->portno) {
+                               p->servicescan = true;
+                               return;
+                       }
+               }
+       } else if (p->proto == IPPROTO_UDP) {
+               for (i = 0; i < srvports->udp_count; i++)
+                       if (srvports->udp_ports[i] == p->portno) {
+                               p->servicescan = true;
+                               return;
+                       }
+       }
+}
+
+void Target::setServicePorts(struct scan_lists *srvports)
+{
+       Port *p = NULL;
+
+       while ((p = ports.nextPort(p, TCPANDUDP, PORT_OPEN)))
+               setServiceFlag(p, srvports);
+
+       while ((p = ports.nextPort(p, TCPANDUDP, PORT_OPENFILTERED)))
+               setServiceFlag(p, srvports);
+}
+

_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org

Current thread: