Nmap Development mailing list archives

[PATCH] NSE "Comm" library + 18 shortened scripts


From: Kris Katterjohn <katterjohn () gmail com>
Date: Sat, 12 Apr 2008 21:47:12 -0500

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hey everyone,

I've attached a new NSE "Comm" library.  Standing for something like
"COMMon COMMunications," this NSElib adds two functions: get_banner()
and exchange().

Obviously the specialized http library and any other protocol-specific
libraries created will be more useful in some circumstances, but as
you'll see below, this library consolidates code in a lot of separate
scripts into these functions.  Maybe any other libraries could use this
one as a back-end.

The top comment in comm.lua goes into some more detail about the usage,
but here's the gist:

comm.get_banner(host, port, [opts])
comm.exchange(host, port, data, [opts])

get_banner() does just what it sounds like it does: connects to the
host, reads whatever it gives us, and then returns it.

connect -> read -> close -> return

exchange() connects to the host, sends the requested data, reads
whatever it gives us, and then returns it.

connect -> send -> read -> close -> return

The functions are designed to be used with exception handling via
nmap.new_try().

An optional table can be passed to these functions, allowing for
additional options.  The table can have the following keys:

bytes - The minimum amount of bytes to receive
lines - The minimum amount of lines to receive
proto - Protocol to connect() with; defaults to "tcp"
timeout - Socket timeout


A whole lot of scripts did the same basic thing: open a socket, possibly
set a timeout, possibly send some data, and then (possibly looping to)
read all of the data.  Now all of that can be done with a single
function call.

I've attached a patch updating 18 scripts to use this library.  This
stripped some of them down to almost nothing.

I haven't been able to test all of the scripts, so I need somebody else
to verify that they work correctly.  Here's a list so far:

Tested
- ------
HTTPtrace
nbstat
ripeQuery
rpcinfo
echoTest
chargenTest
daytimeTest
dns-test-open-recursion
showSMTPVersion
finger

Untested
- --------
MySQLinfo
HTTP_open_proxy
PPTPversion
kibuvDetection
ircZombieTest
iax2Detect
skype_v2-version
mswindowShell


Of course if you could also test the ones I've already done, that'd be
great.  Even just giving a quick look-over the library or patch for any
possible mistakes would be helpful as well.

So:

o Is the interface good?  I think "get_banner" and "exchange" are simple
and concise, but any suggestions for better names are welcome.

o Are there any other options that should be added to the table?

Thanks,
Kris Katterjohn

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iQIVAwUBSAFz7P9K37xXYl36AQKecw/+NHmP47qZ7SM1Nodu8XFWquFnArPPAegj
s69Ea36vBATn3IoDI/qpZV6S+WSc4MYAfiQnU7Tv9sKTPzzrcO+SUjDRi6u6JGDv
V4JM9ToB9JdXWNOFfP+9OzttRFwgQRav//xCkNOYXLjztUn4Nd+KKovDzKGZQlqb
mK7BpujOiyu7kIZKQI6N1hCShv6IqwJAAZXBLmXvBJzeJWDL887luNeUztEt2Eqs
kTEU3Aoey71KmGxXb5pwJQH5R5kPio9EyhFYNCGNM3blCaHAha1IOHbDTicHf4cV
jiLFMTu5/cCoV8SxbqsXVlQBzMeXVW441Ak3tP1/IR/tNa5OdYmCSiS3EsLIDg8k
kBqOdfInDiPNDqBcN671tbCr8czkYMYbOciCh2X5pYdd4I9ixaHJjlMKzYjAxs4N
FEAy4X+gkxVjcOnqCongtFl0WYIylxMsNxcJf5LUO7B64RANXzyAL/ITyicMCRCw
9b5ppcMLGYzcnxk72DOweUYjnL8VfTH6CtLlCQUBo+LYTTlfHV3vP/VmN1jdIQ2E
WWU+uHTvEci2uUCOITU+qGlsDej9sPjlCXqoDpj9RCij3cM1p6ZzQyamlRBK6cOl
nOtEuMrsoSND0a9k5eAdUUqTS1CFKUOT+rdv4+IL0A82D9bA93oI6gnE+LQeuOYS
c6pTHHRzTuw=
=Uy5U
-----END PGP SIGNATURE-----
-- Kris Katterjohn 04/2008

module(..., package.seeall)

------
--
-- The Functions:
--
--   get_banner(host, port, [opts])
--   exchange(host, port, data, [opts])
--
-- get_banner() does just what it sounds like it does: connects to the
-- host, reads whatever it gives us, and then returns it.
--
-- exchange() connects to the host, sends the requested data, reads
-- whatever it gives us, and then returns it.
--
-- Both of these functions return multiple values so that they can be
-- used with exception handling via nmap.new_try().  The second value
-- they return is either the response from the host, or the error message
-- from one of the previous calls (connect, send, receive*).
--
-- These functions can be passed a table of options with the following keys:
--
--   bytes: Specifies the minimum amount of bytes to be read from the host
--   lines: Specifies the minimum amount of lines to be read from the host
--   proto: Specifies the protocol to use.  Defaults to "tcp"
--   timeout: Sets the socket's timeout with nmap.set_timeout()
--
-- If neither lines nor bytes are specified, the calls read as many lines
-- as possible.  If only bytes if specified, then it only tries to read that
-- many bytes.  Likewise, it only lines if specified, then it only tries to
-- read that many lines.  If they're both specified, the lines value is used.
--
------

-- Makes sure that opts exists and the default proto is there
local initopts = function(opts)
        if not opts then
                opts = {}
        end

        if not opts.proto then
                opts.proto = "tcp"
        end

        return opts
end

-- Sets up the socket and connects to host:port
local setup_connect = function(host, port, opts)
        if type(host) ~= "table" then
                host = {ip = host}
        end

        local target = host.targetname or host.ip or host.name

        if type(port) ~= "table" then
                port = {number = port}
        end

        local sock = nmap.new_socket()

        if opts.timeout then
                sock:set_timeout(opts.timeout)
        end

        local status, err = sock:connect(target, port.number, opts.proto)

        if not status then
                return status, err
        end

        return true, sock
end

local read = function(sock, opts)
        if opts.lines then
                return sock:receive_lines(opts.lines)
        elseif opts.bytes then
                return sock:receive_bytes(opts.bytes)
        end

        local response = ""

        while true do
                local status, line = sock:receive_lines(1)

                if not status then
                        break
                end

                response = response .. line
        end

        return true, response
end

get_banner = function(host, port, opts)
        opts = initopts(opts)

        local status, sock = setup_connect(host, port, opts)
        local ret

        if not status then
                -- sock is an error message in this case
                return status, sock
        end

        status, ret = read(sock, opts)

        sock:close()

        return status, ret
end

exchange = function(host, port, data, opts)
        opts = initopts(opts)

        local status, sock = setup_connect(host, port, opts)
        local ret

        if not status then
                -- sock is an error message in this case
                return status, sock
        end

        status, ret = sock:send(data)

        if not status then
                sock:close()
                return status, ret
        end

        status, ret = read(sock, opts)

        sock:close()

        return status, ret
end

Index: scripts/daytimeTest.nse
===================================================================
--- scripts/daytimeTest.nse     (revision 7153)
+++ scripts/daytimeTest.nse     (working copy)
@@ -8,16 +8,13 @@
 
 categories = {"demo"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.port_or_service(13, "daytime", "udp")
 
 action = function(host, port)
-       local socket = nmap.new_socket()
-       socket:connect(host.ip, port.number, "udp")
-       socket:send("dummy")
-       local status, result = socket:receive_lines(1);
-       socket:close()
+       local status, result = comm.exchange(host, port, "dummy", {lines=1, proto="udp"})
 
        if (result ~= nil) then
                return "Daytime: " .. result
Index: scripts/HTTPtrace.nse
===================================================================
--- scripts/HTTPtrace.nse       (revision 7153)
+++ scripts/HTTPtrace.nse       (working copy)
@@ -18,6 +18,7 @@
 
 categories = {"discovery"}
 
+require "comm"
 require "shortport"
 require "stdnse"
 
@@ -76,31 +77,14 @@
 portrule = shortport.port_or_service({80, 8080}, "http")
 
 action = function(host, port)
-       local cmd, response
-       local socket
+       local cmd = "TRACE / HTTP/1.0\r\n\r\n"
 
-       socket = nmap.new_socket()
+       local status, response = comm.exchange(host, port, cmd, {timeout=5000})
 
-       socket:connect(host.ip, port.number)
-
-       cmd = "TRACE / HTTP/1.0\r\n\r\n"
-
-       socket:send(cmd)
-
-       response = ""
-
-       while true do
-               local status, lines = socket:receive_lines(1)
-
-               if not status then
-                       break
-               end
-
-               response = response .. lines
+       if not status then
+               return
        end
 
-       socket:close()
-
        return validate(response, cmd)
 end
 
Index: scripts/dns-test-open-recursion.nse
===================================================================
--- scripts/dns-test-open-recursion.nse (revision 7153)
+++ scripts/dns-test-open-recursion.nse (working copy)
@@ -9,6 +9,7 @@
 categories = {"intrusive"}
 
 require "bit"
+require "comm"
 require "shortport"
 
 portrule = shortport.portnumber(53, "udp")
@@ -18,12 +19,11 @@
     -- generate dns query, Transaction-ID 0xdead, isc.sans.org (type A, class IN)
        local request = string.char(0xde, 0xad, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03) ..  
"isc" .. string.char(0x04) .. "sans" .. string.char(0x03) ..  "org" .. string.char(0x00, 0x00, 0x01, 0x00, 0x01)
 
-       local socket = nmap.new_socket()
-       socket:connect(host.ip, port.number, "udp")
-       socket:send(request)
+       local status, result = comm.exchange(host, port, request, {proto="udp"})
 
-       local status, result = socket:receive();
-       socket:close()
+       if not status or result == "" then
+               return
+       end
 
     -- parse response for dns flags
     if (bit.band(string.byte(result,3), 0x80) == 0x80
Index: scripts/chargenTest.nse
===================================================================
--- scripts/chargenTest.nse     (revision 7153)
+++ scripts/chargenTest.nse     (working copy)
@@ -8,18 +8,15 @@
 
 categories = {"demo"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.port_or_service(19, "chargen", "udp")
 
 action = function(host, port)
-       local socket = nmap.new_socket()
-       socket:connect(host.ip, port.number, "udp")
-       socket:send("dummy")
-       local status, result = socket:receive_lines(1);
-       socket:close()
+       local status, result = comm.exchange(host, port, "dummy", {lines=1, proto="udp"})
 
-       if (result ~= nil) then
+       if (result ~= "") then
                return "Chargen: success"
        else
                return "Chargen: something went wrong"
Index: scripts/echoTest.nse
===================================================================
--- scripts/echoTest.nse        (revision 7153)
+++ scripts/echoTest.nse        (working copy)
@@ -9,18 +9,16 @@
 
 categories = {"demo"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.port_or_service(7, "echo", "udp")
 
 action = function(host, port)
        local echostr = "hello there"
-       local socket = nmap.new_socket()
-       socket:connect(host.ip, port.number, "udp")
-       socket:send(echostr)
-       local status, result = socket:receive_lines(1);
-       socket:close()
 
+       local status, result = comm.exchange(host, port, echostr, {lines=1, proto="udp"})
+
        if (result == echostr) then
                return "UDP Echo: correct response"
        end
Index: scripts/kibuvDetection.nse
===================================================================
--- scripts/kibuvDetection.nse  (revision 7153)
+++ scripts/kibuvDetection.nse  (working copy)
@@ -16,16 +16,14 @@
 
 categories = {"malware"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.port_or_service({7955, 14920, 42260}, "ftp")
 
 action = function(host, port)
-       local socket = nmap.new_socket()
+       local status, s = comm.get_banner(host, port, {lines=1})
 
-       socket:connect(host.ip, port.number)
-       local status, s = socket:receive_lines(1)
-
        if      string.match(s, "220 StnyFtpd 0wns j0")
                or
                string.match(s, "220 fuckFtpd 0wns j0")
Index: scripts/MySQLinfo.nse
===================================================================
--- scripts/MySQLinfo.nse       (revision 7153)
+++ scripts/MySQLinfo.nse       (working copy)
@@ -18,6 +18,7 @@
 categories = { "discovery", "safe" }
 
 require 'bit'
+require 'comm'
 
 -- Grabs NUL-terminated string
 local getstring = function(orig)
@@ -114,28 +115,14 @@
 end
 
 action = function(host, port)
-       local sock
-       local response = ""
        local output = ""
 
-       sock = nmap.new_socket()
+       local status, response = comm.get_banner(host, ip, {timeout=5000})
 
-       sock:set_timeout(5000)
-
-       sock:connect(host.ip, port.number)
-
-       while true do
-               local status, line = sock:receive_lines(1)
-
-               if not status then
-                       break
-               end
-
-               response = response .. line
+       if not status then
+               return
        end
 
-       sock:close()
-
        local length = ntoh3(response:sub(1, 3))
 
        if length ~= response:len() - 4 then
Index: scripts/skype_v2-version.nse
===================================================================
--- scripts/skype_v2-version.nse        (revision 7153)
+++ scripts/skype_v2-version.nse        (working copy)
@@ -3,6 +3,7 @@
 author = "Brandon Enright <bmenrigh () ucsd edu>" 
 license = "Same as Nmap--See http://nmap.org/book/man-legal.html";
 categories = {"version"}
+require "comm"
 
 portrule = function(host, port)
        if      (port.number == 80 or
@@ -22,42 +23,25 @@
 end
 
 action = function(host, port)
+       local status, result = comm.exchange(host, port, "GET / HTTP/1.0\r\n\r\n", {bytes=26, proto=port.protocol})
 
-       local socket = nmap.new_socket()
-       local result;
-       local status = true
-
-       socket:connect(host.ip, port.number, port.protocol)
-               socket:send("GET / HTTP/1.0\r\n\r\n")
-
-       status, result = socket:receive_bytes(26);
-
        if (not status) then
-               socket:close()
                return
        end
 
        if (result ~= "HTTP/1.0 404 Not Found\r\n\r\n") then
-               socket:close()
                return
        end
        
-       socket:close();
-       
        -- So far so good, now see if we get random data for another request
 
-       socket:connect(host.ip, port.number, port.protocol)
-               socket:send("random data\r\n\r\n")
+       status, result = comm.exchange(host, port, "random data\r\n\r\n", {bytes=15, proto=port.protocol})
 
-       status, result = socket:receive_bytes(15);
-
        if (not status) then
-               socket:close()
                return
        end
 
        if string.match(result, "[^%s!-~].*[^%s!-~].*[^%s!-~].*[^%s!-~]") then
-               socket:close()
                port.version.name = "skype2"
                port.version.confidence = 10
                port.version.fingerprint = nil
@@ -66,7 +50,5 @@
                -- return "Skype v2 server detected"
        end
 
-       socket:close();
-
        return
 end
Index: scripts/showSMTPVersion.nse
===================================================================
--- scripts/showSMTPVersion.nse (revision 7153)
+++ scripts/showSMTPVersion.nse (working copy)
@@ -8,20 +8,14 @@
 
 categories = {"demo"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.port_or_service(25, "smtp")
 
 action = function(host, port)
-       
-       local client = nmap.new_socket()
+       local status, result = comm.get_banner(host, port, {lines=1})
 
-       client:connect(host.ip, port.number)
-       
-       local status, result = client:receive_lines(1);
-
-       client:close()  
-
        if result ~= nil then
                result = string.gsub(result, "\n", "")
        end
Index: scripts/nbstat.nse
===================================================================
--- scripts/nbstat.nse  (revision 7153)
+++ scripts/nbstat.nse  (working copy)
@@ -11,6 +11,8 @@
 
 categories = {"discovery", "safe"}
 
+require "comm"
+
 -- I have excluded the port function param because it doesn't make much sense
 -- for a hostrule.  It works without warning.  The NSE documentation is
 -- not explicit enough in this regard.  
@@ -49,46 +51,22 @@
 -- Again, I have excluded the port param.  Is this okay on a hostrule?
 action = function(host)
        
-       local socket = nmap.new_socket()
-
-       socket:set_timeout(5000)
-
-       local result
-       local status = true
-
-       status, result = socket:connect(host.ip, 137, "udp")
-
-       if (not status) then
-               -- Can a UDP connect ever fail?
-               return
-       end
-
        -- This is the UDP NetBIOS request packet.  I didn't feel like
        -- actually generating a new one each time so this has been shamelessly
        -- copied from a packet dump of nbtscan.
        -- See http://www.unixwiz.net/tools/nbtscan.html for code.
        -- The magic number in this code is \003\097.
-       status, result = socket:send(
+       local data =
                "\003\097\000\016\000\001\000\000" ..
                "\000\000\000\000\032\067\075\065" ..
                "\065\065\065\065\065\065\065\065" ..
                "\065\065\065\065\065\065\065\065" ..
                "\065\065\065\065\065\065\065\065" ..
                "\065\065\065\065\065\000\000\033" ..
-               "\000\001")
+               "\000\001"
 
-       if (not status) then
-               -- Can the first UDP send ever fail?
-               return
-       end
+       local status, result = comm.exchange(host, 137, data, {bytes=1, proto="udp", timeout=5000})
 
-       -- this receive_bytes will consume all the input available
-       -- with a minimum of 1 byte.
-       status, result = socket:receive_bytes(1);
-
-       -- We don't need this socket anymore
-       socket:close()
-
        if (not status) then
                return
        end
Index: scripts/iax2Detect.nse
===================================================================
--- scripts/iax2Detect.nse      (revision 7153)
+++ scripts/iax2Detect.nse      (working copy)
@@ -9,43 +9,36 @@
 
 categories = {"version"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.portnumber(4569, "udp")
 
 action = function(host, port)
-       local soc = nmap.new_socket()
-       soc:set_timeout(10000)
-       local conn = soc:connect(host.ip, port.number, port.protocol)
+       -- see http://www.cornfed.com/iax.pdf for all options.
+       local poke = string.char(0x80, 0x00, 0x00, 0x00)
+       poke = poke .. string.char(0x00, 0x00, 0x00, 0x00)  
+       poke = poke .. string.char(0x00, 0x00, 0x06, 0x1e)
 
-       if (conn) then
-               -- see http://www.cornfed.com/iax.pdf for all options.
-               local poke = string.char(0x80, 0x00, 0x00, 0x00)
-               poke = poke .. string.char(0x00, 0x00, 0x00, 0x00)  
-               poke = poke .. string.char(0x00, 0x00, 0x06, 0x1e)
-               soc:send(poke)
+       local status, recv = comm.exchange(host, port, poke, {proto=port.protocol,timeout=10000})
 
-               local status, recv
-               status, recv = soc:receive_bytes(1)
-        
-               if (string.len(recv)) == 12 then
-                       local byte11 = string.format("%02X", string.byte(recv, 11))
-                       local byte12 = string.format("%02X", string.byte(recv, 12))
+       if not status then
+               return
+       end
 
-                       -- byte11 must be \x06 IAX Control Frame
-                       -- and byte12 must be \x03 or \x04
-                       if ((byte11 == "06") and
-                          (byte12 == ("03" or "04"))) 
-                       then
-                               nmap.set_port_state(host, port, "open")
-                           port.version.name = "iax2"
-                           nmap.set_port_version(host, port, "hardmatched")
-                       end
-       
+       if (string.len(recv)) == 12 then
+               local byte11 = string.format("%02X", string.byte(recv, 11))
+               local byte12 = string.format("%02X", string.byte(recv, 12))
+
+               -- byte11 must be \x06 IAX Control Frame
+               -- and byte12 must be \x03 or \x04
+               if ((byte11 == "06") and
+                  (byte12 == ("03" or "04"))) 
+               then
+                       nmap.set_port_state(host, port, "open")
+                   port.version.name = "iax2"
+                   nmap.set_port_version(host, port, "hardmatched")
                end
 
-               soc:close()
-
        end
-
 end
Index: scripts/rpcinfo.nse
===================================================================
--- scripts/rpcinfo.nse (revision 7153)
+++ scripts/rpcinfo.nse (working copy)
@@ -5,6 +5,7 @@
 license = "Same as Nmap--See http://nmap.org/book/man-legal.html";
 categories = {"safe","discovery"}
 
+require "comm"
 require "shortport"
 require "packet"
 require "datafiles"
@@ -12,14 +13,12 @@
 portrule = shortport.port_or_service(111, "rpcbind")
 
 action = function(host, port)
-  local try, catch
+  local try
   local transaction_id = "nmap"
-  local socket = nmap.new_socket()
   local result = " \n"
   local rpc_numbers
 
-  catch = function() socket:close() end
-  try = nmap.new_try( catch )
+  try = nmap.new_try()
   rpc_numbers = try(datafiles.parse_rpc())
 
   local request = string.char(0x80,0,0,40) -- fragment header
@@ -29,16 +28,8 @@
   request = request .. "\0\0\0\2\0\0\0\4" -- programm version (2) procedure dump(4)
   request = request .. "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"-- Credentials and verifier
 
-  socket:set_timeout(1000)
-  try( socket:connect(host.ip, port.number) )
-  try( socket:send( request ) )
-  local status, answer, answer_part
-  status, answer = socket:receive_bytes( 1 )
-  while status do
-    status, answer_part = socket:receive_bytes( 1 )
-    if status then answer = answer .. answer_part end
-  end
-  socket:close()
+  local answer = try(comm.exchange(host, port, request, {timeout=1000}))
+  local answer_part
 
   local fragment_length = answer:byte(4) + answer:byte(3) * 256 + answer:byte(2) * 65536
   if answer:sub(5,8) == transaction_id and answer:byte(12) == 1 and answer:byte(16) == 0 and answer:byte(28) == 0 then
Index: scripts/HTTP_open_proxy.nse
===================================================================
--- scripts/HTTP_open_proxy.nse (revision 7153)
+++ scripts/HTTP_open_proxy.nse (working copy)
@@ -9,6 +9,8 @@
 description="Test if a discovered proxy is open to us by connecting to www.google.com and checking for the 'Server: 
GWS/' header response."
 tags = {"intrusive"}
 
+require 'comm'
+
 -- I found a nice explode() function in lua-users' wiki. I had to fix it, though.
 -- http://lua-users.org/wiki/LuaRecipes
 function explode(d,p)
@@ -39,22 +41,14 @@
 end
 
 action = function(host, port)
-       local socket = nmap.new_socket()
-       local result
-       local status = true
        local response
        local i
 -- We will return this if we don't find "^Server: GWS" in response headers
        local retval
 
-       socket:set_timeout(10000);
-       socket:connect(host.ip, port.number, port.protocol)
-       
 -- Ask proxy to open www.google.com
-       socket:send("GET http://www.google.com HTTP/1.0\r\nHost: www.google.com\r\n\r\n")
-
--- read the response, if any
-       status, result = socket:receive_lines(1)
+       local req = "GET http://www.google.com HTTP/1.0\r\nHost: www.google.com\r\n\r\n"
+       local status, result = comm.exchange(host, port, req, {proto=port.protocol, timeout=10000})
        
 -- Explode result into the response table
        if (status == false) or (result == "TIMEOUT") then
@@ -74,7 +68,5 @@
                end
        end
 
--- close the socket and exit, returning the retval string.
-       socket:close()
        return retval
 end
Index: scripts/finger.nse
===================================================================
--- scripts/finger.nse  (revision 7153)
+++ scripts/finger.nse  (working copy)
@@ -8,29 +8,13 @@
 
 categories = {"discovery"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.port_or_service(79, "finger")
 
 action = function(host, port)
-       local socket = nmap.new_socket()
-       local results = ""
-       local status = true
+       local try = nmap.new_try()
 
-       local err_catch = function()
-               socket:close()
-       end
-
-       local try = nmap.new_try(err_catch())
-
-       socket:set_timeout(5000)
-       try(socket:connect(host.ip, port.number, port.protocol))
-       try(socket:send("\r\n"))
-
-       status, results = socket:receive_lines(100)
-       socket:close()
-
-       if not(status) then
-               return results
-       end
+       return try(comm.exchange(host, port, "\r\n", {lines=100, proto=port.protocol, timeout=5000}))
 end
Index: scripts/mswindowsShell.nse
===================================================================
--- scripts/mswindowsShell.nse  (revision 7153)
+++ scripts/mswindowsShell.nse  (working copy)
@@ -9,22 +9,14 @@
 
 categories = {"backdoor"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.port_or_service(8888, "auth")
 
 action = function(host, port)
-       local status = 0
-       local result = ""
+       local status, result = comm.get_banner(host, port, {bytes=4096})
 
-       local client_ident = nmap.new_socket()
-
-       client_ident:connect(host.ip, port.number)
-
-       status, result = client_ident:receive_bytes(4096)
-
-       client_ident:close()
-
        if string.match(result, "Microsoft Windows") then
                return "Possible open windows shell found."
        end
Index: scripts/ircZombieTest.nse
===================================================================
--- scripts/ircZombieTest.nse   (revision 7153)
+++ scripts/ircZombieTest.nse   (working copy)
@@ -9,22 +9,14 @@
 
 categories = {"malware"}
 
+require "comm"
 require "shortport"
 
 portrule = shortport.port_or_service(113, "auth")
 
 action = function(host, port)
-       local status = 0
-       local owner = ""
+       local status, owner = comm.get_banner(host, port, {lines=1})
 
-       local client_ident = nmap.new_socket()
-
-       client_ident:connect(host.ip, port.number)
-
-       status, owner = client_ident:receive_lines(1)
-
-       client_ident:close()
-
        if owner == "TIMEOUT" then
                return
        end
Index: scripts/ripeQuery.nse
===================================================================
--- scripts/ripeQuery.nse       (revision 7153)
+++ scripts/ripeQuery.nse       (working copy)
@@ -1,3 +1,4 @@
+require "comm"
 require "ipOps"
 
 id = "RIPE query"
@@ -12,25 +13,8 @@
 end
 
 action = function(host, port)
-       local socket = nmap.new_socket()
-       local status, line
-       local result = ""
+       local status, result = comm.exchange("whois.ripe.net", 43, host.ip .. "\n")
 
-       socket:connect("whois.ripe.net", 43)
---     socket:connect("193.0.0.135", 43)
-       socket:send(host.ip .. "\n")
-
-       while true do
-               local status, lines = socket:receive_lines(1)
-
-               if not status then
-                       break
-               else
-                       result = result .. lines
-               end
-       end
-       socket:close()
-
        local value  = string.match(result, "role:(.-)\n")
 
        if (value == "see http://www.iana.org.";) then
Index: scripts/PPTPversion.nse
===================================================================
--- scripts/PPTPversion.nse     (revision 7153)
+++ scripts/PPTPversion.nse     (working copy)
@@ -11,6 +11,8 @@
 
 categories = {"version"}
 
+require "comm"
+
 portrule = function(host, port) 
        if 
                port.number == 1723
@@ -24,23 +26,6 @@
 end
 
 action = function(host, port)
-
-       -- create the socket used for our connection
-       local socket = nmap.new_socket()
-       
-       -- set a reasonable timeout value
-       socket:set_timeout(5000)
-       
-       -- do some exception handling / cleanup
-       local catch = function()
-               socket:close()
-       end
-       
-       local try = nmap.new_try(catch)
-       
-       -- connect to the potential PPTP service
-       try(socket:connect(host.ip, port.number, "tcp"))
-       
        local payload
          
        -- build a PPTP Start-Control-Connection-Request packet
@@ -67,24 +52,9 @@
        payload = payload .. "\000\000\000\000\000\000\000\000" -- padding for vendor name
        payload = payload .. "\000\000\000\000" -- padding for vendor name
 
-       try(socket:send(payload))
-       
-       local status
-       local response
-       
-       -- read in any response we might get
-       status, response = socket:receive_bytes(1)
+       local try = nmap.new_try()
+       local response = try(comm.exchange(host, port, payload, {bytes=1, timeout=5000}))
 
-       if (not status) then
-               return
-       end
-
-       if (response == "TIMEOUT") then
-               return
-       end
-
-       try(socket:close())
-       
        local result
                
        -- check to see if the packet we got back matches the beginning of a PPTP Start-Control-Connection-Reply packet

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

Current thread: