Nmap Development mailing list archives

Re: [NSE] rpc.lua fix for binding to reserved ports (tcp)


From: Daniel Miller <bonsaiviking () gmail com>
Date: Thu, 20 Sep 2012 21:44:24 -0500

On Thu, Sep 20, 2012 at 8:16 PM, David Fifield <david () bamsoftware com> wrote:
On Thu, Sep 20, 2012 at 09:39:41AM -0500, Daniel Miller wrote:
This issue has come up previously (), but we missed a situation that
I've run into: When a host stops responding to probes (possibly due
to an adaptive firewall detecting the portscan phase),

Also when a host replies with a SYN/ACK for ports that aren't really
open. That's what we saw in
        http://seclists.org/nmap-dev/2012/q3/864
        http://seclists.org/nmap-dev/2012/q3/872
You can simulate the situation Daniel is describing with the syn.py
script from http://seclists.org/nmap-dev/2012/q3/955 and
        ./nmap --script=rpc-grind localhost -p 1000 --packet-trace

rpc-grind and possibly other scripts will take a long time timing out
with every source port between 600 and 1024, since that portion of
rpc.lua doesn't check the type of failure (timeout vs. port in use,
specifically). Here's a patch to add that check:

--- a/nselib/rpc.lua
+++ b/nselib/rpc.lua
@@ -171,9 +171,14 @@ Comm = {
             status, err = socket:bind(nil, resvport)
             if status then
               status, err = socket:connect(host, port)
-              if status then break end
+              if status or err == "TIMEOUT" then break end
             end
           end
+          if not status and err ~= "TIMEOUT" then
+            stdnse.print_debug("%s reserved port bind failed,
trying ephemeral port", self.program)
+            socket = nmap.new_socket()
+            status, err = socket:connect(host, port)
+          end
         else
           status, err = socket:connect(host, port)
         end

The only thing I'm not sure about is whether to explicitly check for
TIMEOUT the first time, or simply check for err ~= "ERROR", which is
what ought to happen with EADDRINUSE. Thoughts?

Check for "TIMEOUT". That's the situation that will take a lot of time
that we're most concerned about. (Iterating 400 ports still takes
non-negligible time even when the connections fail quickly, which is
another reason I don't think we should do this reserved port search.)
Don't bother trying an ephemeral port if the reserved ports fail; it's
not worth the additional complexity and I think we'll end up rewriting
this code anyway. Make sure that the socket is closed even if there is a
timeout to avoid the problem that was worked around in r29840.

David Fifield

Ok, this should be addressed in r29841. Commit message has the
details, but here are 3 issues fixed in 8 lines:

1. r29840 moved nmap.new_socket() calls out of the code path for
non-privileged execution. Added them in an "else".

2. Check for TIMEOUT, as in my first patch in this thread. Don't try
ephemeral port if reserved port fails.

3. Try 10 random reserved ports instead of 424 sequential ones.

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


Current thread: