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:
- [PATCH] New --version-ports option Kris Katterjohn (Feb 14)