Nmap Development mailing list archives

Re: NSE Socket Operation on a non-socket


From: Joao Correa <joao () livewire com br>
Date: Sat, 18 Jul 2009 06:19:23 -0300

Hi Jah,

I've been trying to reproduce the error here without success.

On Sat, Jul 18, 2009 at 12:54 AM, jah<jah () zadkiel plus com> wrote:
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).

About your patch, I have a few considerations:
-               if not opts and opts.recv_before then
+               if opts and opts.recv_before then

I agree that the line is incorrect, but I believe that the correct would be:

if not opts or (opts and not opts.recv_before) then

because what we are trying to check here is if there is no data
payload or recv_before option set to emit the debug message. Using
tryssl without any of these conditions makes impossible for the script
to check if a tcp connection is really working, because it depends on
exchanging data to discover if that socket requires SSL or not.

About the bug, if any of the receive() functions did not work fine
(that is what happens if you open a tcp connection on a socket that
requires SSL) there's something wrong with our socket and maybe TCP is
not the correct protocol option. That's why the script attempts to
reconnect using SSL.

The big issue here is that, if you try SSL on a socket that does not
use SSL, you get the error message instantly. But if you try TCP on a
socket that uses SSL, it will connect successfully, and you won't
notice it unless that you exchange some data with the server.

It seems that the ms service at port 445 does not send any data on
connect (data that should be the service banner), what makes the first
receive fail and makes the script test a second option (which is ssl).
Normally this second attempt would not represent a considerable
overhead, since while trying to set a SSL connection on a non-ssl
socket would lead to a connection close instantly. For some reason (as
you noticed, and I could check here) specially this service does not
close the connection when a client tries to open a connection with SSL
support. I've tested some different ms services here, and all of them
closed my SSL connection attempts.

I'm not an expert on SMB, but maybe it supports SSL connections, and
that's why the service is not closing our connection. If it is true,
than I think that it is desirable that the scripts make two attempts
in case of one of them not answer as we expect.

About returning the socket instead of nil, one problem is that, if we
do not test the second option, on a situation like having telnet over
ssl (for example) the script would try a TCP connection, it would not
receive any data but the incorrect socket would remain open. That's
why it should retry with SSL.

I don't think that this bug can lead to errors, but in some cases
(like the one of the port 445) it can represent some lose of
performance. In this specific case, using tryssl may lead to some lose
of performance, but not using it can lead to false negatives in a much
bigger number of situations.

I'll work on a fix for this situation, but I can't think about a
solution now. It would be great if someone could post some ideas.

Another strange behavior I could notice is that when I try SSL
connection first on 445, the second connection, which is TCP, receives
a fast connection close from the server before it reaches its timeout.
When it happens, nsock displays a message about invalid socket.
Perhaps the problem is a similar situation, where your script is
running and the socket is closed unexpectedly.

I'm not sure I was clear enough, but if you need a better explanation
about anything, don't mind asking.

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



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


Thanks,
Joao

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


Current thread: