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:
- allow_ipid_match causing replies to be ignored David Fifield (Jun 11)
- Re: allow_ipid_match causing replies to be ignored Fyodor (Jun 12)