mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Support RPCBIND 3 and 4, not only portmap 2. See #1469
This commit is contained in:
@@ -121,7 +121,7 @@ local mutex = nmap.mutex("rpc")
|
||||
|
||||
-- Supported protocol versions
|
||||
RPC_version = {
|
||||
["rpcbind"] = { min=2, max=2 },
|
||||
["rpcbind"] = { min=2, max=4 },
|
||||
["nfs"] = { min=1, max=3 },
|
||||
["mountd"] = { min=1, max=3 },
|
||||
}
|
||||
@@ -577,6 +577,16 @@ Portmap =
|
||||
CALLIT = 5,
|
||||
},
|
||||
|
||||
[3] =
|
||||
{
|
||||
DUMP = 4,
|
||||
},
|
||||
|
||||
[4] =
|
||||
{
|
||||
DUMP = 4,
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
State =
|
||||
@@ -635,11 +645,13 @@ Portmap =
|
||||
-- <code>
|
||||
-- table[program_id][protocol]["port"] = <port number>
|
||||
-- table[program_id][protocol]["version"] = <table of versions>
|
||||
-- table[program_id][protocol]["addr"] = <IP address, for RPCv3 and higher>
|
||||
-- </code>
|
||||
--
|
||||
-- Where
|
||||
-- o program_id is the number associated with the program
|
||||
-- o protocol is either "tcp" or "udp"
|
||||
-- o protocol is one of "tcp", "udp", "tcp6", or "udp6", or another netid
|
||||
-- reported by the system.
|
||||
--
|
||||
Dump = function(self, comm)
|
||||
local status, data, packet, response, pos, header
|
||||
@@ -701,16 +713,38 @@ Portmap =
|
||||
break
|
||||
end
|
||||
|
||||
program, version, protocol, port, pos = string.unpack(">I4 I4 I4 I4", data, pos)
|
||||
program, version, pos = string.unpack(">I4 I4", data, pos)
|
||||
local addr, owner
|
||||
if comm.version > 2 then
|
||||
local len
|
||||
len, pos = string.unpack(">I4", data, pos)
|
||||
pos, protocol = Util.unmarshall_vopaque(len, data, pos)
|
||||
len, pos = string.unpack(">I4", data, pos)
|
||||
pos, addr = Util.unmarshall_vopaque(len, data, pos)
|
||||
len, pos = string.unpack(">I4", data, pos)
|
||||
pos, owner = Util.unmarshall_vopaque(len, data, pos)
|
||||
if protocol:match("^[tu][cd]p6?$") then
|
||||
-- RFC 5665
|
||||
local upper, lower
|
||||
addr, upper, lower = addr:match("^(.-)%.(%d+)%.(%d+)$")
|
||||
if addr then
|
||||
port = tonumber(upper) * 0x100 + tonumber(lower)
|
||||
end
|
||||
end
|
||||
else
|
||||
protocol, port, pos = string.unpack(">I4 I4", data, pos)
|
||||
if ( protocol == Portmap.PROTOCOLS.tcp ) then
|
||||
protocol = "tcp"
|
||||
elseif ( protocol == Portmap.PROTOCOLS.udp ) then
|
||||
protocol = "udp"
|
||||
end
|
||||
end
|
||||
|
||||
program_table[program] = program_table[program] or {}
|
||||
program_table[program][protocol] = program_table[program][protocol] or {}
|
||||
program_table[program][protocol]["port"] = port
|
||||
program_table[program][protocol]["addr"] = addr
|
||||
program_table[program][protocol]["owner"] = owner
|
||||
program_table[program][protocol]["version"] = program_table[program][protocol]["version"] or {}
|
||||
table.insert( program_table[program][protocol]["version"], version )
|
||||
-- parts of the code rely on versions being in order
|
||||
@@ -2761,7 +2795,8 @@ Helper = {
|
||||
RpcInfo = function( host, port )
|
||||
local status, result
|
||||
local portmap = Portmap:new()
|
||||
local comm = Comm:new('rpcbind', 2)
|
||||
local pversion = 4
|
||||
local comm = Comm:new('rpcbind', pversion)
|
||||
|
||||
mutex "lock"
|
||||
|
||||
@@ -2775,6 +2810,7 @@ Helper = {
|
||||
return true, nmap.registry[host.ip]['portmapper']
|
||||
end
|
||||
|
||||
while pversion >= 2 do
|
||||
status, result = comm:Connect(host, port)
|
||||
if (not(status)) then
|
||||
mutex "done"
|
||||
@@ -2785,11 +2821,14 @@ Helper = {
|
||||
status, result = portmap:Dump(comm)
|
||||
comm:Disconnect()
|
||||
|
||||
mutex "done"
|
||||
if (not(status)) then
|
||||
if status then
|
||||
break
|
||||
end
|
||||
stdnse.debug4("rpc.Helper.RpcInfo: %s", result)
|
||||
pversion = pversion - 1
|
||||
end
|
||||
|
||||
mutex "done"
|
||||
return status, result
|
||||
end,
|
||||
|
||||
@@ -2837,32 +2876,55 @@ Helper = {
|
||||
return status, portmap_table
|
||||
end
|
||||
|
||||
local info = {}
|
||||
-- assume failure
|
||||
status = false
|
||||
|
||||
for _, p in ipairs( RPC_PROTOCOLS ) do
|
||||
local tmp = portmap_table[Util.ProgNameToNumber(program)]
|
||||
if not tmp then
|
||||
return false, "Program not supported by target"
|
||||
end
|
||||
|
||||
if ( tmp and tmp[p] ) then
|
||||
info = {}
|
||||
local info = {}
|
||||
local proginfo
|
||||
local ipv6 = nmap.address_family() == "inet6"
|
||||
::AF_FALLBACK::
|
||||
for _, p in ipairs( RPC_PROTOCOLS ) do
|
||||
if ipv6 then
|
||||
proginfo = tmp[p .. "6"]
|
||||
else
|
||||
proginfo = tmp[p]
|
||||
end
|
||||
if proginfo then
|
||||
info.port = {}
|
||||
info.port.number = tmp[p].port
|
||||
info.port.number = proginfo.port
|
||||
info.port.protocol = p
|
||||
break
|
||||
end
|
||||
end
|
||||
if ipv6 and not proginfo then
|
||||
-- Fall back to trying IPv4
|
||||
ipv6 = false
|
||||
goto AF_FALLBACK
|
||||
end
|
||||
|
||||
if not proginfo then
|
||||
return false, "No transport protocol supported"
|
||||
end
|
||||
|
||||
-- choose the highest version available
|
||||
if ( not(RPC_version[program]) ) then
|
||||
info.version = tmp[p].version[#tmp[p].version]
|
||||
info.version = proginfo.version[#proginfo.version]
|
||||
status = true
|
||||
else
|
||||
for i=#tmp[p].version, 1, -1 do
|
||||
if ( RPC_version[program].max >= tmp[p].version[i] ) then
|
||||
for i=#proginfo.version, 1, -1 do
|
||||
if ( RPC_version[program].max >= proginfo.version[i] ) then
|
||||
if ( not(max_version) ) then
|
||||
info.version = tmp[p].version[i]
|
||||
info.version = proginfo.version[i]
|
||||
status = true
|
||||
break
|
||||
else
|
||||
if ( max_version >= tmp[p].version[i] ) then
|
||||
info.version = tmp[p].version[i]
|
||||
if ( max_version >= proginfo.version[i] ) then
|
||||
info.version = proginfo.version[i]
|
||||
status = true
|
||||
break
|
||||
end
|
||||
@@ -2870,9 +2932,6 @@ Helper = {
|
||||
end
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return status, info
|
||||
end,
|
||||
|
||||
@@ -117,7 +117,10 @@ action = function(host, port)
|
||||
end
|
||||
end
|
||||
|
||||
table.insert( result, ("%-7d %-10s %5d/%s %s"):format(progid, table.concat(v2.version, ","), v2.port, proto, rpc.Util.ProgNumberToName(progid) or "") )
|
||||
if v2.port then
|
||||
-- TODO: report other transports that don't have a port; e.g. "local"
|
||||
table.insert( result, ("%-7d %-10s %5d/%-4s %s"):format(progid, table.concat(v2.version, ","), v2.port, proto, rpc.Util.ProgNumberToName(progid) or "") )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user