mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Compare commits
3 Commits
8d06576dbb
...
a74125aef5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a74125aef5 | ||
|
|
f5a3251e97 | ||
|
|
8d7fa538e3 |
@@ -1,5 +1,12 @@
|
||||
#Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o [GH#3194] RPC-based scripts were sporadically failing due to privileged
|
||||
port conflicts. [nnposter]
|
||||
|
||||
o [GH#3196] Script rlogin-brute was sporadically failing due to using
|
||||
an off-by-one range for privileged ports and not handling potential
|
||||
port conflicts. [nnposter]
|
||||
|
||||
Nmap 7.98 [2025-08-21]
|
||||
|
||||
o [SECURITY] Rebuilt the Windows self-installer with NSIS 3.11, addressing
|
||||
|
||||
@@ -358,7 +358,19 @@ local function validate_options(options)
|
||||
stdnse.debug1("http: options.cookies[i].max-age should be a string")
|
||||
bad = true
|
||||
end
|
||||
elseif not (cookie_key == 'httponly' or cookie_key == 'secure') then
|
||||
elseif(cookie_key == 'domain') then
|
||||
if(type(cookie_value) ~= 'string') then
|
||||
stdnse.debug1("http: options.cookies[i].domain should be a string")
|
||||
bad = true
|
||||
end
|
||||
elseif(cookie_key == 'samesite') then
|
||||
if(type(cookie_value) ~= 'string') then
|
||||
stdnse.debug1("http: options.cookies[i].samesite should be a string")
|
||||
bad = true
|
||||
end
|
||||
elseif not (cookie_key == 'httponly'
|
||||
or cookie_key == 'secure'
|
||||
or cookie_key == 'partitioned') then
|
||||
stdnse.debug1("http: Unknown field in cookie table: %s", cookie_key)
|
||||
-- Ignore unrecognized attributes (per RFC 6265, Section 5.2)
|
||||
end
|
||||
|
||||
@@ -154,67 +154,54 @@ Comm = {
|
||||
-- @return status boolean true on success, false on failure
|
||||
-- @return string containing error message (if status is false)
|
||||
Connect = function(self, host, port, timeout)
|
||||
local status, err, socket
|
||||
status, err = self:ChkProgram()
|
||||
if (not(status)) then
|
||||
timeout = timeout or stdnse.get_timeout(host, 10000)
|
||||
local status, err = self:ChkProgram()
|
||||
if not status then
|
||||
return status, err
|
||||
end
|
||||
status, err = self:ChkVersion()
|
||||
if (not(status)) then
|
||||
if not status then
|
||||
return status, err
|
||||
end
|
||||
timeout = timeout or stdnse.get_timeout(host, 10000)
|
||||
local new_socket = function(...)
|
||||
local socket = nmap.new_socket(...)
|
||||
socket:set_timeout(timeout)
|
||||
return socket
|
||||
end
|
||||
if ( port.protocol == "tcp" ) then
|
||||
if nmap.is_privileged() then
|
||||
-- Try to bind to a reserved port
|
||||
for i = 1, 10, 1 do
|
||||
local resvport = math.random(512, 1023)
|
||||
socket = new_socket()
|
||||
status, err = socket:bind(nil, resvport)
|
||||
local socket = nmap.new_socket(port.protocol)
|
||||
if nmap.is_privileged() then
|
||||
-- Let's make several attempts to bind to an unused well-known port
|
||||
for _ = 1, 10 do
|
||||
local srcport = math.random(512, 1023)
|
||||
status, err = socket:bind(nil, srcport)
|
||||
if status then
|
||||
socket:set_timeout(timeout)
|
||||
status, err = socket:connect(host, port)
|
||||
if status then
|
||||
status, err = socket:connect(host, port)
|
||||
if status or err == "TIMEOUT" then break end
|
||||
socket:close()
|
||||
-- socket:connect() succeeds even if mksock_bind_addr() fails.
|
||||
-- It just assigns an ephemeral port instead of our choice,
|
||||
-- so we need to check the actual source port afterwards.
|
||||
local lport
|
||||
status, err, lport = socket:get_info()
|
||||
if status then
|
||||
if lport == srcport then
|
||||
break
|
||||
end
|
||||
status = false
|
||||
err = "Address already in use"
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
socket = new_socket()
|
||||
status, err = socket:connect(host, port)
|
||||
socket:close()
|
||||
end
|
||||
else
|
||||
if nmap.is_privileged() then
|
||||
-- Try to bind to a reserved port
|
||||
for i = 1, 10, 1 do
|
||||
local resvport = math.random(512, 1023)
|
||||
socket = new_socket("udp")
|
||||
status, err = socket:bind(nil, resvport)
|
||||
if status then
|
||||
status, err = socket:connect(host, port)
|
||||
if status or err == "TIMEOUT" then break end
|
||||
socket:close()
|
||||
end
|
||||
end
|
||||
else
|
||||
socket = new_socket("udp")
|
||||
status, err = socket:connect(host, port)
|
||||
end
|
||||
-- No privileges to force a specific source port
|
||||
status, err = socket:connect(host, port)
|
||||
end
|
||||
if (not(status)) then
|
||||
return status, string.format("%s connect error: %s",
|
||||
self.program, err)
|
||||
else
|
||||
self.socket = socket
|
||||
self.host = host
|
||||
self.ip = host.ip
|
||||
self.port = port.number
|
||||
self.proto = port.protocol
|
||||
return status, nil
|
||||
if not status then
|
||||
return status, ("%s connect error: %s"):format(self.program, err)
|
||||
end
|
||||
self.socket = socket
|
||||
self.host = host
|
||||
self.ip = host.ip
|
||||
self.port = port.number
|
||||
self.proto = port.protocol
|
||||
return status, nil
|
||||
end,
|
||||
|
||||
--- Disconnects from the remote program
|
||||
|
||||
@@ -51,34 +51,36 @@ Driver = {
|
||||
end,
|
||||
|
||||
-- connects to the rlogin service
|
||||
-- it sets the source port to a random value between 513 and 1024
|
||||
-- it sets the source port to a random value between 512 and 1023
|
||||
connect = function(self)
|
||||
|
||||
local status
|
||||
|
||||
local status, err
|
||||
self.socket = brute.new_socket()
|
||||
-- apparently wee need a source port below 1024
|
||||
-- this approach is not very elegant as it causes address already in
|
||||
-- use errors when the same src port is hit in a short time frame.
|
||||
-- hopefully the retry count should take care of this as a retry
|
||||
-- should choose a new random port as source.
|
||||
local srcport = math.random(513, 1024)
|
||||
self.socket:bind(nil, srcport)
|
||||
self.socket:set_timeout(self.timeout)
|
||||
local err
|
||||
status, err = self.socket:connect(self.host, self.port)
|
||||
|
||||
if ( status ) then
|
||||
local lport, _
|
||||
status, _, lport = self.socket:get_info()
|
||||
if (not(status) ) then
|
||||
return false, "failed to retrieve socket status"
|
||||
-- Let's make several attempts to bind to an unused well-known port
|
||||
for _ = 1, 10 do
|
||||
local srcport = math.random(512, 1023)
|
||||
status, err = self.socket:bind(nil, srcport)
|
||||
if status then
|
||||
self.socket:set_timeout(self.timeout)
|
||||
status, err = self.socket:connect(self.host, self.port)
|
||||
if status then
|
||||
-- socket:connect() succeeds even if mksock_bind_addr() fails.
|
||||
-- It just assigns an ephemeral port instead of our choice,
|
||||
-- so we need to check the actual source port afterwards.
|
||||
local lport
|
||||
status, err, lport = self.socket:get_info()
|
||||
if status then
|
||||
if lport == srcport then
|
||||
return status
|
||||
end
|
||||
status = false
|
||||
err = "Address already in use"
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
self.socket:close()
|
||||
end
|
||||
if ( not(status) ) then
|
||||
stdnse.debug3("ERROR: failed to connect to server")
|
||||
if not status then
|
||||
stdnse.debug2("Unable to bind to a well-known port (%s)", err)
|
||||
end
|
||||
return status
|
||||
end,
|
||||
|
||||
Reference in New Issue
Block a user