From 3c5137e7e77274188969796e0920d70b40c2c98a Mon Sep 17 00:00:00 2001 From: dmiller Date: Mon, 8 Sep 2014 04:35:49 +0000 Subject: [PATCH] Update 14 scripts with XML structured output --- scripts/bitcoinrpc-info.nse | 51 ++++++---- scripts/broadcast-versant-locate.nse | 6 +- scripts/cassandra-info.nse | 13 ++- scripts/flume-master-info.nse | 86 +++++++++++++---- scripts/giop-info.nse | 46 ++++++--- scripts/hadoop-datanode-info.nse | 10 +- scripts/hadoop-secondary-namenode-info.nse | 39 +++++--- scripts/hbase-region-info.nse | 13 ++- scripts/hddtemp-info.nse | 38 ++++++-- scripts/ipv6-node-info.nse | 48 ++++++---- scripts/iscsi-info.nse | 33 ++++--- scripts/openlookup-info.nse | 51 ++++------ scripts/rtsp-methods.nse | 10 +- scripts/snmp-processes.nse | 105 +++++++++++++-------- 14 files changed, 358 insertions(+), 191 deletions(-) diff --git a/scripts/bitcoinrpc-info.nse b/scripts/bitcoinrpc-info.nse index e5824418f..9c550fd26 100644 --- a/scripts/bitcoinrpc-info.nse +++ b/scripts/bitcoinrpc-info.nse @@ -18,18 +18,33 @@ Obtains information from a Bitcoin server by calling getinfo on its -- @output -- 8332/tcp open unknown -- | bitcoinrpc-info.nse: --- | USER: root --- | connections: 36 --- | hashespersec: 0 --- | generate: false --- | keypoololdest: 1309381827 --- | difficulty: 1379223.4296725 +-- | root: -- | balance: 0 --- | version: 32100 +-- | blocks: 135041 +-- | connections: 36 +-- | difficulty: 1379223.4296725 +-- | generate: false +-- | genproclimit: -1 +-- | hashespersec: 0 +-- | keypoololdest: 1309381827 -- | paytxfee: 0 -- | testnet: false --- | blocks: 135041 --- |_ genproclimit: -1 +-- |_ version: 32100 +-- +-- @xmloutput +-- +-- 0 +-- 135041 +-- 36 +-- 1379223.4296725 +-- false +-- -1 +-- 0 +-- 1309381827 +-- 0 +-- false +-- 32100 +--
author = "Toni Ruottu" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" @@ -108,11 +123,12 @@ local function decode_bitcoin_version(n) end local function formatpairs(info) - local result = {} - for k, v in pairs(info) do - if v ~= "" then - local line = k .. ": " .. tostring(v) - table.insert(result, line) + local result = stdnse.output_table() + local keys = stdnse.keys(info) + table.sort(keys) + for _, k in ipairs(keys) do + if info[k] ~= "" then + result[k] = info[k] end end return result @@ -125,15 +141,14 @@ local function getinfo(host, port, user, pass) end action = function(host, port) - local response = {} + local response = stdnse.output_table() local c = creds.Credentials:new(creds.ALL_DATA, host, port) local states = creds.State.VALID + creds.State.PARAM for cred in c:getCredentials(states) do local info = getinfo(host, port, cred.user, cred.pass) if info then local result = formatpairs(info) - result["name"] = "USER: " .. cred.user - table.insert(response, result) + response[cred.user] = result port.version.name = "http" port.version.product = "Bitcoin JSON-RPC" @@ -144,6 +159,6 @@ action = function(host, port) end end - return stdnse.format_output(true, response) + return response end diff --git a/scripts/broadcast-versant-locate.nse b/scripts/broadcast-versant-locate.nse index 75f34fac1..e096d442f 100644 --- a/scripts/broadcast-versant-locate.nse +++ b/scripts/broadcast-versant-locate.nse @@ -15,6 +15,10 @@ Discovers Versant object databases using the broadcast srvloc protocol. -- | broadcast-versant-locate: -- |_ vod://192.168.200.222:5019 -- +-- @xmloutput +-- +-- vod://192.168.200.222:5019 +--
author = "Patrik Karlsson" @@ -34,5 +38,5 @@ action = function() for _, v in ipairs(result) do table.insert(output, v:match("^service:odbms.versant:vod://(.*)$")) end - return stdnse.format_output(true, output) + return output end diff --git a/scripts/cassandra-info.nse b/scripts/cassandra-info.nse index c9dcc0ba4..cea03fc1b 100644 --- a/scripts/cassandra-info.nse +++ b/scripts/cassandra-info.nse @@ -24,6 +24,9 @@ http://cassandra.apache.org/ -- | Cluster name: Test Cluster -- |_ Version: 19.10.0 -- +-- @xmloutput +-- Test Cluster +-- 19.10.0 -- version 0.1 -- Created 14/09/2012 - v0.1 - created by Vlatko Kosturjak @@ -52,7 +55,7 @@ function action(host,port) try( socket:connect(host, port) ) - local results = {} + local results = stdnse.output_table() -- ugliness to allow creds.cassandra to work, as the port is not recognized -- as cassandra even when service scan was run, taken from mongodb @@ -61,7 +64,7 @@ function action(host,port) local c = creds.Credentials:new(creds.ALL_DATA, host, port) for cred in c:getCredentials(creds.State.VALID + creds.State.PARAM) do local status, err = cassandra.login(socket, cred.user, cred.pass) - table.insert(results, ("Using credentials: %s"):format(cred.user.."/"..cred.pass)) + results["Using credentials"] = cred.user.."/"..cred.pass if ( not(status) ) then return err end @@ -77,7 +80,7 @@ function action(host,port) port.version.product='Cassandra' port.version.name_confidence = 10 nmap.set_port_version(host,port) - table.insert(results, ("Cluster name: %s"):format(val)) + results["Cluster name"] = val local status, val = cassandra.describe_version(socket,cassinc) if (not(status)) then @@ -86,7 +89,7 @@ function action(host,port) cassinc = cassinc + 1 port.version.product='Cassandra ('..val..')' nmap.set_port_version(host,port) - table.insert(results, ("Version: %s"):format(val)) + results["Version"] = val - return stdnse.format_output(true, results) + return results end diff --git a/scripts/flume-master-info.nse b/scripts/flume-master-info.nse index 779564ea0..db84b2479 100644 --- a/scripts/flume-master-info.nse +++ b/scripts/flume-master-info.nse @@ -79,6 +79,61 @@ the Nmap scan queue. --| mapred.job.tracker.retiredjobs.cache.size: 1000 --| mapred.task.tracker.http.address: 0.0.0.0:50060 --|_ mapred.task.tracker.report.address: 127.0.0.1:0 +-- +--@xmloutput +-- 0.9.4-cdh3u3 +-- 0 +-- +-- node1.example.com +-- node2.example.com +-- node5.example.com +-- node6.example.com +-- node3.example.com +-- node4.example.com +--
+-- +-- master1.example.com +--
+-- +-- hdfs://master1.example.com:8020/hbase +--
+-- +-- Java(TM) SE Runtime Environment +-- 1.6.0_36-a01 +-- 1.6.0_36 +-- Java HotSpot(TM) 64-Bit Server VM +-- Sun Microsystems Inc. +-- 14.0-b12 +-- amd64 +-- Linux +-- 2.6.32-220.4.2.el6.x86_64 +-- US +-- flume +--
+-- +-- 0.0.0.0:50010 +-- 0.0.0.0:50075 +-- 0.0.0.0:50475 +-- 0.0.0.0:50020 +-- master1.example.com:50070 +-- 0.0.0.0:50470 +-- 0.0.0.0:50090 +-- hdfs://master1.example.com/user/flume/collected +-- node1.example.com +-- master1.example.com +-- hdfs://master1.example.com:8020 +-- master1.example.com:9001 +-- 10 +-- 0.0.0.0:50030 +-- 0.0.0.0:50030 +-- 5 +-- false +-- /jobtracker/jobsInfo +-- 0 +-- 1000 +-- 0.0.0.0:50060 +-- 127.0.0.1:0 +--
author = "John R. Bond" license = "Simplified (2-clause) BSD license--See http://nmap.org/svn/docs/licenses/BSD-simplified" @@ -111,7 +166,7 @@ function table_count(tt, item) end parse_page = function( host, port, uri, interesting_keys ) - local result = {} + local result = stdnse.output_table() local response = http.get( host, port, uri ) stdnse.debug1("Status %s", response['status-line'] or "No Response") if response['status-line'] and response['status-line']:match("200%s+OK") @@ -121,11 +176,11 @@ parse_page = function( host, port, uri, interesting_keys ) "([^][<]+)%s*]+>([^][<]+)") do stdnse.debug1("%s=%s ", name, value:gsub("^%s*(.-)%s*$", "%1")) if nmap.verbosity() > 1 then - result[#result+1] = ("%s: %s"):format(name,value:gsub("^%s*(.-)%s*$", "%1")) + result[name] = value:gsub("^%s*(.-)%s*$", "%1") else for i,v in ipairs(interesting_keys) do if name:match(("^%s"):format(v)) then - result[#result+1] = ("%s: %s"):format(name,value:gsub("^%s*(.-)%s*$", "%1")) + result[name] = value:gsub("^%s*(.-)%s*$", "%1") end end end @@ -136,7 +191,7 @@ end action = function( host, port ) - local result = {} + local result = stdnse.output_table() local uri = "/flumemaster.jsp" local env_uri = "/masterenv.jsp" local config_uri = "/masterstaticconfig.jsp" @@ -182,18 +237,18 @@ action = function( host, port ) if body:match("Version:%s*([^][,]+)") then local version = body:match("Version:%s*([^][,]+)") stdnse.debug1("Version %s", version) - result[#result+1] = ("Version: %s"):format(version) + result["Version"] = version port.version.version = version end if body:match("Compiled:%s*([^][<]+)") then local compiled = body:match("Compiled:%s*([^][<]+)") stdnse.debug1("Compiled %s", compiled) - result[#result+1] = ("Compiled: %s"):format(compiled) + result["Compiled"] = compiled end if body:match("ServerID:%s*([^][<]+)") then local upgrades = body:match("ServerID:%s*([^][<]+)") stdnse.debug1("ServerID %s", upgrades) - result[#result] = ("ServerID: %s"):format(upgrades) + result["ServerID"] = upgrades end for logical,physical,hostname in string.gmatch(body, "([%w%.-_:]+)([%w%.]+)([%w%.]+)") do @@ -204,8 +259,7 @@ action = function( host, port ) end end if next(nodes) ~= nil then - table.insert(result, "Flume nodes:") - result[#result+1] = nodes + result["Flume nodes"] = nodes end for zookeeper in string.gmatch(body,"Dhbase.zookeeper.quorum=([^][\"]+)") do if (table_count(zookeepers, zookeeper) == 0) then @@ -214,8 +268,7 @@ action = function( host, port ) end end if next(zookeepers) ~= nil then - result[#result+1] = "Zookeeper Master:" - result[#result+1] = zookeepers + result["Zookeeper Master"] = zookeepers end for hbasemaster in string.gmatch(body,"Dhbase.rootdir=([^][\"]+)") do if (table_count(hbasemasters, hbasemaster) == 0) then @@ -224,24 +277,21 @@ action = function( host, port ) end end if next(hbasemasters) ~= nil then - result[#result+1] = "Hbase Master Master:" - result[#result+1] = hbasemasters + result["Hbase Masters"] = hbasemasters end local vars = parse_page(host, port, env_uri, env_keys ) if next(vars) ~= nil then - result[#result+1] = "Enviroment: " - result[#result+1] = vars + result["Environment"] = vars end local vars = parse_page(host, port, config_uri, config_keys ) if next(vars) ~= nil then - result[#result+1] = "Config: " - result[#result+1] = vars + result["Config"] = vars end if #result > 0 then port.version.name = "flume-master" port.version.product = "Apache Flume" nmap.set_port_version(host, port) + return result end - return stdnse.format_output(true, result) end end diff --git a/scripts/giop-info.nse b/scripts/giop-info.nse index 5406d4494..f9d85153c 100644 --- a/scripts/giop-info.nse +++ b/scripts/giop-info.nse @@ -19,6 +19,23 @@ categories = {"default", "discovery", "safe"} -- | Object: Hello -- | Context: Test -- |_ Object: GoodBye +-- +-- @xmloutput +-- +-- 0 +-- Hello +-- 18 +--
+-- +-- 1 +-- Test +-- 0 +--
+-- +-- 0 +-- Goodbye +-- 18 +--
-- Version 0.1 @@ -28,11 +45,24 @@ categories = {"default", "discovery", "safe"} portrule = shortport.port_or_service( {2809,1050,1049} , "giop", "tcp", "open") +local fmt_meta = { + __tostring = function (t) + local tmp = "Unknown" + if ( t.enum == 0 ) then + tmp = "Object" + elseif( t.enum == 1 ) then + tmp = "Context" + end + + -- TODO: Handle t.kind? May require IDL. + return ("%s: %s"):format(tmp, t.id) + end +} + action = function(host, port) local helper = giop.Helper:new( host, port ) local ctx, objs, status, err - local result = {} status, err = helper:Connect() if ( not(status) ) then return err end @@ -44,18 +74,8 @@ action = function(host, port) if ( not(status) ) then return " \n ERROR: " .. objs end for _, obj in ipairs( objs ) do - local tmp = "" - - if ( obj.enum == 0 ) then - tmp = "Object: " - elseif( obj.enum == 1 ) then - tmp = "Context: " - else - tmp = "Unknown: " - end - - table.insert(result, tmp .. obj.id ) + setmetatable(obj, fmt_meta) end - return stdnse.format_output(true, result) + return objs end diff --git a/scripts/hadoop-datanode-info.nse b/scripts/hadoop-datanode-info.nse index 57ae1e125..34864fd1e 100644 --- a/scripts/hadoop-datanode-info.nse +++ b/scripts/hadoop-datanode-info.nse @@ -25,7 +25,9 @@ For more information about hadoop, see: -- 50075/tcp open hadoop-datanode syn-ack -- | hadoop-datanode-info: -- |_ Logs: /logs/ ---- +-- +-- @xmloutput +-- /logs/ author = "John R. Bond" @@ -42,7 +44,7 @@ end action = function( host, port ) - local result = {} + local result = stdnse.output_table() local uri = "/browseDirectory.jsp" stdnse.debug1("HTTP GET %s:%s%s", host.targetname or host.ip, port.number, uri) local response = http.get( host, port, uri ) @@ -56,8 +58,8 @@ action = function( host, port ) nmap.set_port_version(host, port) local logs = body:match("([^][\"]+)\">Log") stdnse.debug1("Logs %s",logs) - table.insert(result, ("Logs: %s"):format(logs)) + result["Logs"] = logs end - return stdnse.format_output(true, result) + return result end end diff --git a/scripts/hadoop-secondary-namenode-info.nse b/scripts/hadoop-secondary-namenode-info.nse index 6df528665..87f0492fe 100644 --- a/scripts/hadoop-secondary-namenode-info.nse +++ b/scripts/hadoop-secondary-namenode-info.nse @@ -42,6 +42,15 @@ For more information about Hadoop, see: -- | Checkpoint Period: 3600 seconds -- |_ Checkpoint Size: 12345678 MB -- +-- @xmloutput +-- Wed May 11 22:33:44 PDT 2011 +-- 0.20.2, f415ef415ef415ef415ef415ef415ef415ef415e +-- Wed May 11 22:33:44 PDT 2011 by bob from unknown +-- /logs/ +-- namenode1.example.com/192.0.1.1:8020 +-- Wed May 11 22:33:44 PDT 2011 +-- 3600 seconds +-- 12345678 MB author = "John R. Bond" license = "Simplified (2-clause) BSD license--See http://nmap.org/svn/docs/licenses/BSD-simplified" @@ -57,7 +66,7 @@ end action = function( host, port ) - local result = {} + local result = stdnse.output_table() local uri = "/status.jsp" stdnse.debug1("HTTP GET %s:%s%s", host.targetname or host.ip, port.number, uri) local response = http.get( host, port, uri ) @@ -76,34 +85,29 @@ action = function( host, port ) stdnse.debug1("Last Checkpoint %s",stats[3]) stdnse.debug1("Checkpoint Period %s",stats[4]) stdnse.debug1("Checkpoint Size %s",stats[5]) - table.insert(result, ("Start: %s"):format(stats[2])) + result["Start"] = stats[2] end if body:match("Version:%s*([^][\n]+)") then local version = body:match("Version:%s*([^][\n]+)") stdnse.debug1("Version %s",version) - table.insert(result, ("Version: %s"):format(version)) + result["Version"] = version port.version.version = version end if body:match("Compiled:%s*([^][\n]+)") then local compiled = body:match("Compiled:%s*([^][\n]+)") stdnse.debug1("Compiled %s",compiled) - table.insert(result, ("Compiled: %s"):format(compiled)) + result["Compiled"] = compiled end if body:match("([^][\"]+)\">Logs") then local logs = body:match("([^][\"]+)\">Logs") stdnse.debug1("Logs %s",logs) - table.insert(result, ("Logs: %s"):format(logs)) + result["Logs"] = logs end if #stats == 5 then - table.insert(result, ("Namenode: %s"):format(stats[1])) - table.insert(result, ("Last Checkpoint: %s"):format(stats[3])) - table.insert(result, ("Checkpoint Period: %s"):format(stats[4])) - table.insert(result, ("Checkpoint: Size %s"):format(stats[5])) - end - if #result > 0 then - port.version.name = "hadoop-secondary-namenode" - port.version.product = "Apache Hadoop" - nmap.set_port_version(host, port) + result["Namenode"] = stats[1] + result["Last Checkpoint"] = stats[3] + result["Checkpoint Period"] = stats[4] + result["Checkpoint"] = stats[5] end if target.ALLOW_NEW_TARGETS then if stats[1]:match("([^][/]+)") then @@ -112,7 +116,12 @@ action = function( host, port ) local status,err = target.add(newtarget) end end + if #result > 0 then + port.version.name = "hadoop-secondary-namenode" + port.version.product = "Apache Hadoop" + nmap.set_port_version(host, port) + return result + end end - return stdnse.format_output(true, result) end diff --git a/scripts/hbase-region-info.nse b/scripts/hbase-region-info.nse index d4156528d..eeccb03ff 100644 --- a/scripts/hbase-region-info.nse +++ b/scripts/hbase-region-info.nse @@ -51,8 +51,7 @@ end action = function( host, port ) - local result = {} - local region_servers = {} + local result = stdnse.output_table() -- uri was previously "/regionserver.jsp". See -- http://seclists.org/nmap-dev/2012/q3/903. local uri = "/rs-status" @@ -65,23 +64,23 @@ action = function( host, port ) if body:match("HBase%s+Version([^][<]+)") then local version = body:match("HBase%s+Version([^][<]+)"):gsub("%s+", " ") stdnse.debug1("Hbase Version %s",version) - table.insert(result, ("Hbase Version: %s"):format(version)) + result["Hbase Version"] = version port.version.version = version end if body:match("HBase%s+Compiled([^][<]+)") then local compiled = body:match("HBase%s+Compiled([^][<]+)"):gsub("%s+", " ") stdnse.debug1("Hbase Compiled %s",compiled) - table.insert(result, ("Hbase Compiled: %s"):format(compiled)) + result["Hbase Compiled"] = compiled end if body:match("Metrics([^][<]+)") then local metrics = body:match("Metrics([^][<]+)"):gsub("%s+", " ") stdnse.debug1("Metrics %s",metrics) - table.insert(result, ("Metrics %s"):format(metrics)) + result["Metrics"] = metrics end if body:match("Quorum([^][<]+)") then local quorum = body:match("Quorum([^][<]+)"):gsub("%s+", " ") stdnse.debug1("Zookeeper Quorum %s",quorum) - table.insert(result, ("Zookeeper Quorum: %s"):format(quorum)) + result["Zookeeper Quorum"] = quorum if target.ALLOW_NEW_TARGETS then if quorum:match("([%w%.]+)") then local newtarget = quorum:match("([%w%.]+)") @@ -94,7 +93,7 @@ action = function( host, port ) port.version.name = "hbase-region" port.version.product = "Apache Hadoop Hbase" nmap.set_port_version(host, port) + return result end - return stdnse.format_output(true, result) end end diff --git a/scripts/hddtemp-info.nse b/scripts/hddtemp-info.nse index 071716409..18abe393d 100644 --- a/scripts/hddtemp-info.nse +++ b/scripts/hddtemp-info.nse @@ -15,7 +15,22 @@ Reads hard disk information (such as brand, model, and sometimes temperature) fr -- -- @output -- 7634/tcp open hddtemp --- |_hddtemp-info: /dev/sda: WDC WD2500JS-60MHB1: 38 C +-- | hddtemp-info: +-- |_ /dev/sda: WDC WD2500JS-60MHB1: 38 C +-- +-- @xmloutput +-- +-- WDC WD2500JS-60MHB1 +-- C +-- /dev/sda +-- 38 +--
+-- +-- WDC WD3200BPVT-75JJ5T0 +-- C +-- /dev/sdb +-- 41 +--
author = "Toni Ruottu" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" @@ -24,6 +39,11 @@ categories = {"default", "discovery", "safe"} portrule = shortport.port_or_service (7634, "hddtemp", {"tcp"}) +local fmt_meta = { + __tostring = function (t) + return string.format("%s: %s: %s %s", t.device, t.label, t.temperature, t.unit) + end +} action = function( host, port ) -- 5000B should be enough for 100 disks local status, data = comm.get_banner(host, port, {bytes=5000}) @@ -36,12 +56,14 @@ action = function( host, port ) local disks = math.floor((# fields) / 5) for i = 0, (disks - 1) do local start = i * 5 - local device = fields[start + 2] - local label = fields[start + 3] - local temperature = fields[start + 4] - local unit = fields[start + 5] - local formatted = string.format("%s: %s: %s %s", device, label, temperature, unit) - table.insert(info, formatted) + local diskinfo = { + device = fields[start + 2], + label = fields[start + 3], + temperature = fields[start + 4], + unit = fields[start + 5], + } + setmetatable(diskinfo, fmt_meta) + table.insert(info, diskinfo) end - return stdnse.format_output(true, info) + return info end diff --git a/scripts/ipv6-node-info.nse b/scripts/ipv6-node-info.nse index d9cc619bf..622f37bb0 100644 --- a/scripts/ipv6-node-info.nse +++ b/scripts/ipv6-node-info.nse @@ -30,7 +30,17 @@ hostnames)". -- | ipv6-node-info: -- | Hostnames: mac-mini.local -- | IPv6 addresses: fe80::a8bb:ccff:fedd:eeff, 2001:db8:1234:1234::3 --- |_ IPv4 addresses: (actually hostnames) mac-mini.local +-- |_ IPv4 addresses: mac-mini.local +-- +-- @xmloutput +-- mac-mini.local +-- +-- fe80::a8bb:ccff:fedd:eeff +-- 2001:db8:1234:1234::3 +--
+-- +-- mac-mini.local +--
categories = {"default", "discovery", "safe"} @@ -147,27 +157,31 @@ local function stringify_noop(flags, data) return "replied" end +local commasep = { + __tostring = function (t) + return stdnse.strjoin(", ", t) + end +} + -- RFC 4620, section 6.3. local function stringify_nodename(flags, data) local status, names - local text status, names = try_decode_nodenames(data) if empty(names) then return end - text = stdnse.strjoin(", ", names) if not status then - text = text .. " (parsing error)" + names[#names+1] = "(parsing error)" end - return text + setmetatable(names, commasep) + return names end -- RFC 4620, section 6.3. local function stringify_nodeaddresses(flags, data) local ttl, binaddr - local text local addrs = {} local pos = nil @@ -182,12 +196,12 @@ local function stringify_nodeaddresses(flags, data) return end - text = stdnse.strjoin(", ", addrs) if bit.band(flags, 0x01) ~= 0 then - text = text .. " (more omitted for space reasons)" + addrs[#addrs+1] = "(more omitted for space reasons)" end - return text + setmetatable(addrs, commasep) + return addrs end -- RFC 4620, section 6.4. @@ -202,14 +216,14 @@ end local function stringify_nodeipv4addresses(flags, data) local status, names local ttl, binaddr - local text local addrs = {} local pos = nil -- Check for DNS names. status, names = try_decode_nodenames(data .. "\0\0") if status then - return "(actually hostnames) " .. stdnse.strjoin(", ", names) + setmetatable(names, commasep) + return names end -- Okay, looks like it's really IP addresses. @@ -224,12 +238,12 @@ local function stringify_nodeipv4addresses(flags, data) return end - text = stdnse.strjoin(", ", addrs) if bit.band(flags, 0x01) ~= 0 then - text = text .. " (more omitted for space reasons)" + addrs[#addrs+1] = "(more omitted for space reasons)" end - return text + setmetatable(addrs, commasep) + return addrs end local STRINGIFY = { @@ -279,14 +293,14 @@ local function format_results(results) } local output - output = {} + output = stdnse.output_table() for _, qtype in ipairs(QTYPE_ORDER) do if results[qtype] then - output[#output + 1] = QTYPE_STRINGS[qtype] .. ": " .. results[qtype] + output[QTYPE_STRINGS[qtype]] = results[qtype] end end - return stdnse.format_output(true, output) + return output end function action(host) diff --git a/scripts/iscsi-info.nse b/scripts/iscsi-info.nse index d98d1dbb1..4fb92038e 100644 --- a/scripts/iscsi-info.nse +++ b/scripts/iscsi-info.nse @@ -13,12 +13,23 @@ Collects and displays information from remote iSCSI targets. -- 3260/tcp open iscsi -- | iscsi-info: -- | iqn.2006-01.com.openfiler:tsn.c8c08cad469d --- | Target address: 192.168.56.5:3260,1 +-- | Address: 192.168.56.5:3260,1 -- | Authentication: NOT required -- | iqn.2006-01.com.openfiler:tsn.6aea7e052952 --- | Target address: 192.168.56.5:3260,1 --- |_ Authentication: required +-- | Address: 192.168.56.5:3260,1 +-- | Authentication: required +-- |_ Auth reason: Authentication failure -- +-- @xmloutput +-- +-- 192.168.56.5:3260,1 +-- NOT required +--
+-- +-- 192.168.56.5:3260,1 +-- required +-- Authentication failure +--
-- Version 0.2 -- Created 2010/11/18 - v0.1 - created by Patrik Karlsson @@ -76,21 +87,21 @@ action = function( host, port ) status = helper:logout() status = helper:close() - local result = {} + local result = stdnse.output_table() for _, record in ipairs(records) do - local result_part = {} - result_part.name = ("Target: %s"):format(record.name) + local result_part = stdnse.output_table() for _, addr in ipairs( record.addr ) do - table.insert(result_part, ("Address: %s"):format(addr) ) + result_part["Address"] = addr end local status, err = requiresAuth( host, port, record.name ) if ( not(status) ) then - table.insert(result_part, "Authentication: " .. err ) + result_part["Authentication"] = "required" + result_part["Auth reason"] = err else - table.insert(result_part, "Authentication: No authentication required") + result_part["Authentication"] = "NOT required" end - table.insert(result, result_part) + result[record.name] = result_part end - return stdnse.format_output( true, result ) + return result end diff --git a/scripts/openlookup-info.nse b/scripts/openlookup-info.nse index 58a802164..7ce9e2f4f 100644 --- a/scripts/openlookup-info.nse +++ b/scripts/openlookup-info.nse @@ -16,12 +16,20 @@ Parses and displays the banner information of an OpenLookup (network key-value s -- @output -- 5850/tcp open openlookup -- | openlookup-info: --- | sync port: 5850 --- | name: Paradise, Arizona --- | your address: 127.0.0.1:50162 --- | timestamp: 1305977167.52 (2011-05-21 11:26:07 UTC) --- | version: 2.7 --- |_ http port: 5851 +-- | sync port: 5850 +-- | name: Paradise, Arizona +-- | your address: 127.0.0.1:50162 +-- | timestamp: 2011-05-21T11:26:07 +-- | version: 2.7 +-- |_ http port: 5851 +-- +-- @xmloutput +-- 5850 +-- Paradise, Arizona +-- 127.0.0.1:50162 +-- 2011-05-21T11:26:07 +-- 2.7 +-- 5851 author = "Toni Ruottu" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" @@ -166,13 +174,7 @@ local function formattime(data) if not time then return end - local human = stdnse.format_timestamp(time) - return time .. " (" .. human .. ")" -end - -local function formatkey(key) - local parts = stdnse.strsplit("_", key) - return stdnse.strjoin(" ", parts) + return stdnse.format_timestamp(time) end local function formatvalue(key, nson) @@ -190,12 +192,6 @@ local function formatvalue(key, nson) return value end -local function format(rawkey, nson) - local key = formatkey(rawkey) - local value = formatvalue(rawkey, nson) - return key .. ": " .. value -end - function formatoptions(header) local msg = parsedict(header) if not msg then @@ -218,18 +214,7 @@ function formatoptions(header) if not rawopts then return {} end - local options = parsedict(rawopts) - if not options then - return - end - local formatted = {} - for key, nson in pairs(options) do - local tmp = format(key, nson) - if tmp then - table.insert(formatted, tmp) - end - end - return formatted + return parsedict(rawopts) end action = function(host, port) @@ -254,8 +239,6 @@ action = function(host, port) if #options < 1 then return end - local response = {} - table.insert(response, options) - return stdnse.format_output(true, response) + return options end diff --git a/scripts/rtsp-methods.nse b/scripts/rtsp-methods.nse index a371f0f66..9ed3a3ce7 100644 --- a/scripts/rtsp-methods.nse +++ b/scripts/rtsp-methods.nse @@ -16,6 +16,13 @@ Determines which methods are supported by the RTSP (real time streaming protocol -- | rtsp-methods: -- |_ DESCRIBE, SETUP, PLAY, TEARDOWN, OPTIONS -- +-- @xmloutput +-- DESCRIBE +-- SETUP +-- PLAY +-- TEARDOWN +-- OPTIONS +-- -- @args rtsp-methods.path the path to query, defaults to "*" which queries -- the server itself, rather than a specific url. -- @@ -44,6 +51,7 @@ action = function(host, port) status, response = helper:options(path) helper:close() if ( status ) then - return stdnse.format_output(true, response.headers['Public']) + local opts = response.headers['Public'] + return stdnse.strsplit(",%s*", opts), opts end end diff --git a/scripts/snmp-processes.nse b/scripts/snmp-processes.nse index 950f6a01b..c708a6630 100644 --- a/scripts/snmp-processes.nse +++ b/scripts/snmp-processes.nse @@ -13,25 +13,53 @@ Attempts to enumerate running processes through SNMP. -- nmap -sU -p 161 --script=snmp-processes -- @output -- | snmp-processes: --- | System Idle Process --- | PID: 1 --- | System --- | PID: 4 --- | smss.exe +-- | 1: +-- | Name: System Idle Process +-- | 4: +-- | Name: System +-- | 256: +-- | Name: smss.exe -- | Path: \SystemRoot\System32\ --- | PID: 256 --- | csrss.exe +-- | 308: +-- | Name: csrss.exe -- | Path: C:\WINDOWS\system32\ -- | Params: ObjectDirectory=\Windows SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserS --- | PID: 308 --- | winlogon.exe --- | PID: 332 --- | services.exe +-- | 332: +-- | Name: winlogon.exe +-- | 380: +-- | Name: services.exe -- | Path: C:\WINDOWS\system32\ --- | PID: 380 --- | lsass.exe --- | Path: C:\WINDOWS\system32\ --- |_ PID: 392 +-- | 392: +-- | Name: lsass.exe +-- |_ Path: C:\WINDOWS\system32\ +-- +-- @xmloutput +-- +-- System Idle Process +--
+-- +-- System +--
+-- +-- smss.exe +-- \SystemRoot\System32\ +--
+-- +-- csrss.exe +-- C:\WINDOWS\system32\ +-- ObjectDirectory=\Windows SharedSection=1024,3072,512 Windows=On SubSystemType=Windows ServerDll=basesrv,1 ServerDll=winsrv:UserS +--
+-- +-- winlogon.exe +--
+-- +-- services.exe +-- C:\WINDOWS\system32\ +--
+-- +-- lsass.exe +-- C:\WINDOWS\system32\ +--
author = "Patrik Karlsson" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" @@ -73,36 +101,35 @@ function process_answer( tbl ) local swrun_pid = "1.3.6.1.2.1.25.4.2.1.1" local swrun_path = "1.3.6.1.2.1.25.4.2.1.4" local swrun_params = "1.3.6.1.2.1.25.4.2.1.5" - local new_tbl = {} + local new_tbl = stdnse.output_table() for _, v in ipairs( tbl ) do - if ( v.oid:match("^" .. swrun_name) ) then - local item = {} - local objid = v.oid:gsub( "^" .. swrun_name, swrun_path) - local value = get_value_from_table( tbl, objid ) - - if value and value:len() > 0 then - table.insert( item, ("Path: %s"):format( value ) ) - end - - objid = v.oid:gsub( "^" .. swrun_name, swrun_params) - value = get_value_from_table( tbl, objid ) - - if value and value:len() > 0 then - table.insert( item, ("Params: %s"):format( value ) ) - end - - objid = v.oid:gsub( "^" .. swrun_name, swrun_pid) - value = get_value_from_table( tbl, objid ) + if ( v.oid:match("^" .. swrun_pid) ) then + local item = stdnse.output_table() + local objid = v.oid:gsub( "^" .. swrun_pid, swrun_name) + local value = get_value_from_table( tbl, objid ) if value then - table.insert( item, ("PID: %s"):format( value ) ) + item["Name"] = value end - item.name = v.value - table.insert( item, value ) - table.insert( new_tbl, item ) + objid = v.oid:gsub( "^" .. swrun_pid, swrun_path) + value = get_value_from_table( tbl, objid ) + + if value and value:len() > 0 then + item["Path"] = value + end + + objid = v.oid:gsub( "^" .. swrun_pid, swrun_params) + value = get_value_from_table( tbl, objid ) + + if value and value:len() > 0 then + item["Params"] = value + end + + -- key (PID) must be a string for output to work. + new_tbl[tostring(v.value)] = item end end @@ -135,6 +162,6 @@ action = function(host, port) nmap.set_port_state(host, port, "open") - return stdnse.format_output( true, shares ) + return shares end