diff --git a/CHANGELOG b/CHANGELOG
index 9c477ed2b..ad901e4af 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -28,6 +28,10 @@ o Fixed the nmap_command_path bug in Zenmap. The variable now actually
by a new class in UmitConf called PathsConfig, which represents the
[paths] section in zenmap.conf. [Jurand Nogiec]
+o Added a new NSE Comm library for common network discovery tasks such
+ as banner-grabbing (get_banner()) and making a quick exchange of data
+ (exchange()). 16 scripts were updated to use this library. [Kris]
+
o Fixed a bug which caused -PN to erronously bail out for unprivileged
users. Thanks to Jabra (jabra(a)spl0it.org) for the report. [Kris]
diff --git a/docs/scripting.xml b/docs/scripting.xml
index 79a991fdf..29bcea62d 100644
--- a/docs/scripting.xml
+++ b/docs/scripting.xml
@@ -1441,6 +1441,61 @@ if(s) code_to_be_done_on_match end
+
+
+ Common Communication Functions
+
+ The comm module provides functions for common network discovery
+ tasks such as banner-grabbing and making a quick exchange of data. These functions'
+ return values are setup for use with exception handling via nmap.new_try().
+
+
+
+ These functions can all be passed a table of options, but it's not required.
+ The relevant indexes for this table are bytes, lines,
+ proto and timeout. bytes
+ is used to provide the minimum number of bytes required for a read. lines
+ does the same, but for the minimum number of lines. proto is used
+ to set the protocol to communicate with, defaulting to "tcp" if not provided.
+ timeout is used to set the socket timeout (see the socket function
+ set_timeout() for details).
+
+
+
+
+
+ get_banner
+
+
+ This function simply connects to the specified port number on
+ the specified host and returns any data received.
+ bool is a boolean value indicating success.
+ If bool is true, then the second returned
+ value is the response from the target host. If bool
+ is false, an error message is returned as the second value instead
+ of a response.
+
+
+
+
+
+
+ exchange
+
+
+ This function connects to the specified port number on the
+ specified host, sends data, then waits for
+ and returns the response, if any. bool is a
+ boolean value indicating success. If bool is
+ true, then the second returned value is the response from the
+ target host. If bool is false, an error message
+ is returned as the second value instead of a response.
+
+
+
+
+
+
Data File Parsing Functions
diff --git a/nselib/comm.lua b/nselib/comm.lua
new file mode 100644
index 000000000..48ad74cfb
--- /dev/null
+++ b/nselib/comm.lua
@@ -0,0 +1,151 @@
+-- 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 are to be read from the host
+-- lines: Specifies the minimum amount of lines are to be read from the host
+-- proto: Specifies the protocol to be used with the connect() call
+-- 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)
+ local line, response, status
+
+ if opts.lines then
+ status, response = sock:receive_lines(opts.lines)
+ return status, response
+ elseif opts.bytes then
+ status, response = sock:receive_bytes(opts.bytes)
+ return status, response
+ end
+
+ response = ""
+
+ while true do
+ status, line = sock:receive_lines(1)
+
+ if not status then
+ break
+ end
+
+ response = response .. line
+ end
+
+ -- Either we reached the end of the stream, or we got all we could
+ -- within the socket timeout
+ if line == "EOF" or (line == "TIMEOUT" and response ~= "") then
+ return true, response
+ end
+
+ return false, line
+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
+
diff --git a/scripts/HTTP_open_proxy.nse b/scripts/HTTP_open_proxy.nse
index 3b164dd39..9211a0c30 100644
--- a/scripts/HTTP_open_proxy.nse
+++ b/scripts/HTTP_open_proxy.nse
@@ -8,6 +8,7 @@
id="Open Proxy Test"
description="Test if a discovered proxy is open to us by connecting to www.google.com and checking for the 'Server: GWS/' header response."
categories = {"default", "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
@@ -39,29 +40,22 @@ portrule = function(host, port)
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
- else
- response = explode("\n",result)
+ if not status then
+ return
end
+-- Explode result into the response table
+ response = explode("\n",result)
+
-- Now, search for Server: GWS until headers (or table) end.
i = 0
while true do
@@ -74,7 +68,5 @@ action = function(host, port)
end
end
--- close the socket and exit, returning the retval string.
- socket:close()
return retval
end
diff --git a/scripts/HTTPtrace.nse b/scripts/HTTPtrace.nse
index 40e0bc3a2..9f35972a5 100644
--- a/scripts/HTTPtrace.nse
+++ b/scripts/HTTPtrace.nse
@@ -18,6 +18,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"discovery"}
+require "comm"
require "shortport"
require "stdnse"
@@ -76,31 +77,14 @@ end
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
diff --git a/scripts/MySQLinfo.nse b/scripts/MySQLinfo.nse
index 089153020..401a770a1 100644
--- a/scripts/MySQLinfo.nse
+++ b/scripts/MySQLinfo.nse
@@ -18,6 +18,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = { "default", "discovery", "safe" }
require 'bit'
+require 'comm'
-- Grabs NUL-terminated string
local getstring = function(orig)
@@ -105,28 +106,14 @@ portrule = function(host, port)
end
action = function(host, port)
- local sock
- local response = ""
local output = ""
- sock = nmap.new_socket()
+ local status, response = comm.get_banner(host, port, {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
diff --git a/scripts/PPTPversion.nse b/scripts/PPTPversion.nse
index bdc32322a..ade1fc806 100644
--- a/scripts/PPTPversion.nse
+++ b/scripts/PPTPversion.nse
@@ -11,6 +11,8 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"version"}
+require "comm"
+
portrule = function(host, port)
if
port.number == 1723
@@ -24,23 +26,6 @@ portrule = function(host, port)
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 @@ action = function(host, port)
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
diff --git a/scripts/chargenTest.nse b/scripts/chargenTest.nse
index b5da712ba..c138c3653 100644
--- a/scripts/chargenTest.nse
+++ b/scripts/chargenTest.nse
@@ -8,20 +8,15 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
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 status then
return "Chargen: success"
- else
- return "Chargen: something went wrong"
end
end
diff --git a/scripts/daytimeTest.nse b/scripts/daytimeTest.nse
index 1e1d6cafb..320ec21ae 100644
--- a/scripts/daytimeTest.nse
+++ b/scripts/daytimeTest.nse
@@ -8,18 +8,15 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
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
+ if status then
return "Daytime: " .. result
end
end
diff --git a/scripts/dns-test-open-recursion.nse b/scripts/dns-test-open-recursion.nse
index 894194e58..d495f1c32 100644
--- a/scripts/dns-test-open-recursion.nse
+++ b/scripts/dns-test-open-recursion.nse
@@ -9,6 +9,7 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default", "intrusive"}
require "bit"
+require "comm"
require "shortport"
portrule = shortport.portnumber(53, "udp")
@@ -18,12 +19,11 @@ action = function(host, port)
-- generate dns query, Transaction-ID 0xdead, www.wikipedia.org (type A, class IN)
local request = string.char(0xde, 0xad, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03) .. "www" .. string.char(0x09) .. "wikipedia" .. 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 then
+ return
+ end
-- parse response for dns flags
if (bit.band(string.byte(result,3), 0x80) == 0x80
diff --git a/scripts/echoTest.nse b/scripts/echoTest.nse
index 431428aa5..6e5f15cc9 100644
--- a/scripts/echoTest.nse
+++ b/scripts/echoTest.nse
@@ -9,21 +9,17 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
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
-
- return
end
diff --git a/scripts/finger.nse b/scripts/finger.nse
index 5aeca9550..d24c91d85 100644
--- a/scripts/finger.nse
+++ b/scripts/finger.nse
@@ -8,29 +8,13 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default", "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
diff --git a/scripts/iax2Detect.nse b/scripts/iax2Detect.nse
index 5ee922bf3..28026e1ed 100644
--- a/scripts/iax2Detect.nse
+++ b/scripts/iax2Detect.nse
@@ -9,43 +9,36 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
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
- 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))
-
- -- 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
-
- end
-
- soc:close()
+ local status, recv = comm.exchange(host, port, poke, {bytes=1,proto=port.protocol,timeout=10000})
+ if not status then
+ return
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
+
+ end
end
diff --git a/scripts/ircZombieTest.nse b/scripts/ircZombieTest.nse
index c3c672f94..3a411a7c1 100644
--- a/scripts/ircZombieTest.nse
+++ b/scripts/ircZombieTest.nse
@@ -9,23 +9,15 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
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
+ if not status then
return
end
diff --git a/scripts/nbstat.nse b/scripts/nbstat.nse
index 1dcf95e45..e34cb3782 100644
--- a/scripts/nbstat.nse
+++ b/scripts/nbstat.nse
@@ -11,6 +11,8 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default", "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,51 +51,23 @@ end
-- 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"
+
+ local status, result = comm.exchange(host, 137, data, {bytes=1, proto="udp", timeout=5000})
if (not status) then
- -- Can the first UDP send ever fail?
- return
- end
-
- -- 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
-
- if (result == "TIMEOUT") then
return
end
diff --git a/scripts/ripeQuery.nse b/scripts/ripeQuery.nse
index bf21cf36d..a25ebc783 100644
--- a/scripts/ripeQuery.nse
+++ b/scripts/ripeQuery.nse
@@ -1,3 +1,4 @@
+require "comm"
require "ipOps"
id = "RIPE query"
@@ -12,24 +13,11 @@ hostrule = function(host, port)
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
+ if not status then
+ return
end
- socket:close()
local value = string.match(result, "role:(.-)\n")
diff --git a/scripts/rpcinfo.nse b/scripts/rpcinfo.nse
index 3a5ba6607..a0e8676bc 100644
--- a/scripts/rpcinfo.nse
+++ b/scripts/rpcinfo.nse
@@ -5,6 +5,7 @@ author = "Sven Klemm "
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
categories = {"default","safe","discovery"}
+require "comm"
require "shortport"
require "packet"
require "datafiles"
@@ -12,14 +13,12 @@ require "datafiles"
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 @@ action = function(host, port)
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
diff --git a/scripts/showSMTPVersion.nse b/scripts/showSMTPVersion.nse
index f346c82fe..f034da515 100644
--- a/scripts/showSMTPVersion.nse
+++ b/scripts/showSMTPVersion.nse
@@ -8,24 +8,18 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
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", "")
+ if not status then
+ return
end
- return result
+ return string.gsub(result, "\n", "")
end
diff --git a/scripts/skype_v2-version.nse b/scripts/skype_v2-version.nse
index 532d10141..617c79ae6 100644
--- a/scripts/skype_v2-version.nse
+++ b/scripts/skype_v2-version.nse
@@ -3,6 +3,7 @@ description="Determines if remote service is Skype protocol version 2"
author = "Brandon Enright "
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 @@ portrule = function(host, port)
end
action = function(host, port)
-
- 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);
+ local status, result = comm.exchange(host, port, "GET / HTTP/1.0\r\n\r\n", {bytes=26, proto=port.protocol})
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 = socket:receive_bytes(15);
+ status, result = comm.exchange(host, port, "random data\r\n\r\n", {bytes=15, proto=port.protocol})
if (not status) then
- socket:close()
return
end
if string.match(result, "[^%s!-~].*[^%s!-~].*[^%s!-~]") then
- socket:close()
port.version.name = "skype2"
port.version.product = "Skype"
port.version.confidence = 10
@@ -67,7 +51,5 @@ action = function(host, port)
-- return "Skype v2 server detected"
end
- socket:close();
-
return
end