diff --git a/scripts/nbstat.nse b/scripts/nbstat.nse index c943726..e16efda 100644 --- a/scripts/nbstat.nse +++ b/scripts/nbstat.nse @@ -4,6 +4,7 @@ local nmap = require "nmap" local stdnse = require "stdnse" local string = require "string" local table = require "table" +local format = require "format" description = [[ Attempts to retrieve the target's NetBIOS names and MAC address. @@ -19,18 +20,76 @@ owns. -- -- @output -- Host script results: --- |_ nbstat: NetBIOS name: WINDOWS2003, NetBIOS user: , NetBIOS MAC: 00:0c:29:c6:da:f5 (VMware) +-- | nbstat: +-- | name: WINDOWS2003 +-- | user: +-- |_MAC: 00:0c:29:c6:da:f5 (VMware) -- -- Host script results: --- | nbstat: --- | | NetBIOS name: WINDOWS2003, NetBIOS user: , NetBIOS MAC: 00:0c:29:c6:da:f5 (VMware) --- | | Names --- | | | WINDOWS2003<00> Flags: --- | | | WINDOWS2003<20> Flags: --- | | | SKULLSECURITY<00> Flags: --- | | | SKULLSECURITY<1e> Flags: --- | | | SKULLSECURITY<1d> Flags: --- |_ |_ |_ \x01\x02__MSBROWSE__\x02<01> Flags: +-- | nbstat: +-- | name: WINDOWS2003 +-- | user: +-- | MAC: 00:0c:29:c6:da:f5 (VMware) +-- | names: +-- | WINDOWS2003<00> Flags: +-- | WINDOWS2003<20> Flags: +-- | SKULLSECURITY<00> Flags: +-- | SKULLSECURITY<1e> Flags: +-- | SKULLSECURITY<1d> Flags: +-- |_ \x01\x02__MSBROWSE__\x02<01> Flags: +-- +-- +--@xmloutput +-- author = "Brandon Enright, Ron Bowes" @@ -73,8 +132,8 @@ action = function(host) local status local names, statistics local server_name, user_name - local mac, prefix, manuf - local response = {} + local mac = {} + local prefix local catch = function() return end local try = nmap.new_try(catch) @@ -106,21 +165,22 @@ action = function(host) if(#statistics >= 6) then -- MAC prefixes are matched on the first three bytes, all uppercase prefix = string.upper(string.format("%02x%02x%02x", statistics:byte(1), statistics:byte(2), statistics:byte(3))) - manuf = mac_prefixes[prefix] - if manuf == nil then - manuf = "unknown" - end - host.registry['nbstat'] = { - server_name = server_name, - mac = ("%02x:%02x:%02x:%02x:%02x:%02x"):format( statistics:byte(1), statistics:byte(2), statistics:byte(3), statistics:byte(4), statistics:byte(5), statistics:byte(6) ) - } - mac = string.format("%02x:%02x:%02x:%02x:%02x:%02x (%s)", statistics:byte(1), statistics:byte(2), statistics:byte(3), statistics:byte(4), statistics:byte(5), statistics:byte(6), manuf) + mac.manufacturer = mac_prefixes[prefix] + mac.address = string.format("%02x:%02x:%02x:%02x:%02x:%02x", + statistics:byte(1), statistics:byte(2), statistics:byte(3), + statistics:byte(4), statistics:byte(5), statistics:byte(6) + ) -- Samba doesn't set the Mac address, and nmap-mac-prefixes shows that as Xerox - if(mac == "00:00:00:00:00:00 (Xerox)") then - mac = "" - end + if(mac.address == "00:00:00:00:00:00") then + mac.address = "" + mac.manufacturer = nil + end + host.registry['nbstat'] = { + server_name = server_name, + mac = mac.address + } else - mac = "" + mac.address = "" end -- Check if we actually got a username @@ -129,39 +189,36 @@ action = function(host) end + format.set_tostring(mac, function(m) + return string.format("%s (%s)", m.address, m.manufacturer or "unknown") + end) + local response = stdnse.output_table() + response.name = server_name + response.user = user_name + response.MAC = mac -- If verbosity is set, dump the whole list of names if(nmap.verbosity() >= 1) then - table.insert(response, string.format("NetBIOS name: %s, NetBIOS user: %s, NetBIOS MAC: %s", server_name, user_name, mac)) - - local names_output = {} - names_output['name'] = "Names" - for i = 1, #names, 1 do - local padding = string.rep(" ", 17 - #names[i]['name']) - local flags_str = netbios.flags_to_string(names[i]['flags']) - table.insert(names_output, string.format("%s<%02x>%sFlags: %s", names[i]['name'], names[i]['suffix'], padding, flags_str)) + local function namestring(name) + local flags_str = netbios.flags_to_string(name['flags']) + local name_str = string.format("%s<%02x>", name.name, name.suffix) + return string.format("%-20s Flags: %s", name_str, flags_str) + end + + for _,v in ipairs(names) do + format.set_tostring(v, namestring) end - table.insert(response, names_output) + response["names"] = names -- If super verbosity is set, print out the full statistics if(nmap.verbosity() >= 2) then - local statistics_output = {} - local statistics_string = '' - statistics_output['name'] = "Statistics" - for i = 1, #statistics, 1 do - statistics_string = statistics_string .. string.format("%02x ", statistics:byte(i)) - if(i ~= #statistics and ((i) % 16) == 0) then - table.insert(statistics_output, statistics_string) - statistics_string = '' - end + local stats = {} + for i= 1, #statistics, 16 do + stats[#stats+1] = stdnse.tohex(statistics:sub(i,i+15), {separator=" "}) end - table.insert(statistics_output, statistics_string) - table.insert(response, statistics_output) + response.statistics = stats end - - return stdnse.format_output(true, response) - else - return string.format("NetBIOS name: %s, NetBIOS user: %s, NetBIOS MAC: %s", server_name, user_name, mac) end + return response end