Nmap Development mailing list archives

NSE Socket Operation on a non-socket


From: jah <jah () zadkiel plus com>
Date: Sat, 18 Jul 2009 04:54:41 +0100

Hi folks,

I've been struggling with an error which I can reliably reproduce with
the following (r14408) nmap command against a windows machine with tcp
ports 445 and 3389 open:

nmap -sSV -p 445,3389 -PN -n --script banner,smb-enum-shares -d <target>

The error looks like this:

NSOCK (-1950392.4020s) nsock_loop error 10038: An operation was
attempted on something that is not a socket.
NSE: Script Engine Scan Aborted.
An error was thrown by the engine: a fatal error occurred in nsock_loop
stack traceback:
        [C]: ?
        [C]: in function 'nsock_loop'
        C:\Program Files\Nmap\nse_main.lua:605: in function 'run'
        C:\Program Files\Nmap\nse_main.lua:734: in function <C:\Program
Files\Nmap\nse_main.lua:693>
        [C]: ?

I started off doing a --script all against this unfirewalled XP SP2
machine and after about 30 scans had managed to reduce the number of
ports and scripts to the above combination.
I've spent ages fiddling and trying to work-out what was happening and
came to the conclusion that the error happened when banner.nse asks
comm.lua to do an SSL connection to port 3389 (microsoft-rdp aka
Microsoft Terminal Service).  I can't reproduce the error if I try an
SSL connection in the absence of any other script activity - it's only
happening with the aforementioned command.

There's an bug in comm.lua opencon() which causes the tryssl() to
attempt an SSL connection even after a successful TCP connection, but
that isn't really the issue - something strange seems to be going on
(and I've not fully explored the impact of my fix for the bug which is
to ensure that opencon() always returns the socket ref except when the
connection fails - I've attached a patch anyway).

The error seems to happen after banner.nse finishes against port 3389
(after the ssl connect() times-out), after the thread ends and sometime
during an attempt to close the two sockets opened by comm.opencom() -
but, importantly, never if I run banner against those ports without
running smb-enum-shares.  Odd huh?

I've attached a gzipped output with --script-trace and -d3 in case
anyone wants to take a look.  I'll revisit again later after I've slept
(it's nearly daylight here).

Night.

jah

--- comm.lua.orig       2009-07-18 04:22:15.984375000 +0100
+++ comm.lua    2009-07-18 04:21:59.015625000 +0100
@@ -208,7 +208,10 @@
        end
 
        local status = sd:connect(ip, port, protocol)
-       if not status then return nil, nil, nil end
+       if not status then
+               sd:close()
+               return nil, nil, nil
+       end
 
        -- check for request_timeout or timeout option
 
@@ -220,19 +223,19 @@
                sd:set_timeout(8000)
        end
 
-    local response, early_resp;
+       local response, early_resp;
        if opts and opts.recv_before then status, early_resp = sd:receive() end
        if #data > 0 then
                sd:send(data)
                status, response = sd:receive()
        else
-               if not opts and opts.recv_before then
+               if opts and opts.recv_before then
                        nsedebug.print_debug("Using comm.tryssl without first data payload and recv_first." .. 
                                             "\nImpossible to test the connection for the correct protocol!")
                end
                response = early_resp
        end
-       if not status then return nil, response, early_resp end
+       if not status then return sd, response, early_resp end
        return sd, response, early_resp
 end
 
@@ -257,8 +260,8 @@
 -- of the first receive (before sending data)
 function tryssl(host, port, data, opts)
        local opt1, opt2 = bestoption(port)
-       if type(port) == 'table' then port = port.number end    
-       if type(host) == 'table' then host = host.ip end
+       local port = type(port) == 'table' and port.number or port
+       local host = type(host) == 'table' and host.ip     or host
        local best = opt1
        local sd, response, early_resp = opencon(host, port, opt1, data, opts)
        if not sd then

Attachment: out_10038.gz
Description:


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

Current thread: