Nmap Development mailing list archives

--defeat-icmp-ratelimit option for UDP scan


From: Sergey Khegay <g.sergeykhegay () gmail com>
Date: Tue, 29 Mar 2016 19:33:19 -0400

Hello!

I am trying to implement this Issue #216
<https://github.com/nmap/nmap/issues/216> on GitHub.

As discussed here: http://seclists.org/nmap-dev/2014/q4/183

More UDP payloads will definitely improve scan times against open
services, but the real time-killer is the closed ports. If a system is
using a firewall to drop probes, then Nmap will detect those drops
pretty quickly, especially if the few open services are quick to
respond (giving an accurate RTT and packet loss estimate). But if the
host is rate-limiting the ICMP responses, then Nmap knows it ought to
wait for them, and so it just keeps slowing down its probes until it
matches the (slow) rate limit that the target is using for responses.

For TCP scans, most hosts will not rate-limit RST packets (closed port
responses), but some do. In this case, we have the
--defeate-rst-ratelimit option which abandons accuracy in
distinguishing closed ports from filtered ones. This allows it to
focus only on open ports (which respond with SYN/ACK). We don't do the
same for UDP because a port may be open even if it doesn't respond at
all (because we haven't sent the proper payload).

I can conceive of a --defeat-icmp-ratelimit option that would treat
open|filtered UDP ports as closed, and only report the definitely-open
ones as up. This would mean a greater loss of accuracy, since some
open services would be missed. This could be partially remedied by
expanding the nmap-payloads file to include the UDP probes from the
nmap-service-probes file. As you saw in your output, service scan will
often change the status of a port from open|filtered to open because
of a received response.


 My first approach was to:
1. add *--defeat-icmp-ratelimit* option for UDP scan only
2. modify *ultrascan_port_probe_update(...) *in *scan_engine.cc* analogous
to --defeat-rst-ratelimit

   /* Do not slow down if

     1)  we are in --defeat-icmp-ratelimit mode
     2)  the new state is open|filtered
     3)  this is a UDP scan */
  if (rcvdtime != NULL
      && o.defeat_icmp_ratelimit && newstate == PORT_OPENFILTERED
      && USI->udp_scan) {
    if (probe->tryno > 0)
      adjust_timing = false;
    adjust_ping = false;
  }


I figured out that this is flawed, as *ultrascan_port_probe_update(...) *is
never called with
*newstate == PORT_OPENFILTERED *during UDP scan*. *Instead the default port
state is
initialized as open|filtered. When nmap sends a probe and does not get a
response it just
mark the probe as timeout'ed, stages the probe to retransmit (if other
parameters and
timers allow) and does not change the port's state, which is logical. So
the port's state is
changed only when nmap gets any kind of response from server.

As I understand, the option *--defeat-icmp-ratelimit* should let nmap send
only one probe
per a port. If there is no response, then the port is treated as
open|filtered and we do not
attempt any retransmissions for that port to save time. Would it be
reasonable to delete
all probes that are marked as timeout'ed if *--defeat-icmp-ratelimit*
enabled, in other words
just prevent any retransmissions?

Is it a good approach overall? We already lose accuracy since some services
might
be missed because we send wrong payload. Furthermore, UDP does not guarantee
delivery, so response might just be dropped on the way back to our machine
due to
congestion (and nmap would treat corresponding port as open|filtered).

Any comments and clarifications are appreciated.

Best regards,
Sergey.


P.S. I am a Google Summer of Code 2016 Applicant.
_______________________________________________
Sent through the dev mailing list
https://nmap.org/mailman/listinfo/dev
Archived at http://seclists.org/nmap-dev/

Current thread: