1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Provides a common function, url.get_default_port(), for obtaining

the default port number for a given scheme. Fixes #781
This commit is contained in:
nnposter
2017-04-19 18:00:36 +00:00
parent af6bbc35bb
commit e80976a13a
10 changed files with 41 additions and 77 deletions

View File

@@ -1,8 +1,10 @@
# Nmap Changelog ($Id$); -*-text-*- # Nmap Changelog ($Id$); -*-text-*-
o [NSE][GH#781] There is a new common function, url.get_default_port(),
to obtain the default port number for a given scheme. [nnposter]
o [NSE][GH#833] Function url.parse() now returns the port part as a number, o [NSE][GH#833] Function url.parse() now returns the port part as a number,
not a string, which eliminates various inconsistencies in scripts that not a string. [nnposter]
consume the function. [nnposter]
o [NSE][GH#854] New script smb-double-pulsar-backdoor detects the Shadow o [NSE][GH#854] New script smb-double-pulsar-backdoor detects the Shadow
Brokers-leaked Double Pulsar backdoor in Windows SMB servers. [Andrew Orr] Brokers-leaked Double Pulsar backdoor in Windows SMB servers. [Andrew Orr]

View File

@@ -175,10 +175,8 @@ local function url_build_defaults (host, port, parsed)
local parts = tcopy(parsed or {}) local parts = tcopy(parsed or {})
parts.host = parts.host or stdnse.get_hostname(host, port) parts.host = parts.host or stdnse.get_hostname(host, port)
parts.scheme = parts.scheme or shortport.ssl(host, port) and "https" or "http" parts.scheme = parts.scheme or shortport.ssl(host, port) and "https" or "http"
local pn = parts.port or port.number if not parts.port and port.number ~= url.get_default_port(parts.scheme) then
if not (parts.scheme == "http" and pn == 80 parts.port = port.number
or parts.scheme == "https" and pn == 443) then
parts.port = pn
end end
return parts return parts
end end

View File

@@ -157,6 +157,11 @@ local function table_augment(to, from)
end end
end end
--- Provide the default port for a given scheme.
-- The localization is necessary because functions in http.lua like to use
-- "url" as a local parameter
local get_default_port = url.get_default_port
--- Get a value suitable for the Host header field. --- Get a value suitable for the Host header field.
-- See RFC 2616 sections 14.23 and 5.2. -- See RFC 2616 sections 14.23 and 5.2.
local function get_host_field(host, port) local function get_host_field(host, port)
@@ -164,12 +169,11 @@ local function get_host_field(host, port)
if type(port) == "number" then if type(port) == "number" then
port = {number=port, protocol="tcp", state="open", version={}} port = {number=port, protocol="tcp", state="open", version={}}
end end
local ssl = shortport.ssl(host, port) local scheme = shortport.ssl(host, port) and "https" or "http"
local pn = port.number if port.number == get_default_port(scheme) then
if not ssl and pn == 80 or ssl and pn == 443 then
return stdnse.get_hostname(host) return stdnse.get_hostname(host)
else else
return stdnse.get_hostname(host) .. ":" .. pn return stdnse.get_hostname(host) .. ":" .. port.number
end end
end end
@@ -1496,14 +1500,7 @@ local redirect_ok_rules = {
function (url, host, port) function (url, host, port)
-- port fixup, adds default ports 80 and 443 in case no url.port was -- port fixup, adds default ports 80 and 443 in case no url.port was
-- defined, we do this based on the url scheme -- defined, we do this based on the url scheme
local url_port = url.port local url_port = url.port or get_default_port(url.scheme)
if ( not(url_port) ) then
if ( url.scheme == "http" ) then
url_port = 80
elseif( url.scheme == "https" ) then
url_port = 443
end
end
if not url_port or url_port == port.number then if not url_port or url_port == port.number then
return true return true
end end
@@ -1581,11 +1578,7 @@ function parse_redirect(host, port, path, response)
u.path = ((u.path:sub(1,1) == "/" and "" ) or "/" ) .. u.path -- ensuring leading slash u.path = ((u.path:sub(1,1) == "/" and "" ) or "/" ) .. u.path -- ensuring leading slash
end end
-- do port fixup -- do port fixup
if ( not(u.port) ) then u.port = u.port or get_default_port(u.scheme) or port.number
if ( u.scheme == "http" ) then u.port = 80
elseif ( u.scheme == "https") then u.port = 443
else u.port = port.number end
end
if ( not(u.path) ) then if ( not(u.path) ) then
u.path = "/" u.path = "/"
end end
@@ -1679,15 +1672,7 @@ function get_url( u, options )
local port = {} local port = {}
port.service = parsed.scheme port.service = parsed.scheme
port.number = parsed.port port.number = parsed.port or get_default_port(parsed.scheme) or 80
if not port.number then
if parsed.scheme == 'https' then
port.number = 443
else
port.number = 80
end
end
local path = parsed.path or "/" local path = parsed.path or "/"
if parsed.query then if parsed.query then

View File

@@ -233,9 +233,7 @@ LinkExtractor = {
base_href = base_href .. '/' base_href = base_href .. '/'
end end
if ( ( base_url:getProto() == 'https' and base_url:getPort() == 443 ) or if base_url:getPort() == url.get_default_port(base_url:getProto()) then
( base_url:getProto() == 'http' and base_url:getPort() == 80 ) ) then
if ( leading_slash ) then if ( leading_slash ) then
return ("%s://%s/%s"):format(base_url:getProto(), base_url:getHost(), rel_url) return ("%s://%s/%s"):format(base_url:getProto(), base_url:getHost(), rel_url)
else else
@@ -427,14 +425,7 @@ URL = {
self.proto, self.host, self.port, self.file = self.raw:match("^(http[s]?)://([^:/]*)[:]?(%d*)") self.proto, self.host, self.port, self.file = self.raw:match("^(http[s]?)://([^:/]*)[:]?(%d*)")
if ( self.proto and self.host ) then if ( self.proto and self.host ) then
self.file = self.raw:match("^http[s]?://[^:/]*[:]?%d*(/[^#]*)") or '/' self.file = self.raw:match("^http[s]?://[^:/]*[:]?%d*(/[^#]*)") or '/'
self.port = tonumber(self.port) self.port = tonumber(self.port) or url.get_default_port(self.proto)
if ( not(self.port) ) then
if ( self.proto:match("https") ) then
self.port = 443
elseif ( self.proto:match("http")) then
self.port = 80
end
end
self.path = self.file:match("^([^?]*)[%?]?") self.path = self.file:match("^([^?]*)[%?]?")
self.dir = self.path:match("^(.+%/)") or "/" self.dir = self.path:match("^(.+%/)") or "/"

View File

@@ -373,4 +373,16 @@ function build_query(query)
return table.concat(qstr, '&') return table.concat(qstr, '&')
end end
---
-- Provides the default port for a given URI scheme.
--
-- @param scheme for determining the port, such as "http" or "https".
-- @return A port number as an integer, such as 443 for scheme "https",
-- or nil in case of an undefined scheme
-----------------------------------------------------------------------------
function get_default_port (scheme)
local ports = {http=80, https=443}
return ports[(scheme or ""):lower()]
end
return _ENV; return _ENV;

View File

@@ -122,13 +122,8 @@ action = function(host, port)
if ( parsed.path:match(".*%.*.$") ) then if ( parsed.path:match(".*%.*.$") ) then
-- iterate over possible backup files -- iterate over possible backup files
for link in backupNames(parsed.path) do for link in backupNames(parsed.path) do
local host, port = parsed.host, parsed.port local host = parsed.host
local port = parsed.port or url.get_default_port(parsed.scheme)
-- if no port was found, try to deduce it from the scheme
if ( not(port) ) then
port = (parsed.scheme == 'https') and 443
port = port or ((parsed.scheme == 'http') and 80)
end
-- the url.escape doesn't work here as it encodes / to %2F -- the url.escape doesn't work here as it encodes / to %2F
-- which results in 400 bad request, so we simple do a space -- which results in 400 bad request, so we simple do a space

View File

@@ -128,21 +128,17 @@ end
-- host, port, and path if the URL is relative. Return nil if the scheme is not -- host, port, and path if the URL is relative. Return nil if the scheme is not
-- "http" or "https". -- "http" or "https".
function parse_url_relative(u, host, port, path) function parse_url_relative(u, host, port, path)
local defaultport, scheme, abspath local scheme, abspath
u = url.parse(u) u = url.parse(u)
scheme = u.scheme or "http" scheme = u.scheme or "http"
if scheme == "http" then if not (scheme == "http" or scheme == "https") then
defaultport = 80
elseif scheme == "https" then
defaultport = 443
else
return nil return nil
end end
abspath = u.path or "" abspath = u.path or ""
if not string.find(abspath, "^/") then if not string.find(abspath, "^/") then
abspath = dirname(path) .. "/" .. abspath abspath = dirname(path) .. "/" .. abspath
end end
return u.host or host, u.port or defaultport, abspath return u.host or host, u.port or url.get_default_port(scheme), abspath
end end
function parseIcon( body ) function parseIcon( body )

View File

@@ -59,13 +59,7 @@ local function dbgt(tbl)
end end
local function getHostPort(parsed) local function getHostPort(parsed)
local host, port = parsed.host, parsed.port return parsed.host, parsed.port or url.get_default_port(parsed.scheme)
-- if no port was found, try to deduce it from the scheme
if ( not(port) ) then
port = (parsed.scheme == 'https') and 443
port = port or ((parsed.scheme == 'http') and 80)
end
return host, port
end end
local function isRedirect(status) local function isRedirect(status)

View File

@@ -147,12 +147,8 @@ PHP files are not handling safely the variable $_SERVER["PHP_SELF"] causing Refl
--Only work with .php files --Only work with .php files
if ( parsed.path and parsed.path:match(".*.php") ) then if ( parsed.path and parsed.path:match(".*.php") ) then
--The following port/scheme code was seen in http-backup-finder and its neat =) local host = parsed.host
local host, port = parsed.host, parsed.port local port = parsed.port or url.get_default_port(parsed.scheme)
if ( not(port) ) then
port = (parsed.scheme == 'https') and 443
port = port or ((parsed.scheme == 'http') and 80)
end
local escaped_link = parsed.path:gsub(" ", "%%20") local escaped_link = parsed.path:gsub(" ", "%%20")
if launch_probe(host,port,escaped_link) then if launch_probe(host,port,escaped_link) then
table.insert(vulnpages, parsed.scheme..'://'..host..escaped_link..PHP_SELF_PROBE) table.insert(vulnpages, parsed.scheme..'://'..host..escaped_link..PHP_SELF_PROBE)

View File

@@ -49,14 +49,9 @@ portrule = shortport.http
local dbg = stdnse.debug2 local dbg = stdnse.debug2
local function getHostPort(parsed) local function getHostPort(parsed)
local host, port = parsed.host, parsed.port return parsed.host, parsed.port or url.get_default_port(parsed.scheme)
-- if no port was found, try to deduce it from the scheme
if ( not(port) ) then
port = (parsed.scheme == 'https') and 443
port = port or ((parsed.scheme == 'http') and 80)
end
return host, port
end end
local function getReflected(parsed, r) local function getReflected(parsed, r)
local reflected_values,not_reflected_values = {},{} local reflected_values,not_reflected_values = {},{}
local count = 0 local count = 0