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

Handle libssh2 errors on connect. Closes #2616. Fixes #1014

This commit is contained in:
dmiller
2024-10-04 18:21:25 +00:00
parent b507356091
commit f1325d7c6f
5 changed files with 22 additions and 15 deletions

View File

@@ -1,5 +1,9 @@
#Nmap Changelog ($Id$); -*-text-*- #Nmap Changelog ($Id$); -*-text-*-
o [NSE][GH#1014][GH#2616] SSH NSE scripts now catch connection errors thrown by
the libssh2 Lua binding, providing useful output instead of a backtrace.
[Joshua Rogers, Daniel Miller]
o Nmap will now allow targets to be specified both on the command line and in o Nmap will now allow targets to be specified both on the command line and in
an input file with -iL. Previously, if targets were provided in both places, an input file with -iL. Previously, if targets were provided in both places,
only the targets in the input file would be scanned, and no notice was given only the targets in the input file would be scanned, and no notice was given

View File

@@ -41,8 +41,9 @@ portrule = shortport.ssh
function action (host, port) function action (host, port)
local result = stdnse.output_table() local result = stdnse.output_table()
local helper = libssh2_util.SSHConnection:new() local helper = libssh2_util.SSHConnection:new()
if not helper:connect(host, port) then local status, err = helper:connect_pcall(host, port)
return "Failed to connect to ssh server" if not status then
return "Failed to connect to ssh server: " .. err
end end
local authmethods = helper:list(username) local authmethods = helper:list(username)

View File

@@ -82,9 +82,7 @@ Driver = {
local function password_auth_allowed (host, port) local function password_auth_allowed (host, port)
local helper = libssh2_util.SSHConnection:new() local helper = libssh2_util.SSHConnection:new()
if not helper:connect(host, port) then helper:connect(host, port) -- throws error on failure
return "Failed to connect to ssh server"
end
local methods = helper:list "root" local methods = helper:list "root"
if methods then if methods then
for _, value in pairs(methods) do for _, value in pairs(methods) do
@@ -99,7 +97,11 @@ end
function action (host, port) function action (host, port)
local timems = stdnse.parse_timespec(arg_timeout) --todo: use this! local timems = stdnse.parse_timespec(arg_timeout) --todo: use this!
local ssh_timeout = 1000 * timems local ssh_timeout = 1000 * timems
if password_auth_allowed(host, port) then local connected, auth_status = pcall(password_auth_allowed, host, port)
if not connected then
return "Failed to connect to ssh server: " .. auth_status
end
if auth_status then
local options = { local options = {
ssh_timeout = ssh_timeout, ssh_timeout = ssh_timeout,
} }

View File

@@ -61,12 +61,12 @@ function action (host, port)
local status, result = helper:read_publickey(publickeys[i]) local status, result = helper:read_publickey(publickeys[i])
if not status then if not status then
stdnse.verbose("Error reading key: " .. result) stdnse.verbose("Error reading key: " .. result)
elseif helper:connect(host, port) then elseif helper:connect_pcall(host, port) then
successes = successes + 1 successes = successes + 1
local status, err = helper:publickey_canauth(usernames[j], result) local status, err = helper:publickey_canauth(usernames[j], result)
if status then if status then
table.insert(r, "Key " .. publickeys[i] .. " accepted for user " .. usernames[j]) table.insert(r, "Key " .. publickeys[i] .. " accepted for user " .. usernames[j])
stdnse.verbose("Found accepted key: " .. publickeys[i] .. " for user " .. usernames[j]) stdnse.verbose("Found accepted key: " .. publickeys[i] .. " for user " .. usernames[j] .. " on host " .. host.ip .. ":" .. port.number)
elseif err then elseif err then
stdnse.debug("Error in publickey_canauth: %s", err) stdnse.debug("Error in publickey_canauth: %s", err)
end end
@@ -100,7 +100,7 @@ function action (host, port)
local msg = sections[3] local msg = sections[3]
stdnse.debug("Checking key: " .. key .. " for user " .. user) stdnse.debug("Checking key: " .. key .. " for user " .. user)
key = base64.dec(key) key = base64.dec(key)
if helper:connect(host, port) then if helper:connect_pcall(host, port) then
successes = successes + 1 successes = successes + 1
if helper:publickey_canauth(user, key) then if helper:publickey_canauth(user, key) then
table.insert(r, msg) table.insert(r, msg)
@@ -128,14 +128,13 @@ function action (host, port)
for j = 1, #usernames do for j = 1, #usernames do
for i = 1, #privatekeys do for i = 1, #privatekeys do
stdnse.debug("Checking key: " .. privatekeys[i] .. " for user " .. usernames[j]) stdnse.debug("Checking key: " .. privatekeys[i] .. " for user " .. usernames[j])
if helper:connect(host, port) then if helper:connect_pcall(host, port) then
successes = successes + 1 successes = successes + 1
if not helper:publickey_auth(usernames[j], privatekeys[i], passphrases[i] or "") then if not helper:publickey_auth(usernames[j], privatekeys[i], passphrases[i] or "") then
stdnse.verbose "Failed to authenticate" stdnse.verbose("Failed to authenticate key " .. privatekeys[i] .. " for user " .. usernames[j] .. " on host " .. host.ip .. ":" .. port.number)
else else
table.insert(r, "Key " .. privatekeys[i] .. " accepted for user " .. usernames[j]) table.insert(r, "Key " .. privatekeys[i] .. " accepted for user " .. usernames[j])
stdnse.verbose("Found accepted key: " .. privatekeys[i] .. " for user " .. usernames[j]) stdnse.verbose("Found accepted key: " .. privatekeys[i] .. " for user " .. usernames[j] .. " on host " .. host.ip .. ":" .. port.number)
end end
helper:disconnect() helper:disconnect()
else else

View File

@@ -61,8 +61,9 @@ end
function action (host, port) function action (host, port)
local conn = libssh2_util.SSHConnection:new() local conn = libssh2_util.SSHConnection:new()
if not conn:connect(host, port) then local status, err = helper:connect_pcall(host, port)
return "Failed to connect to ssh server" if not status then
return "Failed to connect to ssh server: " .. err
end end
if username and password and cmd then if username and password and cmd then
if not conn:password_auth(username, password) then if not conn:password_auth(username, password) then