Nmap Development mailing list archives

Gen1 OS Detection bugs?


From: Kris Katterjohn <katterjohn () gmail com>
Date: Thu, 17 May 2007 12:46:05 -0500

Hey nmap-dev!

I made a patch to fix Sebastian's problem when using OS Detection (gen1)
and port 0.  He said the patch works for him, and I test the SVN version
of Nmap, got the problem, and the patch fixes it for me, too.  So that
seems to work.. but then I start looking around in osscan.cc...

Apparently, Nmap actually sends a UDP packet to a closed *TCP* port
instead of UDP.  It uses the same closed port number it grabs for TCP
and uses it for UDP.  Is it for some reason the intended behavior?  Or
has it been like this so long that the wrong results would be given if
this is fixed?  Or is this something that's not worth fixing anyway
because it's just gen1?  Or am I confused?

I attached two patches.  The first one is the patch to skip port 0 if
possible when grabbing a closed port (fixing Sebastian's problem).  The
second is a rough patch to possibly fix the possible problem I've just
talked about (and has the skip-port-0 code in it).

(I was considering applying the port 0 patch to /nmap but then I
realized this potential problem, which uses the same code so that's why
I'm sending both. Two reviews at once :P)

Please let me know what you think about these!


Thanks,
Kris Katterjohn
Index: osscan.cc
===================================================================
--- osscan.cc   (revision 4730)
+++ osscan.cc   (working copy)
@@ -575,10 +575,21 @@
   /* Now we should find a closed port */
   if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_CLOSED))) {
     closedport = tport->portno;
-    target->FPR1->osscan_closedtcpport = tport->portno;
+
+    /* Port 0 seems to screw things up, so try to get another if available */
+    if (tport->portno == 0)
+      if ((tport = target->ports.nextPort(tport, IPPROTO_TCP, PORT_CLOSED)))
+        closedport = tport->portno;
+
+    target->FPR1->osscan_closedtcpport = closedport;
   } else if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_UNFILTERED))) {
     /* Well, we will settle for unfiltered */
     closedport = tport->portno;
+
+    /* Port 0 seems to screw things up, so try to get another if available */
+    if (tport->portno == 0)
+      if ((tport = target->ports.nextPort(tport, IPPROTO_TCP, PORT_CLOSED)))
+        closedport = tport->portno;
   } else {
     closedport = (get_random_uint() % 14781) + 30000;
   }
Index: osscan.cc
===================================================================
--- osscan.cc   (revision 4730)
+++ osscan.cc   (working copy)
@@ -490,7 +490,8 @@
   unsigned int sequence_base;
   unsigned long openport;
   unsigned int bytes;
-  unsigned int closedport = 31337;
+  unsigned int closedtcpport = 31337;
+  unsigned int closedudpport = 31337;
   Port *tport = NULL;
   char filter[512];
   double seq_inc_sum = 0;
@@ -572,19 +573,52 @@
     target->FPR1->osscan_opentcpport = tport->portno;
   }
  
-  /* Now we should find a closed port */
+  /* Now we should find a closed TCP port */
   if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_CLOSED))) {
-    closedport = tport->portno;
-    target->FPR1->osscan_closedtcpport = tport->portno;
+    closedtcpport = tport->portno;
+
+    /* We'd prefer something non-zero */
+    if (tport->portno == 0)
+      if ((tport = target->ports.nextPort(tport, IPPROTO_TCP, PORT_CLOSED)))
+        closedtcpport = tport->portno;
+
+    target->FPR1->osscan_closedtcpport = closedtcpport;
   } else if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_UNFILTERED))) {
     /* Well, we will settle for unfiltered */
-    closedport = tport->portno;
+    closedtcpport = tport->portno;
+
+    /* We'd prefer something non-zero */
+    if (tport->portno == 0)
+      if ((tport = target->ports.nextPort(tport, IPPROTO_TCP, PORT_CLOSED)))
+        closedtcpport = tport->portno;
   } else {
-    closedport = (get_random_uint() % 14781) + 30000;
+    closedtcpport = (get_random_uint() % 14781) + 30000;
   }
 
+  /* Now we should find a closed UDP port */
+  if ((tport = target->ports.nextPort(NULL, IPPROTO_UDP, PORT_CLOSED))) {
+    closedudpport = tport->portno;
+
+    /* Port 0 seems to screw things up, so try to get another if available */
+    if (tport->portno == 0)
+      if ((tport = target->ports.nextPort(tport, IPPROTO_UDP, PORT_CLOSED)))
+        closedudpport = tport->portno;
+
+    target->FPR1->osscan_closedudpport = closedudpport;
+  } else if ((tport = target->ports.nextPort(NULL, IPPROTO_UDP, PORT_UNFILTERED))) {
+    /* Well, we will settle for unfiltered */
+    closedudpport = tport->portno;
+
+    /* Port 0 seems to screw things up, so try to get another if available */
+    if (tport->portno == 0)
+      if ((tport = target->ports.nextPort(tport, IPPROTO_UDP, PORT_CLOSED)))
+        closedudpport = tport->portno;
+  } else {
+    closedudpport = (get_random_uint() % 14781) + 30000;
+  }
+
   if (o.verbose && openport != (unsigned long) -1)
-    log_write(LOG_STDOUT, "For OSScan assuming port %lu is open, %d is closed, and neither are firewalled\n", 
openport, closedport);
+    log_write(LOG_STDOUT, "For OSScan assuming port %lu is open, %d is closed, and neither are firewalled\n", 
openport, closedtcpport);
 
   current_port = o.magic_port + NUM_SEQ_SAMPLES +1;
  
@@ -632,7 +666,7 @@
     if (!FPtests[5]) {   
       if (o.scan_delay) enforce_scan_delay(NULL);
      send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0,
-                        current_port +4, closedport, sequence_base, 0, 0,
+                        current_port +4, closedtcpport, sequence_base, 0, 0,
                         TH_SYN, 0, 0, (u8 *) 
"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
     }
 
@@ -640,7 +674,7 @@
     if (!FPtests[6]) {   
       if (o.scan_delay) enforce_scan_delay(NULL);
      send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0,
-                        current_port +5, closedport, sequence_base, 0, 0,
+                        current_port +5, closedtcpport, sequence_base, 0, 0,
                         TH_ACK, 0, 0, (u8 *) 
"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
     }
 
@@ -648,14 +682,14 @@
     if (!FPtests[7]) {
       if (o.scan_delay) enforce_scan_delay(NULL);   
      send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false, NULL, 0,
-                        current_port +6, closedport, sequence_base, 0, 0,
+                        current_port +6, closedtcpport, sequence_base, 0, 0,
                         TH_FIN|TH_PUSH|TH_URG, 0, 0, (u8 *) 
"\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
     }
 
     /* Test 8 */
     if (!FPtests[8]) {
       if (o.scan_delay) enforce_scan_delay(NULL);
-      upi = send_closedudp_probe(rawsd, ethptr, target->v4hostip(), o.magic_port, closedport);
+      upi = send_closedudp_probe(rawsd, ethptr, target->v4hostip(), o.magic_port, closedudpport);
     }
     gettimeofday(&t1, NULL);
     timeout = 0;

Attachment: signature.asc
Description: OpenPGP digital signature


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

Current thread: