Penetration Testing mailing list archives

Re: UDP Scanning - how nmap really works


From: "Robert E. Lee" <robert () dyadsecurity com>
Date: Tue, 10 Aug 2004 18:24:48 -0700

joshnunan123 () yahoo com(joshnunan123 () yahoo com)@Tue, Aug 10, 2004 at 12:04:19PM -0000:
Using nmap for udp scanning, I commonly come across hosts such as this:
      root@source# nmap -sU -P0 -T Aggressive -F target

It is well documented that UDP scanners wait for an "icmp port unreachable" message to differentiate between 
open/filtered 
and closed ports. A software/hardware packet filter between the source and the target seems to be blocking these 
packets. 
Seen as this method cannot be used, it does not seem feasible for nmap to generate any meaningful information in this 
situation yet somehow it is differentiating between filtered and open udp ports. 

Let's examine what is really happening here.  I'm taking all of the source snippets from 3.55 (the latest public 
general release).

First, definition of terms.:
  Open - According to line 1634 of file nmap.cc:
    case PORT_OPEN: return "open"; break;
    What that says, is if something is matched as being PORT_OPEN, display it as open in the output.
    
  Filtered - According to line 1635 of file nmap.cc:
    case PORT_FIREWALLED: return "filtered"; break;
    What that says, is if something is matched as being PORT_FIREWALLED, display it as filtered in the output.

  Closed - According to line 1637 of file nmap.cc:
    case PORT_CLOSED: return "closed"; break;
    What that says, is if something is matched as being PORT_CLOSED, display it as closed in the output.
  
So how does it match PORT_FIREWALLED in UDP scanning?  For the answer to that, if we look around line 1710 of 
scan_engine.cc we see:
  case 3: /* p0rt unreachable */
    if (scantype == UDP_SCAN &&
        ip->ip_src.s_addr == target->v4host().s_addr) {
       newstate = PORT_CLOSED;
     } else newstate = PORT_FIREWALLED;
     break;
This basically says, if we receive a p0rt unreachable from the target, count that as a CLOSED response.  If we get a 
p0rt unreachable from any other IP count it as a PORT_FIREWALLED response.

Skip down to line 1719:
  case 13: /* Administratively prohibited packet */
    newstate = PORT_FIREWALLED;
    break;
This says if we get an Administratively prohibited packet back from any ip, count it as a PORT_FIREWALLED response.

For how we get an open, this comment sheds some light (around line 1847):
  /* Super scan relies on us receiving a response if the port is
     CLOSED and no response if the port is OPEN.  A problem with
     this is that when a machine is doing heavy filtering, all ports
     will seem to be open.  Thus we add a little metric: if > 25
     ports were scanned and they are ALL considered open by this
     function, then it is reasonably to assume that the REAL reason
     they are all open is that they have been filtered. */

To see what case 3 and case 13 are referring to, pull up the file tcpip.cc and look around line 334:
      else if (ping->code == 3)
        strcpy(icmptype, "port unreachable");
Also known as ICMP Type 3 Code 3, T3C3 for short (see http://www.iana.org/assignments/icmp-parameters).

On line 354:
      else if (ping->code == 13)
        strcpy(icmptype, "communication administratively prohibited by filtering");
Also known as ICMP Type 3 Code 13, T3C13 for short (see http://www.iana.org/assignments/icmp-parameters).

All of this can be summarized from the nmap man page:
       -sU    UDP  scans:  This method is used to determine which
              UDP (User Datagram Protocol,  RFC  768)  ports  are
              open  on  a  host.  The technique is to send 0 byte
              UDP packets to each port on the target machine.  If
              we  receive  an ICMP port unreachable message, then
              the port is closed.   Otherwise  we  assume  it  is
              open.   Unfortunately,  firewalls  often  block the
              port unreachable  messages,  causing  the  port  to
              appear  open.   Sometimes  an ISP will block only a
              few specific dangerous ports such  as  31337  (back
              orifice)  and 139 (Windows NetBIOS), making it look
              like these vulnerable ports  are  open.   So  don't
              panic  immediately.  Unfortunately, it isn't always
              trivial to  differentiate  between  real  open  UDP
              ports and these filtered false-positives.

It is "trivial" on a one port by one port basis .. but if you scanned 5 ports on a /24, the response data from nmap -sU 
scanning is completely useless when the target network has an ACL or firewall in front of the targets being scanned.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

OK .. now that we have a primer on what nmap is doing with responses, we'll go through the rest of the email.

If the port is open, nmap sends two udp packets with a length of zero -- no data is returned.
Sort of.  Nmap will send a different number of tries depending on which -T level you specify.  In this case, since you 
were sending fewer than 25 ports per machine, the default response type for getting nothing back from the target when 
sent a UDP packet is to report that the port is open.  I repeat, this means that if the nmap scanner did not receive 
any response for any reason, it will count it as open.  This makes udp scanning with nmap a frustrating experience when 
dealing with networks that have ACL/Firewalls of any kind.  Also be careful trying to UDP scan too fast if you're 
relying on ICMP messages to determine what is open or closed as these ICMP response messages are commonly rate limited 
in the kernel on the target machine.

If the port is filtered, nmap sends a single udp packet with a length of zero -- no data is returned.
It likely did get a response.  Nmap likely sent a UDP packet and received either an ICMP T3C3 from a host other than 
the target, or it received an ICMP T3C13 from any IP.  --packet_trace on nmap, or tcpdump -s0 -X -n, should tell you 
for sure though.

I can see a number of reasons for this:
      * All packets sent from 'target' are being nat'd to another IP address and are being missed by the tcpdump 
filter.
Not likely.

      * Nmap is using protocol specific methods to obtain these results and...
Definately not happening.

      * I dont know how to use tcpdump
Try something closer to:
tcpdump -n -X -s0

      * I dont know how to use nmap
More likely that you didn't understand what nmap was doing.  Now you do :).

So I say to you, WTF?
Yeah.. this way of udp scanning used to be useful... and still is marginally useful in internal networks with no 
filtering going on.

Hope this helps with your current situation.  Stay tuned though, as we expect to have the first public release of 
unicornscan around the end of the month.

Sincerely,

Robert

-- 
Robert E. Lee
CTO, Dyad Security, Inc.
W - http://www.dyadsecurity.com
E - robert () dyadsecurity com
M - (949) 394-2033


Current thread: