Nmap Development mailing list archives

RE: nmap +multiping


From: Dion Stempfley <Dion () riptech com>
Date: Tue, 27 Nov 2001 12:54:00 -0500

Oops... Patch is attached.  It didn't attach like it was supposed to.
Operator head space I guess.  Like I said, the patch is real rough and needs
a rewrite, but this should get someone thinking.

 Since you sound interested, I will start a rework.  


-----Original Message-----
From: Fyodor [mailto:fyodor () insecure org]
Sent: Tuesday, November 27, 2001 1:01 AM
To: Dion Stempfley
Cc: 'nmap-dev () insecure org '
Subject: Re: nmap +multiping


On Tue, Nov 27, 2001 at 12:23:49AM -0500, Dion Stempfley wrote:

I was fighting with the most efficient methods to do host 
discovery, and
found that I occaissionally needed to use different tcp 
ports in tcp ping
scans to get really reliable results.

Cool!  This has been on my TODO list for a long time, but I haven't
had a chance to implement it cleanly.  I have also been using
multi-run approach of doing a "-sS -P0", plus potentially a "-PI" and
several with "-g" source ports such as 20,53,etc.  Then I merge the
results to determine the hosts that deserve the full "-P0 -sSU -p-"
treatment.  Clearly this is suboptimal.  I would accept a clean patch
for allowing multiport pings.  Ideally it should be well tested,
support all the ping types (-PT, -PB, -PS, etc), and have a reasonable
syntax.  Connect() support would be pretty useful as well.

So here is a hack to allow nmap to support multiple tcp 
probe ports during
scanning.

Did you remember to attach the patch or a URL to it?  If you did
attach it, maybe the content-type was wrong (this listserv bans many
application/* types, Word/Excel documents, etc).

It's here now.
 
The syntax is basically:

  nmap -PB -pR:22,23,53,80,443,T:1-1024 ...

Why not extend the current pingport system to allow a list of ports?
For example you can currently do "-PB80" or "-PS80".  How about just
allowing "-PS53,80,113"?


Fair enough. I was just trying to reduce my original code and the command
line parsing for port structures existed.

scanning.  Options such as idle scanning only use the first 
probe port
specified.  

That sounds appropriate.

It seems to work, but has undergone limited testing.  If the general
consenus is that this is useful I will try to clean it up, 
and make it
integrate into the existing code more nicely.

Sure!  I'll bet many people would find it handy!

Cheers,
Fyodor


diff -urNb nmap-2.54BETA30/global_structures.h
nmap-2.54BETA30-multiping/global_structures.h
--- nmap-2.54BETA30/global_structures.h Fri Aug 10 01:53:07 2001
+++ nmap-2.54BETA30-multiping/global_structures.h       Sat Nov 10 01:59:35
2001
@@ -238,7 +238,8 @@
   FingerPrint **reference_FPs;
   u16 magic_port;
   unsigned short magic_port_set; /* Was this set by user? */
-  u16 tcp_probe_port;
+  unsigned short *tcp_probe_port;
+  int tcp_probe_count;
 
   /* Scan timing/politeness issues */
   int max_parallelism;
@@ -298,6 +299,8 @@
        int udp_count;
        unsigned short *prots;
        int prot_count;
+       unsigned short *probe_ports;
+       int probe_count;
 };
 
 
diff -urNb nmap-2.54BETA30/idle_scan.c nmap-2.54BETA30-multiping/idle_scan.c
--- nmap-2.54BETA30/idle_scan.c Sun Oct 14 05:38:26 2001
+++ nmap-2.54BETA30-multiping/idle_scan.c       Fri Oct 19 18:52:40 2001
@@ -249,7 +249,7 @@
     if (*q==0 || !endptr || *endptr != '\0' || !proxy->probe_port) {
       fatal("Invalid port number given in IPID zombie specification: %s",
proxyName);
     }
-  } else proxy->probe_port = o.tcp_probe_port;
+  } else proxy->probe_port = o.tcp_probe_port[0];
 
   proxy->host.name = strdup(name);
 
diff -urNb nmap-2.54BETA30/nmap.c nmap-2.54BETA30-multiping/nmap.c
--- nmap-2.54BETA30/nmap.c      Sun Oct 14 17:28:41 2001
+++ nmap-2.54BETA30-multiping/nmap.c    Wed Nov 21 08:15:43 2001
@@ -669,24 +669,39 @@
       else if (*optarg == 'S') {
        o.pingtype |= (PINGTYPE_TCP|PINGTYPE_TCP_USE_SYN);
        if (isdigit((int) *(optarg+1))) {      
-         o.tcp_probe_port = atoi(optarg+1);
-         log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port);
-       } else if (o.verbose)
-         log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port);
+         if (ports && ports->probe_count)
+        fatal("You can select a ping port with -P or select a list of ports
with -p, but not both");
+         o.tcp_probe_port[0] = atoi(optarg+1); o.tcp_probe_count = 1;
+       }
+       /* With potential port list, print message later 
+       * log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port[0]);
+        *  else if (o.verbose)
+       *   log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port[0]);
+        */
       }
       else if (*optarg == 'T' || *optarg == 'A') {
        o.pingtype |= (PINGTYPE_TCP|PINGTYPE_TCP_USE_ACK);
        if (isdigit((int) *(optarg+1))) {      
-         o.tcp_probe_port = atoi(optarg+1);
-         log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port);
-       } else if (o.verbose)
-         log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port);
+         if (ports && ports->probe_count)
+        fatal("You can select a ping port with -P or select a list of ports
with -p, but not both");
+           o.tcp_probe_port[0] = atoi(optarg+1); o.tcp_probe_count = 1;
+       }
+       /* With potential port list, print message later 
+       * log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port[0]);
+        *  else if (o.verbose)
+       *   log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port[0]);
+        */
       }
       else if (*optarg == 'B') {
        o.pingtype = (PINGTYPE_TCP|PINGTYPE_TCP_USE_ACK|PINGTYPE_ICMP);
-       if (isdigit((int) *(optarg+1)))
-         o.tcp_probe_port = atoi(optarg+1);
-       log_write(LOG_STDOUT, "TCP probe port is %hu\n", o.tcp_probe_port);
+       if (isdigit((int) *(optarg+1))){
+         if (ports && ports->probe_count)
+        fatal("You can select a ping port with -P or select a list of ports
with -p, but not both");
+         o.tcp_probe_port[0] = atoi(optarg+1); o.tcp_probe_count = 1;
+       /* With potential port list, print message later 
+        * log_write(LOG_STDOUT, "TCP probe port is %hu\n",
o.tcp_probe_port[0]);
+       */
+       }
       }
       else {fatal("Illegal Argument to -P, use -P0, -PI, -PT, or -PT80 (or
whatever number you want for the TCP probe destination port)"); }
       break;
@@ -848,8 +863,8 @@
   }
 
 
-  if ((o.pingscan || o.listscan) && ports) {
-    fatal("You cannot use -F (fast scan) or -p (explicit port selection)
with PING scan or LIST scan");
+  if (o.listscan && ports) {
+    fatal("You cannot use -p (explicit port selection) with LIST scan");
   }
 
   if ((o.pingscan || o.listscan) && fastscan) {
@@ -860,6 +875,11 @@
     fatal("-P0 (skip ping) is incompatable with -sP (ping scan).  If you
only want to enumerate hosts, try list scan (-sL)");
   }
 
+  if ((ports && ports->probe_count) && (o.pingtype & PINGTYPE_TCP )) {
+    o.tcp_probe_port = ports->probe_ports; o.tcp_probe_count =
ports->probe_count;
+  }
+
+
   if (!ports) {
     if (o.ipprotscan) {
       ports = getdefaultprots();
@@ -883,7 +903,7 @@
     error("WARNING: protocol scan was requested, but no protocols were
specified to be scanned.  Skipping this scan type.");
 
   /* Default dest port for tcp probe */
-  if (!o.tcp_probe_port) o.tcp_probe_port = DEFAULT_TCP_PROBE_PORT;
+ if (!o.tcp_probe_port[0]){ o.tcp_probe_port[0] = DEFAULT_TCP_PROBE_PORT;
o.tcp_probe_count = 1;}
 
 
   if (o.pingscan && (o.connectscan || o.udpscan || o.windowscan ||
o.synscan || o.idlescan || o.finscan || o.maimonscan ||  o.nullscan ||
o.xmasscan || o.ackscan || o.bouncescan || o.ipprotscan || o.listscan)) {
@@ -1347,7 +1367,7 @@
 }
 
 void options_init() {
-
+  static unsigned short tcp_probe_port;
   bzero( (char *) &o, sizeof(struct ops));
 #ifndef WIN32
   o.isr00t = !(geteuid());
@@ -1369,6 +1389,8 @@
   o.scan_delay = 0;
   o.extra_payload_length = 0;
   o.extra_payload = NULL;
+  o.tcp_probe_port = &tcp_probe_port;
+  o.tcp_probe_count = 0;
 }
 
 /* We set the socket lingering so we will RST connection instead of wasting
@@ -1412,9 +1434,9 @@
   char *current_range;
   char *endptr;
   int i;
-  int tcpportcount = 0, udpportcount = 0, protcount = 0;
+  int tcpportcount = 0, udpportcount = 0, protcount = 0, probecount = 0;
   struct scan_lists *ports;
-  int range_type = SCAN_TCP_PORT|SCAN_UDP_PORT|SCAN_PROTOCOLS;
+  int range_type =
SCAN_TCP_PORT|SCAN_UDP_PORT|SCAN_PROTOCOLS|SCAN_PROBE_PORT;
 
   bzero(porttbl, sizeof(porttbl));
 
@@ -1437,6 +1459,13 @@
        range_type = SCAN_PROTOCOLS;
        continue;
     }
+    if (*current_range == 'R' && *++current_range == ':') {
+        if ( o.tcp_probe_count)
+          fatal("You can select a ping port with -P or select a list of
ports with -p, but not both");
+       current_range++;
+       range_type = SCAN_PROBE_PORT;
+       continue;
+    }
     if (*current_range == '-') {
       rangestart = 1;
     }
@@ -1486,6 +1515,8 @@
        udpportcount++;
       if (range_type & SCAN_PROTOCOLS)
        protcount++;
+      if (range_type & SCAN_PROBE_PORT)
+       probecount++;
       porttbl[rangestart] |= range_type;
       rangestart++;
     }
@@ -1499,8 +1530,8 @@
       current_range++;
   } while(current_range && *current_range);
 
-  if ( 0 == (tcpportcount + udpportcount + protcount))
-    fatal("No ports specified -- If you really don't want to scan any ports
use ping scan...");
+  if ( 0 == (tcpportcount + udpportcount + protcount + probecount))
+    fatal("No ports specified -- You need to specify a list of ports after
-p");
 
   ports = (struct scan_lists *) safe_malloc(sizeof(struct scan_lists));
   bzero(ports, sizeof(ports));
@@ -1516,13 +1547,19 @@
     ports->prots = (unsigned short *)safe_malloc((protcount + 1) *
sizeof(unsigned short));
     bzero(ports->prots, (protcount + 1) * sizeof(unsigned short));
   }
+  if (probecount) {
+    ports->probe_ports = (unsigned short *)safe_malloc((probecount + 1) *
sizeof(unsigned short));
+    bzero(ports->probe_ports, (probecount + 1) * sizeof(unsigned short));
+  }
   ports->tcp_count = tcpportcount;
   ports->udp_count = udpportcount;
   ports->prot_count = protcount;
+  ports->probe_count = probecount;
 
   tcpportcount=0;
   udpportcount=0;
   protcount=0;
+  probecount=0;
   for(i=0; i <= 65535; i++) {
     if (porttbl[i] & SCAN_TCP_PORT)
       ports->tcp_ports[tcpportcount++] = i;
@@ -1530,6 +1567,8 @@
       ports->udp_ports[udpportcount++] = i;
     if (porttbl[i] & SCAN_PROTOCOLS)
       ports->prots[protcount++] = i;
+    if (porttbl[i] & SCAN_PROBE_PORT)
+      ports->probe_ports[probecount++] = i;
   }
 
   /* Someday I am going to make sure this isn't neccessary and then I
@@ -1540,6 +1579,8 @@
     ports->udp_ports[ports->udp_count] = 0; 
   if (protcount)
     ports->prots[ports->prot_count] = 0; 
+  if (probecount)
+    ports->probe_ports[ports->probe_count] = 0; 
   return ports;
 }
 
diff -urNb nmap-2.54BETA30/services.h nmap-2.54BETA30-multiping/services.h
--- nmap-2.54BETA30/services.h  Fri Aug 10 01:53:08 2001
+++ nmap-2.54BETA30-multiping/services.h        Sat Nov 10 03:07:25 2001
@@ -66,6 +66,7 @@
 #define SCAN_TCP_PORT  (1 << 0)
 #define SCAN_UDP_PORT  (1 << 1)
 #define SCAN_PROTOCOLS (1 << 2)
+#define SCAN_PROBE_PORT        (1 << 3)
 
 struct service_list {
   struct servent *servent;
diff -urNb nmap-2.54BETA30/targets.c nmap-2.54BETA30-multiping/targets.c
--- nmap-2.54BETA30/targets.c   Fri Aug 10 01:53:08 2001
+++ nmap-2.54BETA30-multiping/targets.c Wed Nov 21 10:19:20 2001
@@ -494,7 +494,11 @@
 if (o.pingtype & PINGTYPE_TCP) {
   if (o.isr00t)
     ptech.rawtcpscan = 1;
-  else ptech.connecttcpscan = 1;
+  else {
+    if ( o.tcp_probe_count != 1)
+      error("Warning:  You are not root -- using only the first port on the
probe port list");
+    ptech.connecttcpscan = 1;
+  }
 }
 
 time = (struct timeval *) safe_malloc(sizeof(struct timeval) *
((pt.max_tries) * num_hosts));
@@ -712,7 +716,7 @@
 
   bzero(&sock, sockaddr_in_len);
   sock.sin_family = AF_INET;
-  sock.sin_port = htons(o.tcp_probe_port);
+  sock.sin_port = htons(o.tcp_probe_port[0]);
   sock.sin_addr.s_addr = target->host.s_addr;
   
   res = connect(tqi->sockets[seq],(struct sockaddr *)&sock,sizeof(struct
sockaddr));
@@ -743,6 +747,7 @@
 int sendrawtcppingquery(int rawsd, struct hoststruct *target, int seq,
                        struct timeval *time, struct pingtune *pt) {
 int trynum;
+int pc;
 int myseq;
 unsigned short sportbase;
 unsigned long myack = get_random_uint();
@@ -754,12 +759,23 @@
  myseq = (get_random_uint() << 19) + (seq << 3) + 3; /* Response better end
in 011 or 100 */
  memcpy((char *)&(o.decoys[o.decoyturn]), (char *)&target->source_ip,
sizeof(struct in_addr));
  if (o.pingtype & PINGTYPE_TCP_USE_SYN) {   
-   send_tcp_raw_decoys( rawsd, &(target->host), sportbase + trynum,
o.tcp_probe_port, myseq, myack, TH_SYN, 0, NULL, 0, o.extra_payload, 
+
+    if (o.debugging)
+        log_write(LOG_STDOUT, "%d ports being tcp ping scanned",
o.tcp_probe_count );
+   for (pc=0;pc<o.tcp_probe_count;pc++){
+    if (o.debugging)
+        log_write(LOG_STDOUT, "TCP ports %d being tcp ping scanned",
o.tcp_probe_port[pc] );
+     send_tcp_raw_decoys( rawsd, &(target->host), sportbase + trynum,
o.tcp_probe_port[pc], myseq, myack, TH_SYN, 0, NULL, 0, o.extra_payload, 
                        o.extra_payload_length);
+   }
  } else {
-   send_tcp_raw_decoys( rawsd, &(target->host), sportbase + trynum,
o.tcp_probe_port, myseq, myack, TH_ACK, 0, NULL, 0, o.extra_payload, 
+   for (pc=0;pc<o.tcp_probe_count;pc++){
+    if (o.debugging)
+        log_write(LOG_STDOUT, "TCP ports %d being tcp ping scanned",
o.tcp_probe_port[pc] );
+     send_tcp_raw_decoys( rawsd, &(target->host), sportbase + trynum,
o.tcp_probe_port[pc], myseq, myack, TH_ACK, 0, NULL, 0, o.extra_payload, 
                        o.extra_payload_length);
  }
+ }
 
  gettimeofday(&time[seq], NULL);
  return 0;
@@ -874,7 +890,7 @@
 //               case WSAENOTCONN:     //      needed?  this fails around
here on my system
 #endif
                if (errno == EAGAIN && o.verbose) {
-                 log_write(LOG_STDOUT, "Machine %s MIGHT actually be
listening on probe port %d\n", inet_ntoa(hostbatch[hostindex].host),
o.tcp_probe_port);
+                 log_write(LOG_STDOUT, "Machine %s MIGHT actually be
listening on probe port %d\n", inet_ntoa(hostbatch[hostindex].host),
o.tcp_probe_port[0]);
                }
                foundsomething = 1;
                newstate = HOST_UP;     
@@ -902,11 +918,11 @@
                if (res2 == 0)
                  log_write(LOG_STDOUT, "Machine %s is actually LISTENING on
probe port %d\n",
                         inet_ntoa(hostbatch[hostindex].host), 
-                        o.tcp_probe_port);
+                        o.tcp_probe_port[0]);
                else 
                  log_write(LOG_STDOUT, "Machine %s is actually LISTENING on
probe port %d, banner: %s\n",
                         inet_ntoa(hostbatch[hostindex].host), 
-                        o.tcp_probe_port, buf);
+                        o.tcp_probe_port[0], buf);
              }
            }
            if (foundsomething) {

---------------------------------------------------------------------
For help using this (nmap-dev) mailing list, send a blank email to 
nmap-dev-help () insecure org . List run by ezmlm-idx (www.ezmlm.org).



Current thread: