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:
149
nselib/rpc.lua
149
nselib/rpc.lua
@@ -121,7 +121,7 @@ local mutex = nmap.mutex("rpc")
|
|||||||
|
|
||||||
-- Supported protocol versions
|
-- Supported protocol versions
|
||||||
RPC_version = {
|
RPC_version = {
|
||||||
["rpcbind"] = { min=2, max=2 },
|
["rpcbind"] = { min=2, max=4 },
|
||||||
["nfs"] = { min=1, max=3 },
|
["nfs"] = { min=1, max=3 },
|
||||||
["mountd"] = { min=1, max=3 },
|
["mountd"] = { min=1, max=3 },
|
||||||
}
|
}
|
||||||
@@ -577,6 +577,16 @@ Portmap =
|
|||||||
CALLIT = 5,
|
CALLIT = 5,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[3] =
|
||||||
|
{
|
||||||
|
DUMP = 4,
|
||||||
|
},
|
||||||
|
|
||||||
|
[4] =
|
||||||
|
{
|
||||||
|
DUMP = 4,
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
State =
|
State =
|
||||||
@@ -635,11 +645,13 @@ Portmap =
|
|||||||
-- <code>
|
-- <code>
|
||||||
-- table[program_id][protocol]["port"] = <port number>
|
-- table[program_id][protocol]["port"] = <port number>
|
||||||
-- table[program_id][protocol]["version"] = <table of versions>
|
-- table[program_id][protocol]["version"] = <table of versions>
|
||||||
|
-- table[program_id][protocol]["addr"] = <IP address, for RPCv3 and higher>
|
||||||
-- </code>
|
-- </code>
|
||||||
--
|
--
|
||||||
-- Where
|
-- Where
|
||||||
-- o program_id is the number associated with the program
|
-- 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)
|
Dump = function(self, comm)
|
||||||
local status, data, packet, response, pos, header
|
local status, data, packet, response, pos, header
|
||||||
@@ -701,16 +713,38 @@ Portmap =
|
|||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
program, version, protocol, port, pos = string.unpack(">I4 I4 I4 I4", data, pos)
|
program, version, pos = string.unpack(">I4 I4", data, pos)
|
||||||
if ( protocol == Portmap.PROTOCOLS.tcp ) then
|
local addr, owner
|
||||||
protocol = "tcp"
|
if comm.version > 2 then
|
||||||
elseif ( protocol == Portmap.PROTOCOLS.udp ) then
|
local len
|
||||||
protocol = "udp"
|
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
|
end
|
||||||
|
|
||||||
program_table[program] = program_table[program] or {}
|
program_table[program] = program_table[program] or {}
|
||||||
program_table[program][protocol] = program_table[program][protocol] or {}
|
program_table[program][protocol] = program_table[program][protocol] or {}
|
||||||
program_table[program][protocol]["port"] = port
|
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 {}
|
program_table[program][protocol]["version"] = program_table[program][protocol]["version"] or {}
|
||||||
table.insert( program_table[program][protocol]["version"], version )
|
table.insert( program_table[program][protocol]["version"], version )
|
||||||
-- parts of the code rely on versions being in order
|
-- parts of the code rely on versions being in order
|
||||||
@@ -2761,7 +2795,8 @@ Helper = {
|
|||||||
RpcInfo = function( host, port )
|
RpcInfo = function( host, port )
|
||||||
local status, result
|
local status, result
|
||||||
local portmap = Portmap:new()
|
local portmap = Portmap:new()
|
||||||
local comm = Comm:new('rpcbind', 2)
|
local pversion = 4
|
||||||
|
local comm = Comm:new('rpcbind', pversion)
|
||||||
|
|
||||||
mutex "lock"
|
mutex "lock"
|
||||||
|
|
||||||
@@ -2775,21 +2810,25 @@ Helper = {
|
|||||||
return true, nmap.registry[host.ip]['portmapper']
|
return true, nmap.registry[host.ip]['portmapper']
|
||||||
end
|
end
|
||||||
|
|
||||||
status, result = comm:Connect(host, port)
|
while pversion >= 2 do
|
||||||
if (not(status)) then
|
status, result = comm:Connect(host, port)
|
||||||
mutex "done"
|
if (not(status)) then
|
||||||
stdnse.debug4("rpc.Helper.RpcInfo: %s", result)
|
mutex "done"
|
||||||
return status, result
|
stdnse.debug4("rpc.Helper.RpcInfo: %s", result)
|
||||||
end
|
return status, result
|
||||||
|
end
|
||||||
|
|
||||||
status, result = portmap:Dump(comm)
|
status, result = portmap:Dump(comm)
|
||||||
comm:Disconnect()
|
comm:Disconnect()
|
||||||
|
|
||||||
|
if status then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
stdnse.debug4("rpc.Helper.RpcInfo: %s", result)
|
||||||
|
pversion = pversion - 1
|
||||||
|
end
|
||||||
|
|
||||||
mutex "done"
|
mutex "done"
|
||||||
if (not(status)) then
|
|
||||||
stdnse.debug4("rpc.Helper.RpcInfo: %s", result)
|
|
||||||
end
|
|
||||||
|
|
||||||
return status, result
|
return status, result
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -2837,40 +2876,60 @@ Helper = {
|
|||||||
return status, portmap_table
|
return status, portmap_table
|
||||||
end
|
end
|
||||||
|
|
||||||
local info = {}
|
|
||||||
-- assume failure
|
-- assume failure
|
||||||
status = false
|
status = false
|
||||||
|
|
||||||
for _, p in ipairs( RPC_PROTOCOLS ) do
|
local tmp = portmap_table[Util.ProgNameToNumber(program)]
|
||||||
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
|
local info = {}
|
||||||
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 = {}
|
||||||
info.port.number = tmp[p].port
|
info.port.number = proginfo.port
|
||||||
info.port.protocol = p
|
info.port.protocol = p
|
||||||
-- choose the highest version available
|
break
|
||||||
if ( not(RPC_version[program]) ) then
|
end
|
||||||
info.version = tmp[p].version[#tmp[p].version]
|
end
|
||||||
status = true
|
if ipv6 and not proginfo then
|
||||||
else
|
-- Fall back to trying IPv4
|
||||||
for i=#tmp[p].version, 1, -1 do
|
ipv6 = false
|
||||||
if ( RPC_version[program].max >= tmp[p].version[i] ) then
|
goto AF_FALLBACK
|
||||||
if ( not(max_version) ) then
|
end
|
||||||
info.version = tmp[p].version[i]
|
|
||||||
status = true
|
if not proginfo then
|
||||||
break
|
return false, "No transport protocol supported"
|
||||||
else
|
end
|
||||||
if ( max_version >= tmp[p].version[i] ) then
|
|
||||||
info.version = tmp[p].version[i]
|
-- choose the highest version available
|
||||||
status = true
|
if ( not(RPC_version[program]) ) then
|
||||||
break
|
info.version = proginfo.version[#proginfo.version]
|
||||||
end
|
status = true
|
||||||
end
|
else
|
||||||
|
for i=#proginfo.version, 1, -1 do
|
||||||
|
if ( RPC_version[program].max >= proginfo.version[i] ) then
|
||||||
|
if ( not(max_version) ) then
|
||||||
|
info.version = proginfo.version[i]
|
||||||
|
status = true
|
||||||
|
break
|
||||||
|
else
|
||||||
|
if ( max_version >= proginfo.version[i] ) then
|
||||||
|
info.version = proginfo.version[i]
|
||||||
|
status = true
|
||||||
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -117,14 +117,17 @@ action = function(host, port)
|
|||||||
end
|
end
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
||||||
table.sort(result)
|
table.sort(result)
|
||||||
|
|
||||||
if (#result > 0) then
|
if (#result > 0) then
|
||||||
table.insert(result, 1, "program version port/proto service")
|
table.insert(result, 1, "program version port/proto service")
|
||||||
end
|
end
|
||||||
|
|
||||||
return xmlout, stdnse.format_output( true, result )
|
return xmlout, stdnse.format_output( true, result )
|
||||||
|
|||||||
Reference in New Issue
Block a user