Nmap Development mailing list archives

Fixed: intermittent large scan delays caused by bench retransmits


From: David Fifield <david () bamsoftware com>
Date: Fri, 19 Sep 2008 11:13:27 -0600

Hi,

I had observed, when scanning a particular Mac OS X host, that perhaps
one time in ten the scan would come to a near-standstill, with the scan
delay rapidly growing from 0 to 1000 ms.

Increased max_successful_tryno for 192.168.0.190 to 1 (packet drop)
Increased max_successful_tryno for 192.168.0.190 to 2 (packet drop)
Increasing send delay for 192.168.0.190 from 0 to 5 due to 216 out of 718 dropped probes since last increase.
Increased max_successful_tryno for 192.168.0.190 to 3 (packet drop)
Increasing send delay for 192.168.0.190 from 5 to 10 due to 92 out of 305 dropped probes since last increase.
Increasing send delay for 192.168.0.190 from 10 to 20 due to 11 out of 11 dropped probes since last increase.
Increasing send delay for 192.168.0.190 from 20 to 40 due to 11 out of 11 dropped probes since last increase.
Increasing send delay for 192.168.0.190 from 40 to 80 due to 11 out of 11 dropped probes since last increase.
Increasing send delay for 192.168.0.190 from 80 to 160 due to 11 out of 11 dropped probes since last increase.
Increasing send delay for 192.168.0.190 from 160 to 320 due to 11 out of 11 dropped probes since last increase.
...

I found out the problem was caused by a bug in Nmap, and I fixed it.

Understanding the bug requires a bit of background information. When a
probe reaches the current maximum retry count, it is moved to a holding
area called the bench, where it stays unless the retry count happens to
increase. When moved to the bench probes are compressed from UltraProbe
objects to smaller probespec structures. If the maximum retry count
increases, the probespecs are moved to the retry stack, from whence they
are converted back into UltraProbes and retransmitted.

When an UltraProbe is converted to a probespec some information is lost.
In this case the critical information is the time the probe was sent.
When a probe is retransmitted, it stores in its prevSent member the time
the previous probe was transmitted, which is used as part of the scan
delay logic. Because the send time is lost in the probespec conversion,
probes retransmitted from the bench have a prevSent timeval of { 0, 0 },
that is, Thu Jan  1 00:00:00 1970. A calculation with this value caused
an integer overflow and made a test true that should have been false.

I fixed it by using TIMEVAL_AFTER to compare times, rather than
TIMEVAL_SUBTRACT which is susceptible to integer overflows. The prevSent
of probes retransmitted from the bench is still { 0, 0 }. It would have
been more correct to find a way to store a probe's send time with it on
the bench, but I didn't think that worth this one little test, the only
place prevSent is used. The test should always be false for these
retransmitted probes anyway.

I hit this when scanning an unfirewalled OS X machine because OS X
rate-limits RSTs to 250 per second. So a lot of probes get dropped at
the beginning and end up on the bench. The reason the later increases
were due to "11 out of 11" is because Nmap requires more than 10 dropped
probes between scan delay increases. This shows that every received
probe was being counted as a drop.

David Fifield

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


Current thread: