Nmap Development mailing list archives

allow_ipid_match causing replies to be ignored


From: David Fifield <david () bamsoftware com>
Date: Thu, 11 Jun 2009 16:54:12 -0600

Hello,

Stanley Bammel reported a case where altering the order of hosts on the
command line changed scan results. Specifically, a host was down when it
came first and up when it came second.

http://seclists.org/nmap-dev/2009/q2/0580.html

With Stanley's help I found the cause of the problem. It has to do with
a router sending back ICMP destination unreachable messages with a
mangled IP ID in the encapsulated packet, and a function called
allow_ipid_match.

When Nmap receives a packet it has to decide whether to use it or ignore
it. One of the tests is applies is the function allow_ipid_match, which is

static bool allow_ipid_match(u16 ipid_sent, u16 ipid_rcvd) {
  static int numvalid = 0;
  static int numbogus = 0;

  /* These systems seem to hose sent IPID */
#if defined(SOLARIS) || defined(SUNOS) || defined(IRIX) || defined(HPUX)
  return true;
#endif

  if (ipid_sent == ipid_rcvd) {
    numvalid++;
    return true;
  } else numbogus++;

  if (numbogus >= 2 && numvalid == 0)
    return true; /* Test does not seem to be working */
  /* This test is because sometimes a valid will come by luck */
  if (numbogus / (numbogus + numvalid) > .8)
    return true;
  return false;
}

I believe the intent of this test is to see whether the scanning host
modifies the IP IDs that Nmap sets, as Solaris, IRIX, and HP-UX do. It
is not meant to detect IP ID mangling in scanned hosts. The way it works
is, it compares every received packet's IP ID with the IP ID in a probe
that was sent. It it matches, it's valid; if not, it's bogus. If the
ratio of bogus to the total is over 80%, it assumes the IP IDs are being
changed by the OS and stops doing matching. If there was a mismatch, but
the ratio is 80% or less, it returns false and the packet is not given
further consideration.

In Stanley's scan, host1 was sending back ICMP destination unreachables
for itself (Nmap should mark it "up"), with IP IDs byte-swapped; i.e.,
bogus. Another router was sending dest-unreaches for host2, with correct
IP IDs. (Nmap should mark host2 "down".)

If host1 is probed first, everything works fine:
                                           numvalid  numbogus  ratio
nmap   -> host1  ping                             0         0     --
host1  -> nmap   host1 unreachable (bogus IP ID)  0         1   100%
                 ; Nmap marks host1 "up".
nmap   -> host2  ping                             0         1   100%
router -> nmap   host2 unreachable (valid IP ID)  1         1    50%
                 ; Nmap marks host2 "down".

But if host2 is probed first, its valid response upsets the ratio and
keeps it below, causing further bogus responses to be ignored.

                                           numvalid  numbogus  ratio
nmap   -> host2  ping                             0         0     --
router -> nmap   host2 unreachable (valid IP ID)  1         0     0%
                 ; Nmap marks host2 "down".
nmap   -> host1  ping                             1         0     0%
host1  -> nmap   host1 unreachable (bogus IP ID)  1         1    50%
                 ; Nmap ignores because ratio < 80%.
nmap   -> host1  ping (retransmit)                1         1    50%
host1  -> nmap   host1 unreachable (bogus IP ID)  1         2    67%
                 ; Also ignored.

So, that's the problem, what's the solution? allow_ipid_match should
default to accepting packets, otherwise it can be fooled when there's
not much data. It should reject a packet only when the ratio of bogus to
the total is low and a certain large number of packets have been
received, like 100.

On the other hand, maybe the whole allow_ipid_match concept is
misguided. Solaris and the other operating systems seem to get by fine
without it. Its purpose is to separate the wheat from the chaff, but
merely examining a piece of chaff makes it more likely to accept chaff
in the future; in other words the filter only works as long as there's
not much filtering to do. I'd like to get opinions on removing it and
see if I missed something in my analysis.

David Fifield

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


Current thread: