mirror of
https://github.com/nmap/nmap.git
synced 2026-01-24 23:29:04 +00:00
o [NSE] Added two new scripts broadcast-netbios-master-browser and smb-mbenum:
- broadcast-netbios-master-browser attempts to discover master browsers in
the broadcast domain
- smb-mbenum lists servers registered with the master browser
[Patrik]
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o [NSE] Added two new scripts broadcast-netbios-master-browser and smb-mbenum:
|
||||
- broadcast-netbios-master-browser attempts to discover master browsers in
|
||||
the broadcast domain
|
||||
- smb-mbenum lists servers registered with the master browser
|
||||
[Patrik]
|
||||
|
||||
o [NSE] Added credential storage library (creds.lua) and modified the brute
|
||||
library and scripts to make use of it. [Patrik]
|
||||
|
||||
|
||||
@@ -239,8 +239,10 @@ end
|
||||
-- * <code>tries</code>: How often should <code>query</code> try to contact another server (for non-recursive queries).
|
||||
-- * <code>retAll</code>: Return all answers, not just the first.
|
||||
-- * <code>retPkt</code>: Return the packet instead of using the answer-fetching mechanism.
|
||||
-- * <code>norecurse</code> If true, do not set the recursion (RD) flag.
|
||||
-- * <code>multiple</code> If true, expects multiple hosts to respond to multicast request
|
||||
-- * <code>norecurse</code>: If true, do not set the recursion (RD) flag.
|
||||
-- * <code>multiple</code>: If true, expects multiple hosts to respond to multicast request
|
||||
-- * <code>flags</code>: numeric value to set flags in the DNS query to a specific value
|
||||
-- * <code>id</code>: numeric value to use for the DNS transaction id
|
||||
-- @return <code>true</code> if a dns response was received and contained an answer of the requested type,
|
||||
-- or the decoded dns response was requested (retPkt) and is being returned - or <code>false</code> otherwise.
|
||||
-- @return String answer of the requested type, table of answers or a String error message of one of the following:
|
||||
@@ -284,6 +286,9 @@ function query(dname, options)
|
||||
addOPT(pkt, {DO = true})
|
||||
end
|
||||
|
||||
if ( options.flags ) then pkt.flags.raw = options.flags end
|
||||
if ( options.id ) then pkt.id = options.id end
|
||||
|
||||
local data = encode(pkt)
|
||||
|
||||
local status, response = sendPackets(data, host, port, options.timeout, options.sendCount, options.multiple)
|
||||
@@ -824,7 +829,12 @@ function encode(pkt)
|
||||
aorulen = #pkt.updates
|
||||
end
|
||||
|
||||
local encStr = bin.pack(">SBS4", pkt.id, encFlags, qorzlen, aorplen, aorulen, #pkt.additional) .. data .. additional
|
||||
local encStr
|
||||
if ( pkt.flags.raw ) then
|
||||
encStr = bin.pack(">SSS4", pkt.id, pkt.flags.raw, qorzlen, aorplen, aorulen, #pkt.additional) .. data .. additional
|
||||
else
|
||||
encStr = bin.pack(">SBS4", pkt.id, encFlags, qorzlen, aorplen, aorulen, #pkt.additional) .. data .. additional
|
||||
end
|
||||
return encStr
|
||||
end
|
||||
|
||||
|
||||
@@ -397,59 +397,86 @@ function call_function(smbstate, opnum, arguments)
|
||||
end
|
||||
|
||||
---LANMAN API calls use different conventions than everything else, so make a separate function for them.
|
||||
function call_lanmanapi(smbstate, opnum, server_type)
|
||||
function call_lanmanapi(smbstate, opnum, paramdesc, datadesc, data)
|
||||
local status, result
|
||||
local parameters = ""
|
||||
local data
|
||||
local convert, entry_count, available_entries
|
||||
local entries = {}
|
||||
local pos
|
||||
|
||||
parameters = bin.pack("<SzzSSI",
|
||||
parameters = bin.pack("<SzzA",
|
||||
opnum,
|
||||
"WrLehDO", -- Parameter Descriptor
|
||||
"B16", -- Return Descriptor
|
||||
0, -- Detail level
|
||||
14724, -- Return buffer size
|
||||
server_type -- Server type
|
||||
paramdesc, -- Parameter Descriptor
|
||||
datadesc, -- Return Descriptor
|
||||
data
|
||||
)
|
||||
|
||||
stdnse.print_debug(1, "MSRPC: Sending Browser Service request")
|
||||
status, result = smb.send_transaction_named_pipe(smbstate, parameters, nil, "\\PIPE\\LANMAN", true)
|
||||
|
||||
if(not(status)) then
|
||||
return false, "Couldn't call LANMAN API: " .. result
|
||||
end
|
||||
|
||||
parameters = result.parameters
|
||||
data = result.data
|
||||
return true, result
|
||||
end
|
||||
|
||||
--- Queries the (master) browser service for a list of server that it manages
|
||||
--
|
||||
-- @param smbstate The SMB state table (after <code>bind</code> has been called).
|
||||
-- @param domain (optional) string containing the domain name to query
|
||||
-- @param server_type number containing a server bit mask to use to filter responses
|
||||
-- @param detail_level number containing either 0 or 1
|
||||
function rap_netserverenum2(smbstate, domain, server_type, detail_level)
|
||||
|
||||
local NETSERVERENUM2 = 0x0068
|
||||
local paramdesc = (domain and "WrLehDz" or "WrLehDO")
|
||||
assert( detail_level > 0 and detail_level < 2, "detail_level must be either 0 or 1")
|
||||
local datadesc = ( detail_level == 0 and "B16" or "B16BBDz")
|
||||
local data = bin.pack("<SSIA", detail_level,
|
||||
14724,
|
||||
server_type,
|
||||
(domain or "")
|
||||
)
|
||||
|
||||
local status, result = call_lanmanapi(smbstate, NETSERVERENUM2, paramdesc, datadesc, data )
|
||||
|
||||
if ( not(status) ) then
|
||||
return false, "MSRPC: NetServerEnum2 call failed"
|
||||
end
|
||||
|
||||
local parameters = result.parameters
|
||||
local data = result.data
|
||||
|
||||
stdnse.print_debug(1, "MSRPC: Parsing Browser Service response")
|
||||
pos, status, convert, entry_count, available_entries = bin.unpack("<SSSS", parameters)
|
||||
local pos, status, convert, entry_count, available_entries = bin.unpack("<SSSS", parameters)
|
||||
|
||||
if(status ~= 0) then
|
||||
return false, string.format("Call to Browser Service failed with status = %d", status)
|
||||
end
|
||||
|
||||
stdnse.print_debug(1, "MSRPC: Browser service returned %d entries", entry_count)
|
||||
|
||||
|
||||
|
||||
local pos = 1
|
||||
local entry
|
||||
local entries = {}
|
||||
|
||||
for i = 1, entry_count, 1 do
|
||||
-- Read the string
|
||||
pos, entry = bin.unpack("<z", data, pos)
|
||||
stdnse.print_debug(1, "MSRPC: Found name: %s", entry)
|
||||
local server = {}
|
||||
|
||||
pos, server.name = bin.unpack("<z", data, pos)
|
||||
stdnse.print_debug(1, "MSRPC: Found name: %s", server.name)
|
||||
|
||||
-- pos needs to be rounded to the next even multiple of 16
|
||||
while(((pos - 1) % 16) ~= 0) do
|
||||
pos = pos + 1
|
||||
end
|
||||
pos = pos + ( 16 - (#server.name % 16) ) - 1
|
||||
|
||||
-- Make sure we didn't hit the end of the packet
|
||||
if(not(entry)) then
|
||||
return false, "Call to browser service didn't receive enough data"
|
||||
end
|
||||
if ( detail_level > 0 ) then
|
||||
local comment_offset, _
|
||||
server.version = {}
|
||||
pos, server.version.major, server.version.minor,
|
||||
server.type, comment_offset, _ = bin.unpack("<CCISS", data, pos)
|
||||
|
||||
-- Insert the result
|
||||
table.insert(entries, entry)
|
||||
_, server.comment = bin.unpack("<z", data, (comment_offset - convert + 1))
|
||||
end
|
||||
table.insert(entries, server)
|
||||
end
|
||||
|
||||
return true, entries
|
||||
|
||||
@@ -10,6 +10,12 @@ module(... or "netbios", package.seeall)
|
||||
require 'bit'
|
||||
require 'bin'
|
||||
require 'stdnse'
|
||||
require 'dns'
|
||||
|
||||
types = {
|
||||
NB = 32,
|
||||
NBSTAT = 33,
|
||||
}
|
||||
|
||||
--- Encode a NetBIOS name for transport. Most packets that use the NetBIOS name
|
||||
-- require this encoding to happen first. It takes a name containing any possible
|
||||
@@ -369,6 +375,41 @@ function do_nbstat(host)
|
||||
end
|
||||
end
|
||||
|
||||
function nbquery(host, nbname, options)
|
||||
-- override any options or set the default values
|
||||
local options = options or {}
|
||||
options.port = options.port or 137
|
||||
options.retPkt = options.retPkt or true
|
||||
options.dtype = options.dtype or types.NB
|
||||
options.host = host.ip
|
||||
options.flags = options.flags or ( options.multiple and 0x0110 )
|
||||
options.id = math.random(0xFFFF)
|
||||
|
||||
-- encode and chop off the leading byte, as the dns library takes care of
|
||||
-- specifying the length
|
||||
local encoded_name = name_encode(nbname):sub(2)
|
||||
|
||||
local status, response = dns.query( encoded_name, options )
|
||||
if ( not(status) ) then return false, "ERROR: nbquery failed" end
|
||||
|
||||
local results = {}
|
||||
-- discard any additional responses
|
||||
if ( options.multiple and #response > 0 ) then
|
||||
for _, resp in ipairs(response) do
|
||||
assert( options.id == resp.output.id, "Received packet with invalid transaction ID" )
|
||||
if ( not(resp.output.answers) or #resp.output.answers < 1 ) then
|
||||
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) } )
|
||||
end
|
||||
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) } }
|
||||
end
|
||||
end
|
||||
|
||||
---Convert the 16-bit flags field to a string.
|
||||
--@param flags The 16-bit flags field
|
||||
--@return A string representing the flags
|
||||
|
||||
65
scripts/broadcast-netbios-master-browser.nse
Normal file
65
scripts/broadcast-netbios-master-browser.nse
Normal file
@@ -0,0 +1,65 @@
|
||||
description = [[
|
||||
Attempts to discover master browsers and the domains they manage
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap --script=broadcast-netbios-master-browser
|
||||
--
|
||||
-- @output
|
||||
-- | broadcast-netbios-master-browser:
|
||||
-- | ip server domain
|
||||
-- |_10.0.200.156 WIN2K3-EPI-1 WORKGROUP
|
||||
--
|
||||
|
||||
-- Version 0.1
|
||||
-- Created 06/14/2011 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
|
||||
author = "Patrik Karlsson"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"broadcast", "safe"}
|
||||
|
||||
require 'netbios'
|
||||
require 'tab'
|
||||
require 'bit'
|
||||
|
||||
prerule = function() return true end
|
||||
|
||||
local function isGroup(flags) return ( bit.band(flags, 0x8000) == 0x8000 ) end
|
||||
|
||||
action = function()
|
||||
|
||||
-- NBNS only works over ipv4
|
||||
if ( nmap.address_family() == "inet6") then return end
|
||||
|
||||
local MASTER_BROWSER_DOMAIN = 0x1D
|
||||
local STD_WORKSTATION_SERVICE = 0x00
|
||||
local NBNAME = "\1\2__MSBROWSE__\2\1"
|
||||
local BROADCAST_ADDR = "255.255.255.255"
|
||||
|
||||
local status, result = netbios.nbquery( { ip = BROADCAST_ADDR }, NBNAME, { multiple = true })
|
||||
if ( not(status) ) then return end
|
||||
|
||||
local outtab = tab.new(3)
|
||||
tab.addrow(outtab, 'ip', 'server', 'domain')
|
||||
|
||||
for _, v in ipairs(result) do
|
||||
local status, names, _ = netbios.do_nbstat(v.peer)
|
||||
local srv_name, domain_name
|
||||
if (status) then
|
||||
for _, item in ipairs(names) do
|
||||
if ( item.suffix == MASTER_BROWSER_DOMAIN and not(isGroup(item.flags)) ) then
|
||||
domain_name = item.name
|
||||
elseif ( item.suffix == STD_WORKSTATION_SERVICE and not(isGroup(item.flags)) ) then
|
||||
srv_name = item.name
|
||||
end
|
||||
end
|
||||
if ( srv_name and domain_name ) then
|
||||
tab.addrow(outtab, v.peer, srv_name, domain_name)
|
||||
else
|
||||
stdnse.print_debug(3, "No server name or domain name was found")
|
||||
end
|
||||
end
|
||||
end
|
||||
return "\n" .. tab.dump(outtab)
|
||||
end
|
||||
@@ -13,6 +13,7 @@ Entry { filename = "broadcast-avahi-dos.nse", categories = { "broadcast", "dos",
|
||||
Entry { filename = "broadcast-dns-service-discovery.nse", categories = { "broadcast", "safe", } }
|
||||
Entry { filename = "broadcast-dropbox-listener.nse", categories = { "broadcast", "safe", } }
|
||||
Entry { filename = "broadcast-ms-sql-discover.nse", categories = { "broadcast", "discovery", "safe", } }
|
||||
Entry { filename = "broadcast-netbios-master-browser.nse", categories = { "broadcast", "safe", } }
|
||||
Entry { filename = "broadcast-novell-locate.nse", categories = { "broadcast", "safe", } }
|
||||
Entry { filename = "broadcast-upnp-info.nse", categories = { "broadcast", "safe", } }
|
||||
Entry { filename = "broadcast-wsdd-discover.nse", categories = { "broadcast", "safe", } }
|
||||
@@ -161,6 +162,7 @@ Entry { filename = "smb-enum-sessions.nse", categories = { "discovery", "intrusi
|
||||
Entry { filename = "smb-enum-shares.nse", categories = { "discovery", "intrusive", } }
|
||||
Entry { filename = "smb-enum-users.nse", categories = { "discovery", "intrusive", } }
|
||||
Entry { filename = "smb-flood.nse", categories = { "dos", "intrusive", } }
|
||||
Entry { filename = "smb-mbenum.nse", categories = { "discovery", "safe", } }
|
||||
Entry { filename = "smb-os-discovery.nse", categories = { "default", "discovery", "safe", } }
|
||||
Entry { filename = "smb-psexec.nse", categories = { "intrusive", } }
|
||||
Entry { filename = "smb-security-mode.nse", categories = { "discovery", "safe", } }
|
||||
|
||||
230
scripts/smb-mbenum.nse
Normal file
230
scripts/smb-mbenum.nse
Normal file
@@ -0,0 +1,230 @@
|
||||
description=[[
|
||||
Queries information managed by the Windows Master Browser.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 445 <host> --script smb-mbenum
|
||||
--
|
||||
-- @output
|
||||
-- | smb-mbenum:
|
||||
-- | Backup Browser
|
||||
-- | WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
|
||||
-- | DFS Root
|
||||
-- | WIN2K3-1 5.2 MSSQL Server backend
|
||||
-- | WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
|
||||
-- | Master Browser
|
||||
-- | WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
|
||||
-- | SQL Server
|
||||
-- | WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
|
||||
-- | Server
|
||||
-- | TIME-CAPSULE 4.32 Time Capsule
|
||||
-- | WIN2K3-1 5.2 MSSQL Server backend
|
||||
-- | WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
|
||||
-- | Server service
|
||||
-- | TIME-CAPSULE 4.32 Time Capsule
|
||||
-- | WIN2K3-1 5.2 MSSQL Server backend
|
||||
-- | WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
|
||||
-- | Windows NT/2000/XP/2003 server
|
||||
-- | TIME-CAPSULE 4.32 Time Capsule
|
||||
-- | WIN2K3-1 5.2 MSSQL Server backend
|
||||
-- | WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
|
||||
-- | Workstation
|
||||
-- | TIME-CAPSULE 4.32 Time Capsule
|
||||
-- | WIN2K3-1 5.2 MSSQL Server backend
|
||||
-- |_ WIN2K3-EPI-1 5.2 EPiServer 2003 frontend server
|
||||
--
|
||||
-- @args smb-mbenum.format (optional) if set, changes the format of the result
|
||||
-- returned by the script. There are three possible formats:
|
||||
-- 1. Ordered by type horizontally
|
||||
-- 2. Ordered by type vertically
|
||||
-- 3. Ordered by type vertically with details (default)
|
||||
--
|
||||
-- @args smb-mbenum.filter (optional) if set, queries the browser for a
|
||||
-- specific type of server (@see ServerTypes)
|
||||
--
|
||||
-- @args smb-mbenum.domain (optional) if not specified, lists the domain of the queried browser
|
||||
--
|
||||
|
||||
--
|
||||
-- Version 0.1
|
||||
-- Created 06/11/2011 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
|
||||
author = "Patrik Karlsson"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"discovery", "safe"}
|
||||
|
||||
require 'smb'
|
||||
require 'msrpc'
|
||||
require 'shortport'
|
||||
require 'tab'
|
||||
|
||||
hostrule = function(host) return smb.get_port(host) ~= nil end
|
||||
prerule = function() return true end
|
||||
|
||||
local function log(msg) stdnse.print_debug(3, msg) end
|
||||
|
||||
ServerTypes = {
|
||||
SV_TYPE_WORKSTATION = 0x00000001,
|
||||
SV_TYPE_SERVER = 0x00000002,
|
||||
SV_TYPE_SQLSERVER = 0x00000004,
|
||||
SV_TYPE_DOMAIN_CTRL = 0x00000008,
|
||||
SV_TYPE_DOMAIN_BAKCTRL = 0x00000010,
|
||||
SV_TYPE_TIME_SOURCE = 0x00000020,
|
||||
SV_TYPE_AFP = 0x00000040,
|
||||
SV_TYPE_NOVELL = 0x00000080,
|
||||
SV_TYPE_DOMAIN_MEMBER = 0x00000100,
|
||||
SV_TYPE_PRINTQ_SERVER = 0x00000200,
|
||||
SV_TYPE_DIALIN_SERVER = 0x00000400,
|
||||
SV_TYPE_SERVER_UNIX = 0x00000800,
|
||||
SV_TYPE_NT = 0x00001000,
|
||||
SV_TYPE_WFW = 0x00002000,
|
||||
SV_TYPE_SERVER_MFPN = 0x00004000,
|
||||
SV_TYPE_SERVER_NT = 0x00008000,
|
||||
SV_TYPE_POTENTIAL_BROWSER = 0x00010000,
|
||||
SV_TYPE_BACKUP_BROWSER = 0x00020000,
|
||||
SV_TYPE_MASTER_BROWSER = 0x00040000,
|
||||
SV_TYPE_DOMAIN_MASTER = 0x00080000,
|
||||
SV_TYPE_WINDOWS = 0x00400000,
|
||||
SV_TYPE_DFS = 0x00800000,
|
||||
SV_TYPE_CLUSTER_NT = 0x01000000,
|
||||
SV_TYPE_TERMINALSERVER = 0x02000000,
|
||||
SV_TYPE_CLUSTER_VS_NT = 0x04000000,
|
||||
SV_TYPE_DCE = 0x10000000,
|
||||
SV_TYPE_ALTERNATE_XPORT = 0x20000000,
|
||||
SV_TYPE_LOCAL_LIST_ONLY = 0x40000000,
|
||||
SV_TYPE_DOMAIN_ENUM = 0x80000000,
|
||||
SV_TYPE_ALL = 0xFFFFFFFF
|
||||
}
|
||||
|
||||
TypeNames = {
|
||||
SV_TYPE_WORKSTATION = { long = "Workstation", short = "WKS" },
|
||||
SV_TYPE_SERVER = { long = "Server service", short = "SRVSVC" },
|
||||
SV_TYPE_SQLSERVER = { long = "SQL Server", short = "MSSQL" },
|
||||
SV_TYPE_DOMAIN_CTRL = { long = "Domain Controller", short = "DC" },
|
||||
SV_TYPE_DOMAIN_BAKCTRL = { long = "Backup Domain Controller", short = "BDC" },
|
||||
SV_TYPE_TIME_SOURCE = { long = "Time Source", short = "TIME" },
|
||||
SV_TYPE_AFP = { long = "Apple File Protocol Server", short = "AFP" },
|
||||
SV_TYPE_NOVELL = { long = "Novell Server", short = "NOVELL" },
|
||||
SV_TYPE_DOMAIN_MEMBER = { long = "LAN Manager Domain Member", short = "MEMB" },
|
||||
SV_TYPE_PRINTQ_SERVER = { long = "Print server", short = "PRINT" },
|
||||
SV_TYPE_DIALIN_SERVER = { long = "Dial-in server", short = "DIALIN" },
|
||||
SV_TYPE_SERVER_UNIX = { long = "Unix server", short = "UNIX" },
|
||||
SV_TYPE_NT = { long = "Windows NT/2000/XP/2003 server", short = "NT" },
|
||||
SV_TYPE_WFW = { long = "Windows for workgroups", short = "WFW" },
|
||||
SV_TYPE_SERVER_MFPN = { long = "Microsoft File and Print for Netware", short="MFPN" },
|
||||
SV_TYPE_SERVER_NT = { long = "Server", short = "SRV" },
|
||||
SV_TYPE_POTENTIAL_BROWSER = { long = "Potential Browser", short = "POTBRWS" },
|
||||
SV_TYPE_BACKUP_BROWSER = { long = "Backup Browser", short = "BCKBRWS"},
|
||||
SV_TYPE_MASTER_BROWSER = { long = "Master Browser", short = "MBRWS"},
|
||||
SV_TYPE_DOMAIN_MASTER = { long = "Domain Master Browser", short = "DOMBRWS"},
|
||||
SV_TYPE_WINDOWS = { long = "Windows 95/98/ME", short="WIN95"},
|
||||
SV_TYPE_DFS = { long = "DFS Root", short = "DFS"},
|
||||
}
|
||||
|
||||
OutputFormat = {
|
||||
BY_TYPE_H = 1,
|
||||
BY_TYPE_V = 2,
|
||||
BY_TYPE_V_DETAILED = 3,
|
||||
}
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local status, smbstate = smb.start(host)
|
||||
local err, entries
|
||||
local path = ("\\\\%s\\IPC$"):format(host.ip)
|
||||
local detail_level = 1
|
||||
local format = stdnse.get_script_args("smb-mbenum.format") or OutputFormat.BY_TYPE_V_DETAILED
|
||||
local filter = stdnse.get_script_args("smb-mbenum.filter") or ServerTypes.SV_TYPE_ALL
|
||||
local domain = stdnse.get_script_args("smb-mbenum.domain")
|
||||
|
||||
filter = tonumber(filter) or ServerTypes[filter]
|
||||
format = tonumber(format)
|
||||
|
||||
if ( not(filter) ) then
|
||||
return "\n The argument smb-mbenum.filter contained an invalid value."
|
||||
end
|
||||
|
||||
if ( not(format) ) then
|
||||
return "\n The argument smb-mbenum.format contained an invalid value."
|
||||
end
|
||||
|
||||
status, err = smb.negotiate_protocol(smbstate, {})
|
||||
if ( not(status) ) then
|
||||
log("ERROR: smb.negotiate_protocol failed")
|
||||
return "\n ERROR: Failed to connect to browser service"
|
||||
end
|
||||
|
||||
status, err = smb.start_session(smbstate, {})
|
||||
if ( not(status) ) then
|
||||
log("ERROR: smb.negotiate_protocol failed")
|
||||
return "\n ERROR: Failed to connect to browser service"
|
||||
end
|
||||
|
||||
status, err = smb.tree_connect(smbstate, path, {})
|
||||
if ( not(status) ) then
|
||||
log("ERROR: smb.negotiate_protocol failed")
|
||||
return "\n ERROR: Failed to connect to browser service"
|
||||
end
|
||||
|
||||
status, entries = msrpc.rap_netserverenum2(smbstate, domain, filter, detail_level)
|
||||
if ( not(status) ) then
|
||||
log("ERROR: msrpc.call_lanmanapi failed")
|
||||
return "\n ERROR: Failed to retrieve list of servers from browser service"
|
||||
end
|
||||
|
||||
status, err = smb.tree_disconnect(smbstate)
|
||||
if ( not(status) ) then log("ERROR: smb.tree_disconnect failed") end
|
||||
|
||||
status, err = smb.logoff(smbstate)
|
||||
if ( not(status) ) then log("ERROR: smb.logoff failed") end
|
||||
|
||||
status, err = smb.stop(smbstate)
|
||||
if ( not(status) ) then log("ERROR: smb.stop failed") end
|
||||
|
||||
local results, output = {}, {}
|
||||
for k, _ in pairs(ServerTypes) do
|
||||
for _, server in ipairs(entries) do
|
||||
if ( bit.band(server.type,ServerTypes[k]) == ServerTypes[k] ) then
|
||||
results[TypeNames[k].long] = results[TypeNames[k].long] or {}
|
||||
if ( format == OutputFormat.BY_TYPE_V_DETAILED ) then
|
||||
table.insert(results[TypeNames[k].long], server)
|
||||
else
|
||||
table.insert(results[TypeNames[k].long], server.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ( format == OutputFormat.BY_TYPE_H ) then
|
||||
for k, v in pairs(results) do
|
||||
local row = ("%s: %s"):format( k, stdnse.strjoin(",", v) )
|
||||
table.insert(output, row)
|
||||
end
|
||||
table.sort(output)
|
||||
elseif( format == OutputFormat.BY_TYPE_V ) then
|
||||
for k, v in pairs(results) do
|
||||
v.name = k
|
||||
table.insert(output, v)
|
||||
end
|
||||
table.sort(output, function(a,b) return a.name < b.name end)
|
||||
elseif( format == OutputFormat.BY_TYPE_V_DETAILED ) then
|
||||
for k, v in pairs(results) do
|
||||
local cat_tab = tab.new(3)
|
||||
table.sort(v, function(a,b) return a.name < b.name end )
|
||||
for _, server in pairs(v) do
|
||||
tab.addrow(
|
||||
cat_tab,
|
||||
server.name,
|
||||
("%d.%d"):format(server.version.major,server.version.minor),
|
||||
server.comment
|
||||
)
|
||||
end
|
||||
table.insert(output, { name = k, tab.dump(cat_tab) } )
|
||||
end
|
||||
table.sort(output, function(a,b) return a.name < b.name end)
|
||||
end
|
||||
|
||||
return stdnse.format_output(true, output)
|
||||
end
|
||||
Reference in New Issue
Block a user