From a134286227026686f478b7712c8cb2acf0b46b01 Mon Sep 17 00:00:00 2001 From: s0i37 Date: Thu, 10 Dec 2020 23:19:08 +0500 Subject: [PATCH 1/3] added script for getting network interfaces via NetBIOS --- nselib/netbios.lua | 2 +- scripts/netbios-interfaces.nse | 68 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 scripts/netbios-interfaces.nse diff --git a/nselib/netbios.lua b/nselib/netbios.lua index fabab8e5d0..b5ee7255c7 100644 --- a/nselib/netbios.lua +++ b/nselib/netbios.lua @@ -445,7 +445,7 @@ function nbquery(host, nbname, options) return false, "ERROR: Response contained no answers" end local dname = string.char(#resp.output.answers[1].dname) .. resp.output.answers[1].dname - table.insert( results, { peer = resp.peer, name = name_decode(dname) } ) + table.insert( results, { peer = resp.peer, name = name_decode(dname), data = resp.output.answers[1].data } ) end return true, results else diff --git a/scripts/netbios-interfaces.nse b/scripts/netbios-interfaces.nse new file mode 100644 index 0000000000..a83f9ec438 --- /dev/null +++ b/scripts/netbios-interfaces.nse @@ -0,0 +1,68 @@ +local netbios = require "netbios" +local nmap = require "nmap" +local string = require "string" +local tab = require "tab" + +description = [[ +Attempts to retrieve the target's network interfaces. +It is very useful for finding pathes to isolated networks. +]] + +--- +-- @usage +-- sudo nmap -sU --script netbios-interfaces.nse -p137 +-- +-- @output +-- Host script results: +-- | netbios-interfaces: +-- | 10.0.0.64 +-- |_12.0.0.1 + + + +author = {"Andrey Zhukov from USSC"} +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" + +categories = {"default", "discovery", "safe"} + + +hostrule = function(host) + + -- The following is an attempt to only run this script against hosts + -- that will probably respond to a UDP 137 probe. One might argue + -- that sending a single UDP packet and waiting for a response is no + -- big deal and that it should be done for every host. In that case + -- simply change this rule to always return true. + + local port_t135 = nmap.get_port_state(host, + {number=135, protocol="tcp"}) + local port_t139 = nmap.get_port_state(host, + {number=139, protocol="tcp"}) + local port_t445 = nmap.get_port_state(host, + {number=445, protocol="tcp"}) + local port_u137 = nmap.get_port_state(host, + {number=137, protocol="udp"}) + + return (port_t135 ~= nil and port_t135.state == "open") or + (port_t139 ~= nil and port_t139.state == "open") or + (port_t445 ~= nil and port_t445.state == "open") or + (port_u137 ~= nil and + (port_u137.state == "open" or + port_u137.state == "open|filtered")) +end + +get_ip = function(buf) + return tostring(string.byte(buf:sub(1,2))) .. "." .. tostring(string.byte(buf:sub(2,3))) .. "." .. tostring(string.byte(buf:sub(3,4))) .. "." .. tostring(string.byte(buf:sub(4,5))) +end + +action = function(host) + local outtab = tab.new(1) + local status, server_name = netbios.get_server_name(host) + local status, result = netbios.nbquery(host, server_name, { multiple = true }) + for k, v in ipairs(result) do + for i=1,string.len(v.data),6 do + tab.addrow(outtab, get_ip(v.data:sub(i+2,i+2+4))) + end + end + return "\n" .. tab.dump(outtab) +end From 69425b97bb4df206061ad31e8893d55e877cac3a Mon Sep 17 00:00:00 2001 From: s0i37 Date: Fri, 25 Dec 2020 00:27:06 +0500 Subject: [PATCH 2/3] changes in netbios-interfaces.nse --- scripts/netbios-interfaces.nse | 65 ++++++++++++++-------------------- scripts/script.db | 1 + 2 files changed, 28 insertions(+), 38 deletions(-) diff --git a/scripts/netbios-interfaces.nse b/scripts/netbios-interfaces.nse index a83f9ec438..bc9fd569d3 100644 --- a/scripts/netbios-interfaces.nse +++ b/scripts/netbios-interfaces.nse @@ -1,23 +1,28 @@ +local shortport = require "shortport" local netbios = require "netbios" -local nmap = require "nmap" local string = require "string" -local tab = require "tab" +local stdnse = require "stdnse" description = [[ -Attempts to retrieve the target's network interfaces. -It is very useful for finding pathes to isolated networks. +Attempts to retrieve via NetBIOS the target's network interfaces. +Additional network interfaces may reveal more information about target. +In particular, it is very useful for finding paths to non-routed networks if target has more than one NIC. ]] --- -- @usage --- sudo nmap -sU --script netbios-interfaces.nse -p137 +-- nmap -sU --script netbios-interfaces.nse -p 137 -- -- @output --- Host script results: +-- PORT STATE SERVICE +-- 137/udp open netbios-ns -- | netbios-interfaces: --- | 10.0.0.64 --- |_12.0.0.1 - +-- | hostname: NOTEBOOK-NB3 +-- | interfaces: +-- | 192.168.128.100 +-- | 172.24.80.1 +-- | 172.27.96.1 +-- MAC Address: 9C:7B:EF:AA:BB:CC (Hewlett Packard) author = {"Andrey Zhukov from USSC"} @@ -25,44 +30,28 @@ license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"default", "discovery", "safe"} - -hostrule = function(host) - - -- The following is an attempt to only run this script against hosts - -- that will probably respond to a UDP 137 probe. One might argue - -- that sending a single UDP packet and waiting for a response is no - -- big deal and that it should be done for every host. In that case - -- simply change this rule to always return true. - - local port_t135 = nmap.get_port_state(host, - {number=135, protocol="tcp"}) - local port_t139 = nmap.get_port_state(host, - {number=139, protocol="tcp"}) - local port_t445 = nmap.get_port_state(host, - {number=445, protocol="tcp"}) - local port_u137 = nmap.get_port_state(host, - {number=137, protocol="udp"}) - - return (port_t135 ~= nil and port_t135.state == "open") or - (port_t139 ~= nil and port_t139.state == "open") or - (port_t445 ~= nil and port_t445.state == "open") or - (port_u137 ~= nil and - (port_u137.state == "open" or - port_u137.state == "open|filtered")) -end +portrule = shortport.portnumber(137, "udp", {"open", "open|filtered"}) get_ip = function(buf) - return tostring(string.byte(buf:sub(1,2))) .. "." .. tostring(string.byte(buf:sub(2,3))) .. "." .. tostring(string.byte(buf:sub(3,4))) .. "." .. tostring(string.byte(buf:sub(4,5))) + return table.concat({buf:byte(1, 4)}, ".") end action = function(host) - local outtab = tab.new(1) + local output = stdnse.output_table() local status, server_name = netbios.get_server_name(host) + if(not(status)) then + return output, "Failed to get hostname" + end local status, result = netbios.nbquery(host, server_name, { multiple = true }) + if(not(status)) then + return output, "Failed to get remote network interfaces" + end + output.hostname = server_name + output.interfaces = {} for k, v in ipairs(result) do for i=1,string.len(v.data),6 do - tab.addrow(outtab, get_ip(v.data:sub(i+2,i+2+4))) + output.interfaces[#output.interfaces + 1] = get_ip(v.data:sub(i+2,i+2+4)) end end - return "\n" .. tab.dump(outtab) + return output, "" end diff --git a/scripts/script.db b/scripts/script.db index f46fe138c1..9b7e33d451 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -389,6 +389,7 @@ Entry { filename = "ndmp-fs-info.nse", categories = { "discovery", "safe", } } Entry { filename = "ndmp-version.nse", categories = { "version", } } Entry { filename = "nessus-brute.nse", categories = { "brute", "intrusive", } } Entry { filename = "nessus-xmlrpc-brute.nse", categories = { "brute", "intrusive", } } +Entry { filename = "netbios-interfaces.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "netbus-auth-bypass.nse", categories = { "auth", "safe", "vuln", } } Entry { filename = "netbus-brute.nse", categories = { "brute", "intrusive", } } Entry { filename = "netbus-info.nse", categories = { "default", "discovery", "safe", } } From de71f35075fe0d5973722e942734e20c87b0f719 Mon Sep 17 00:00:00 2001 From: s0i37 Date: Tue, 29 Dec 2020 23:50:33 +0500 Subject: [PATCH 3/3] changes in netbios-interfaces.nse and nselib/netbios.lua --- nselib/netbios.lua | 2 +- scripts/netbios-interfaces.nse | 24 ++++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/nselib/netbios.lua b/nselib/netbios.lua index b5ee7255c7..47b4d4d98a 100644 --- a/nselib/netbios.lua +++ b/nselib/netbios.lua @@ -450,7 +450,7 @@ function nbquery(host, nbname, options) return true, results else local dname = string.char(#response.answers[1].dname) .. response.answers[1].dname - return true, { { peer = host.ip, name = name_decode(dname) } } + return true, { { peer = host.ip, name = name_decode(dname), data = response.answers[1].data } } end end diff --git a/scripts/netbios-interfaces.nse b/scripts/netbios-interfaces.nse index bc9fd569d3..2b8acb895d 100644 --- a/scripts/netbios-interfaces.nse +++ b/scripts/netbios-interfaces.nse @@ -2,6 +2,7 @@ local shortport = require "shortport" local netbios = require "netbios" local string = require "string" local stdnse = require "stdnse" +local table = require "table" description = [[ Attempts to retrieve via NetBIOS the target's network interfaces. @@ -19,10 +20,17 @@ In particular, it is very useful for finding paths to non-routed networks if tar -- | netbios-interfaces: -- | hostname: NOTEBOOK-NB3 -- | interfaces: --- | 192.168.128.100 +-- | 10.5.4.89 +-- | 192.168.56.1 -- | 172.24.80.1 --- | 172.27.96.1 -- MAC Address: 9C:7B:EF:AA:BB:CC (Hewlett Packard) +-- +-- @xmloutput +-- +-- 10.5.4.89 +-- 192.168.56.1 +-- 172.24.80.1 +--
author = {"Andrey Zhukov from USSC"} @@ -30,7 +38,7 @@ license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"default", "discovery", "safe"} -portrule = shortport.portnumber(137, "udp", {"open", "open|filtered"}) +portrule = shortport.portnumber(137, "udp") get_ip = function(buf) return table.concat({buf:byte(1, 4)}, ".") @@ -40,18 +48,18 @@ action = function(host) local output = stdnse.output_table() local status, server_name = netbios.get_server_name(host) if(not(status)) then - return output, "Failed to get hostname" + return stdnse.format_output(false, "Failed to get NetBIOS name of the target") end - local status, result = netbios.nbquery(host, server_name, { multiple = true }) + local status, result = netbios.nbquery(host, server_name) if(not(status)) then - return output, "Failed to get remote network interfaces" + return stdnse.format_output(false, "Failed to get remote network interfaces") end output.hostname = server_name output.interfaces = {} for k, v in ipairs(result) do for i=1,string.len(v.data),6 do - output.interfaces[#output.interfaces + 1] = get_ip(v.data:sub(i+2,i+2+4)) + output.interfaces[#output.interfaces + 1] = get_ip(v.data:sub(i+2,i+2+4-1)) end end - return output, "" + return output end