mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Move in_port_range to shortport.port_range, expand portnumber to match ranges
This commit is contained in:
@@ -25,6 +25,29 @@ local function includes(t, value)
|
||||
return false
|
||||
end
|
||||
|
||||
-- Just like includes, but can match simple port ranges
|
||||
local function port_includes(t, value)
|
||||
for _, elem in ipairs(t) do
|
||||
if elem == value then
|
||||
return true
|
||||
elseif type(elem) == "string" then
|
||||
local pstart, pend = elem:match("^(%d+)%-(%d+)$")
|
||||
if not pstart then
|
||||
pstart = elem:match("^(%d+)$")
|
||||
pend = pstart
|
||||
end
|
||||
pstart, pend = tonumber(pstart), tonumber(pend)
|
||||
assert(pstart,"Incorrect port range specification.")
|
||||
assert(pstart<=pend,"Incorrect port range specification, the starting port should have a smaller value than the ending port.")
|
||||
assert(pstart>-1 and pend<65536, "Port range number out of range (0-65535).")
|
||||
if value >= pstart and value <= pend then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Check if the port and its protocol are in the exclude directive.
|
||||
--
|
||||
-- @param port A port number.
|
||||
@@ -60,7 +83,7 @@ portnumber = function(ports, protos, states)
|
||||
end
|
||||
|
||||
return function(host, port)
|
||||
return includes(ports, port.number)
|
||||
return port_includes(ports, port.number)
|
||||
and includes(protos, port.protocol)
|
||||
and includes(states, port.state)
|
||||
end
|
||||
@@ -281,4 +304,54 @@ function ssl(host, port)
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
--- Return a portrule that returns true when given an open port matching a port range
|
||||
--
|
||||
--@param range A port range string in Nmap standard format (ex. "T:80,1-30,U:31337,21-25")
|
||||
--@return Function for the portrule.
|
||||
function port_range(range)
|
||||
assert(type(range)=="string" and range~="","Incorrect port range specification.")
|
||||
|
||||
local ports = {
|
||||
tcp = {},
|
||||
udp = {},
|
||||
}
|
||||
local proto = "both"
|
||||
local pos = 1
|
||||
repeat
|
||||
local i, j, protspec = range:find("^%s*([TU:]+)", pos)
|
||||
if i then
|
||||
pos = j + 1
|
||||
if protspec == "U:" then
|
||||
proto = "udp"
|
||||
elseif protspec == "T:" then
|
||||
proto = "tcp"
|
||||
else
|
||||
assert(protspec == "", "Incorrect port range specification.")
|
||||
end
|
||||
end
|
||||
repeat
|
||||
local i, j, portspec = range:find("^%s*([%d%-]+),?", pos)
|
||||
if not i then break end
|
||||
pos = j + 1
|
||||
portspec = tonumber(portspec) or portspec
|
||||
if proto == "both" then
|
||||
local ttab = ports.tcp
|
||||
ttab[#ttab+1] = portspec
|
||||
local utab = ports.udp
|
||||
utab[#utab+1] = portspec
|
||||
else
|
||||
local ptab = ports[proto]
|
||||
ptab[#ptab+1] = portspec
|
||||
end
|
||||
until pos >= #range
|
||||
until pos >= #range
|
||||
|
||||
local tcp_rule = portnumber(ports.tcp, "tcp")
|
||||
local udp_rule = portnumber(ports.udp, "udp")
|
||||
return function(host, port)
|
||||
return tcp_rule(host, port) or udp_rule(host, port)
|
||||
end
|
||||
end
|
||||
|
||||
return _ENV;
|
||||
|
||||
@@ -944,77 +944,6 @@ do end -- no function here, see nse_main.lua
|
||||
do end -- no function here, see nse_main.lua
|
||||
|
||||
|
||||
|
||||
---Checks if the port is in the port range
|
||||
--
|
||||
-- For example, calling:
|
||||
-- <code>in_port_range({number=31337,protocol="udp"},"T:15,50-75,U:31334-31339")</code>
|
||||
-- would result in a true value
|
||||
--@param port a port structure containing keys port number(number) and protocol(string)
|
||||
--@param port_range a port range string in Nmap standard format (ex. "T:80,1-30,U:31337,21-25")
|
||||
--@returns boolean indicating whether the port is in the port range
|
||||
function in_port_range(port,port_range)
|
||||
assert(port and type(port.number)=="number" and type(port.protocol)=="string" and
|
||||
(port.protocol=="udp" or port.protocol=="tcp"),"Port structure missing or invalid: port={ number=<port_number>, protocol=<port_protocol> }")
|
||||
assert((type(port_range)=="string" or type(port_range)=="number") and port_range~="","Incorrect port range specification.")
|
||||
|
||||
-- Proto - true for TCP, false for UDP
|
||||
local proto
|
||||
if(port.protocol=="tcp") then proto = true else proto = false end
|
||||
|
||||
--TCP flag for iteration - true for TCP, false for UDP, if not specified we presume TCP
|
||||
local tcp_flag = true
|
||||
|
||||
-- in case the port_range is a single number
|
||||
if type(port_range)=="number" then
|
||||
if proto and port_range==port.number then return true
|
||||
else return false
|
||||
end
|
||||
end
|
||||
|
||||
--clean the string a bit
|
||||
port_range=port_range:gsub("%s+","")
|
||||
|
||||
-- single_pr - single port range
|
||||
for i, single_pr in ipairs(strsplit(",",port_range)) do
|
||||
if single_pr:match("T:") then
|
||||
tcp_flag = true
|
||||
single_pr = single_pr:gsub("T:","")
|
||||
else
|
||||
if single_pr:match("U:") then
|
||||
tcp_flag = false
|
||||
single_pr = single_pr:gsub("U:","")
|
||||
end
|
||||
end
|
||||
|
||||
-- compare ports only when the port's protocol is the same as
|
||||
-- the current single port range
|
||||
if tcp_flag == proto then
|
||||
local pone = single_pr:match("^(%d+)$")
|
||||
if pone then
|
||||
pone = tonumber(pone)
|
||||
assert(pone>-1 and pone<65536, "Port range number out of range (0-65535).")
|
||||
|
||||
if pone == port.number then
|
||||
return true
|
||||
end
|
||||
else
|
||||
local pstart, pend = single_pr:match("^(%d+)%-(%d+)$")
|
||||
pstart, pend = tonumber(pstart), tonumber(pend)
|
||||
assert(pstart,"Incorrect port range specification.")
|
||||
assert(pstart<=pend,"Incorrect port range specification, the starting port should have a smaller value than the ending port.")
|
||||
assert(pstart>-1 and pstart<65536 and pend>-1 and pend<65536, "Port range number out of range (0-65535).")
|
||||
|
||||
if port.number >=pstart and port.number <= pend then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- if no match is found then the port doesn't belong to the port_range
|
||||
return false
|
||||
end
|
||||
|
||||
--- Module function that mimics some behavior of Lua 5.1 module function.
|
||||
--
|
||||
-- This convenience function returns a module environment to set the _ENV
|
||||
|
||||
@@ -49,20 +49,16 @@ categories = {"intrusive", "brute"}
|
||||
-- This portrule succeeds only when the open|filtered port is in the port range
|
||||
-- which is specified by the ports script argument
|
||||
portrule = function(host, port)
|
||||
if not stdnse.get_script_args(SCRIPT_NAME .. ".ports") then
|
||||
stdnse.debug3("Skipping '%s' %s, 'ports' argument is missing.",SCRIPT_NAME, SCRIPT_TYPE)
|
||||
return false
|
||||
end
|
||||
|
||||
local ports = stdnse.get_script_args(SCRIPT_NAME .. ".ports")
|
||||
|
||||
--print out a debug message if port 31337/udp is open
|
||||
if port.number==31337 and port.protocol == "udp" and not(ports) then
|
||||
stdnse.debug1("Port 31337/udp is open. Possibility of version detection and password bruteforcing using the backorifice-brute script")
|
||||
if not ports then
|
||||
stdnse.verbose1("Skipping '%s' %s, 'ports' argument is missing.",SCRIPT_NAME, SCRIPT_TYPE)
|
||||
return false
|
||||
end
|
||||
|
||||
return port.protocol == "udp" and stdnse.in_port_range(port, ports:gsub(",",",") ) and
|
||||
-- ensure UDP
|
||||
portarg = portarg:gsub("^[U:]*", "U:")
|
||||
return port.protocol == "udp" and shortport.port_range(ports)(host, port) and
|
||||
not(shortport.port_is_excluded(port.number,port.protocol))
|
||||
end
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
local comm = require "comm"
|
||||
local nmap = require "nmap"
|
||||
local stdnse = require "stdnse"
|
||||
local shortport = require "shortport"
|
||||
local table = require "table"
|
||||
local U = require "lpeg-utility"
|
||||
|
||||
@@ -28,20 +29,15 @@ categories = {"discovery", "safe"}
|
||||
|
||||
|
||||
local portarg = stdnse.get_script_args(SCRIPT_NAME .. ".ports")
|
||||
if portarg then
|
||||
if portarg == "common" then
|
||||
portarg = "13,17,21-23,25,129,194,587,990,992,994,6667,6697"
|
||||
end
|
||||
|
||||
---
|
||||
-- Script is executed for any TCP port.
|
||||
portrule = function( host, port )
|
||||
if port.protocol == "tcp" then
|
||||
if portarg then
|
||||
return stdnse.in_port_range(port, portarg)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
-- ensure TCP
|
||||
portarg = portarg:gsub("^[T:]*", "T:")
|
||||
portrule = shortport.port_range(portarg)
|
||||
else
|
||||
portrule = function(host, port) return port.protocol == "tcp" end
|
||||
end
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user