Nmap Development mailing list archives

Re: [NSE] False positive in jdwp-version.nse


From: Tom Sellers <nmap () fadedcode net>
Date: Sun, 02 Oct 2011 11:50:24 -0500

On 10/2/2011 10:42 AM, Tom Sellers wrote:
All,

      A user in the Freenode #nmap IRC channel reported false positives with the jdwp-version.nse (ref a)
script.  After looking at the code and some testing it looks like there may be a logic error that is causing
the false positives.  It seems to occur when the probed service returns data but is not otherwise successfully
fingerprinted.

The simplest reproduction scenario involves a service that Nmap cannot fingerprint and the following command line:

nmap -sV -p <port> <ip_address>

In my tests I was scanning a HTTP service that returned very little data.


I think the problem lies with the following section of code:

      -- match jdwp m|JDWP-Handshake| p/$1/ v/$3/ i/$2\n$4/
1:      local match = {string.match(result, 
"^JDWP%-Handshake%z%z..%z%z%z\1\128%z%z%z%z..([^%z\n]*)\n([^%z]*)%z%z..%z%z..%z%z..([0-9._]+)%z%z..([^%z]*)")}
2:      if match == nil then
                -- if we have one \128 (reply marker), it is at least not echo because the request did not contain 
\128
                if (string.match(result,"^JDWP%-Handshake%z.*\128") ~= nil) then
                    port.version.name="jdwp"
                    port.version.product="unknown"
                    nmap.set_port_version(host, port, "hardmatched")
                end
                return
        end
3:      port.version.name="jdwp"
        port.version.product = match[1]
        port.version.version = match[3]
        -- port.version.extrainfo = match[2] .. "\n" .. match[4]
        nmap.set_port_version(host, port, "hardmatched")
        return


The output of the first string.match (1:) appears to be a table of nils when parsing the following
result data:   HTTP/1.1 404 Not Found

The check for match == nil (2:) returns false, skipping the block of code that follows it.  Execution
resumes at 3: which then goes on to flag to the port as hardmatched 'jdwp'.  This result is incorrect.

The RegEx captures at 1: are not used as far as I can tell. Based on my understanding of how
string.match works (ref b) it may be better to remove the captures and just let string.match return
the original value of the result variable if a match is found.

Unfortunately I do not have a jdwp sample to test with and I am not familiar with the protocol so
I cannot test this logic change reliably.

If I am correct then this problem needs to be addressed as soon as possible as it will prevent
fingerprints for unidentified services being generated because they will all be flagged as hardmatched
jdwp.

Thanks much,

Tom


Reference:
a.  jdwp-version.nse : http://nmap.org/svn/scripts/jdwp-version.nse
b.  LUA.org 5.1 reference manual - string.match : http://www.lua.org/manual/5.1/manual.html#pdf-string.match

Further testing shows that there is an error in my assumptions above.  It looks like this is not
triggered against all unidentified services, but in the situation where the service detection NULL probe
causes the remote host to reset the connection ( READ ERROR [Connection reset by peer (104)] ) which
seems to end probe based detection.  The scripting portion of version detection then picks up and is
able to trigger a response by the targeted host.

This means that while this is still a problem, the impact should be fairly small.

I have some hosts that can be used for testing.  I will provide them upon request if someone needs them.

Sorry for the bad data.

Tom


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


Current thread: