mirror of
https://github.com/nmap/nmap.git
synced 2026-02-15 18:06:35 +00:00
Merged libssh2-integration branch
This commit is contained in:
35
scripts/ssh-auth-methods.nse
Normal file
35
scripts/ssh-auth-methods.nse
Normal file
@@ -0,0 +1,35 @@
|
||||
local shortport = require "shortport"
|
||||
local stdnse = require "stdnse"
|
||||
local libssh2 = require "libssh2"
|
||||
|
||||
description = [[
|
||||
Returns authenication methods a ssh server supports.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 22 --script ssh-auth-methods --script-args="ssh.user=<username>" <target>
|
||||
--
|
||||
-- @output
|
||||
-- 22/tcp open ssh syn-ack
|
||||
-- | ssh-auth-methods:
|
||||
-- | Supported authentication methods:
|
||||
-- | publickey
|
||||
-- |_ password
|
||||
|
||||
author = "Devin Bjelland"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
|
||||
local username = stdnse.get_script_args("ssh.user") or stdnse.generate_random_string(5)
|
||||
portrule = shortport.port_or_service(22, 'ssh')
|
||||
|
||||
action = function (host, port)
|
||||
local result = stdnse.output_table()
|
||||
|
||||
local session = libssh2.session_open(host, port.number)
|
||||
local authmethods = libssh2.userauth_list(session, username)
|
||||
|
||||
result["Supported authentication methods"] = authmethods
|
||||
|
||||
return result
|
||||
end
|
||||
118
scripts/ssh-brute.nse
Normal file
118
scripts/ssh-brute.nse
Normal file
@@ -0,0 +1,118 @@
|
||||
local shortport = require "shortport"
|
||||
local stdnse = require "stdnse"
|
||||
local brute = require "brute"
|
||||
|
||||
local libssh2 = stdnse.silent_require "libssh2"
|
||||
|
||||
description = [[
|
||||
Performs brute-force password guessing against ssh servers.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 22 --script ssh-brute --script-args userdb=users.lst,passdb=pass.lst \
|
||||
-- --script-args ssh-brute.timeout=4s <target>
|
||||
--
|
||||
-- @output
|
||||
-- 22/ssh open ssh
|
||||
-- | ssh-brute:
|
||||
-- | Accounts
|
||||
-- | username:password
|
||||
-- | Statistics
|
||||
-- |_ Performed 32 guesses in 25 seconds.
|
||||
--
|
||||
-- @args ssh-brute.timeout Connection timeout (default: "5s")
|
||||
|
||||
author = "Devin Bjelland"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {'brute', 'intrusive'}
|
||||
|
||||
portrule = shortport.port_or_service(22, 'ssh')
|
||||
|
||||
local arg_timeout = stdnse.get_script_args(SCRIPT_NAME .. ".timeout") or "5s"
|
||||
|
||||
Driver = {
|
||||
new = function(self, host, port, options)
|
||||
stdnse.debug(2, "creating brute driver")
|
||||
local o = {}
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
o.host = host
|
||||
o.port = port
|
||||
o.options = options
|
||||
return o
|
||||
end,
|
||||
|
||||
connect = function (self)
|
||||
stdnse.debug(2, "connecting to %s:%d", self.host.ip, self.port.number)
|
||||
local status, session, err = pcall(libssh2.session_open, self.host, self.port.number)
|
||||
if not status then
|
||||
stdnse.debug(2, "libssh2 error: %s", session)
|
||||
local err = brute.Error:new(session)
|
||||
err:setAbort(true)
|
||||
return false, err
|
||||
elseif not session then
|
||||
stdnse.debug(2, "failure to connect: %s", err);
|
||||
local err = brute.Error:new(err)
|
||||
err:setAbort(true)
|
||||
return false, err
|
||||
else
|
||||
self.ssh_session = session
|
||||
libssh2.set_timeout(self.ssh_session, self.options.ssh_timeout)
|
||||
return true
|
||||
end
|
||||
end,
|
||||
|
||||
disconnect = function(self)
|
||||
stdnse.debug(2, "disconnecting from %s:%d", self.host.ip, self.port.number);
|
||||
local status, err = pcall(libssh2.session_close, self.ssh_session)
|
||||
if not status then
|
||||
stdnse.debug(2, "libssh2 error: %s", ok)
|
||||
end
|
||||
end,
|
||||
|
||||
login = function(self, username, password)
|
||||
stdnse.verbose(2, "Trying username/password pair: %s:%s", username, password)
|
||||
local status, ok = pcall(libssh2.userauth_password, self.ssh_session, username, password)
|
||||
if not status then
|
||||
stdnse.debug(2, "libssh2 error: %s", ok)
|
||||
return false, brute.Error:new(ok)
|
||||
elseif not ok then
|
||||
stdnse.debug(2, "login failed for %s:%s", username, password)
|
||||
return false, brute.Error:new("login failed")
|
||||
else
|
||||
stdnse.verbose(1, "Found working Credentials: %s:%s", username, password)
|
||||
return true, brute.Account:new(username, password, "OPEN")
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
password_auth_allowed = function (host, port)
|
||||
local status, ssh_session = pcall(libssh2.session_open, host, port.number)
|
||||
if status and ssh_session then
|
||||
local status, methods = pcall(libssh2.userauth_list, ssh_session, "root")
|
||||
if status then
|
||||
for _, value in pairs(methods) do
|
||||
if value == "password" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
action = function (host, port)
|
||||
local timems = stdnse.parse_timespec(arg_timeout) --todo: use this!
|
||||
local ssh_timeout = 1000 * timems
|
||||
if password_auth_allowed(host, port) then
|
||||
local options = {ssh_timeout = ssh_timeout}
|
||||
local engine = brute.Engine:new(Driver, host, port, options)
|
||||
engine.options.script_name = SCRIPT_NAME
|
||||
local _, result = engine:start()
|
||||
return result
|
||||
else
|
||||
return "Password authenication not allowed"
|
||||
end
|
||||
end
|
||||
|
||||
128
scripts/ssh-vuln-hostkey.nse
Normal file
128
scripts/ssh-vuln-hostkey.nse
Normal file
@@ -0,0 +1,128 @@
|
||||
local shortport = require "shortport"
|
||||
local ssh2 = require "ssh2"
|
||||
local ssh1 = require "ssh1"
|
||||
local stdnse = require "stdnse"
|
||||
|
||||
local io = require "io"
|
||||
local string = require "string"
|
||||
local table = require "table"
|
||||
|
||||
description = [[
|
||||
Checks if ssh server has a predictable hostkey by checking it against a list of fingerprints
|
||||
generated by HD Moore. You have to download these hostkeys separately and specify their directory
|
||||
as the fingerprintdir variable. The keys are available at http://itsecurity.net/debian_ssh_scan_v4.tar.bz2. Additionally, you can specify a file ssh hostkey fingerprints, one per line, and the scripts will report if the hostkey matches one of the provided fingerprints.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap -p 22 --script ssh-vuln-hostkey \
|
||||
-- --script-args fingerprintdir=<directory with vulnerable fingerprints> <target>
|
||||
--
|
||||
-- @output
|
||||
--
|
||||
-- 22/tcp open ssh syn-ack
|
||||
-- | ssh-vuln-hostkey:
|
||||
-- | Weak hostkeys:
|
||||
-- |_ 2048 6d:cd:2a:8b:dc:3e:e0:92:00:47:59:16:8c:8b:17:70 (RSA)
|
||||
--
|
||||
--
|
||||
-- @usage
|
||||
-- -- nmap -p 22 --script ssh-vuln-hostkey \
|
||||
-- --script-args fingerprintfile=<file with fingerprints to check for> <target>
|
||||
--
|
||||
-- @output
|
||||
--
|
||||
-- 22/tcp open ssh syn-ack
|
||||
-- | ssh-vuln-hostkey:
|
||||
-- | Listed hostkeys:
|
||||
-- |_ 2048 6d:cd:2a:8b:dc:3e:e0:92:00:47:59:16:8c:8b:17:70 (RSA)
|
||||
--
|
||||
-- @args fingerprintdir Directory containing vulnerable fingerprints
|
||||
-- @args fingerprintfile File containing fingerprints to check against
|
||||
--
|
||||
|
||||
author = "Devin Bjelland"
|
||||
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"safe","default","discovery"}
|
||||
|
||||
dependencies = {"ssh-hostkey"}
|
||||
|
||||
portrule = shortport.port_or_service(22, 'ssh')
|
||||
|
||||
local fingerprintdir = stdnse.get_script_args("fingerprintdir")
|
||||
local fingerprintfile = stdnse.get_script_args("fingerprintfile")
|
||||
|
||||
action = function (host, port)
|
||||
local key
|
||||
local keys = {}
|
||||
local r = stdnse.output_table()
|
||||
local w = {}
|
||||
local listed_hostkeys = {}
|
||||
local found_listed_key
|
||||
local found_weak_key
|
||||
|
||||
if nmap.registry.sshhostkey and nmap.registry.sshhostkey[host.ip] then
|
||||
keys = nmap.registgry.sshhostkey[host.ip]
|
||||
else
|
||||
key = ssh2.fetch_host_key( host, port, "ssh-rsa" )
|
||||
if key then table.insert( keys, key ) end
|
||||
|
||||
key = ssh2.fetch_host_key( host, port, "ssh-dss" )
|
||||
if key then table.insert( keys, key ) end
|
||||
end
|
||||
|
||||
for _,key in ipairs(keys) do
|
||||
local fingerprint = stdnse.tohex(key.fingerprint)
|
||||
stdnse.debug("fingerprint: " .. fingerprint)
|
||||
if fingerprintdir then
|
||||
if key.key_type == "ssh-rsa" then
|
||||
for line in io.lines(fingerprintdir .. "ssh_rsa_" .. key.bits .. "_keys.txt") do
|
||||
local stripped_line = string.gsub(line, "-.*", "")
|
||||
if stripped_line == fingerprint then
|
||||
found_weak_key = true
|
||||
stdnse.verbose("Found weak hostkey: " .. ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
|
||||
table.insert(w, ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
|
||||
end
|
||||
end
|
||||
elseif key.key_type == "ssh-dss" and key.bits == "1024" then
|
||||
for line in io.lines(fingerprintdir .. "ssh_dsa_1024_keys.txt", "r") do
|
||||
local stripped_line = string.gsub(line, "-.*", "")
|
||||
if stripped_line == fingerprint then
|
||||
found_weak_key = true
|
||||
stdnse.verbose("Found weak hostkey: " .. ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
|
||||
table.insert(w, ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if fingerprintfile then
|
||||
for line in io.lines(fingerprintfile) do
|
||||
local stripped_line = string.gsub(line, ":", "")
|
||||
if stripped_line == fingerprint then
|
||||
found_listed_key = true
|
||||
table.insert(listed_hostkeys, ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
|
||||
stdnse.verbose("Found hostkey on list:" .. ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not found_weak_key then
|
||||
w = "No weak hostkeys found"
|
||||
end
|
||||
|
||||
if not found_listed_key then
|
||||
list_hostkey = "No listed hostkeys found"
|
||||
end
|
||||
|
||||
if fingerprintdir then
|
||||
r["Weak hostkeys"] = w
|
||||
end
|
||||
|
||||
if fingerprintfile then
|
||||
r["Listed hostkeys"] = listed_hostkeys
|
||||
end
|
||||
|
||||
return r
|
||||
end
|
||||
Reference in New Issue
Block a user