From 2b898d61f7629a10643a7c855c915f63afbeb67b Mon Sep 17 00:00:00 2001 From: david Date: Sun, 27 Mar 2011 22:04:13 +0000 Subject: [PATCH] o [NSE] ssh-hostkey now additionally has a postrule that prints hosts that have the same hostkey. [Toni Ruottu] --- CHANGELOG | 3 ++ scripts/ssh-hostkey.nse | 78 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 0ec8d1e75..82c9ec59f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,8 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] ssh-hostkey now additionally has a postrule that prints hosts + that have the same hostkey. [Toni Ruottu] + o [NSE] Added dns-nsec-enum.nse, which quickly enumerates the domains of a DNSSEC server that uses NSEC records for nonexistent domains. [John Bond, David] diff --git a/scripts/ssh-hostkey.nse b/scripts/ssh-hostkey.nse index 187f9af5c..d083a7c74 100644 --- a/scripts/ssh-hostkey.nse +++ b/scripts/ssh-hostkey.nse @@ -2,6 +2,8 @@ description = [[ Shows SSH hostkeys. Shows the target SSH server's key fingerprint and (with high enough verbosity level) the public key itself. It records the discovered host keys in nmap.registry for use by other scripts. Output can be controlled with the ssh_hostkey script argument. + +The script also includes a postrule that check for duplicate hosts using the gathered keys. ]] --- @@ -36,6 +38,18 @@ Shows the target SSH server's key fingerprint and (with high enough verbosity le -- 22/tcp open ssh -- | ssh-hostkey: 2048 xuvah-degyp-nabus-zegah-hebur-nopig-bubig-difeg-hisym-rumef-cuxex (RSA) -- |_ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwVuv2gcr0maaKQ69VVIEv2ob4OxnuI64fkeOnCXD1lUx5tTA+vefXUWEMxgMuA7iX4irJHy2zer0NQ3Z3yJvr5scPgTYIaEOp5Uo/eGFG9Agpk5wE8CoF0e47iCAPHqzlmP2V7aNURLMODb3jVZuI07A2ZRrMGrD8d888E2ORVORv1rYeTYCqcMMoVFmX9l3gWEdk4yx3w5sD8v501Iuyd1v19mPfyhrI5E1E1nl/Xjp5N0/xP2GUBrdkDMxKaxqTPMie/f0dXBUPQQN697a5q+5lBRPhKYOtn6yQKCd9s1Q22nxn72Jmi1RzbMyYJ52FosDT755Qmb46GLrDMaZMQ== +-- +--@output +-- Post-scan script results: +-- | ssh-hostkey: Possible duplicate hosts +-- | Key 1024 60:ac:4d:51:b1:cd:85:09:12:16:92:76:1d:5d:27:6e (DSA) used by: +-- | 192.168.1.1 +-- | 192.168.1.2 +-- | Key 2048 2c:22:75:60:4b:c3:3b:18:a2:97:2c:96:7e:28:dc:dd (RSA) used by: +-- | 192.168.1.1 +-- |_ 192.168.1.2 +-- + author = "Sven Klemm" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"safe","default","discovery"} @@ -57,6 +71,7 @@ end portrule = shortport.port_or_service(22, "ssh") +postrule = function() return (nmap.registry.sshhostkey ~= nil) end --- put hostkey in the nmap registry for usage by other scripts --@param host nmap host table @@ -67,7 +82,10 @@ local add_key_to_registry = function( host, key ) table.insert( nmap.registry.sshhostkey[host.ip], key ) end -action = function(host, port) +--- gather host keys +--@param host nmap host table +--@param port nmap port table of the currently probed port +local function portaction(host, port) local output = {} local keys = {} local _,key @@ -107,3 +125,61 @@ action = function(host, port) end end +--- check for the presence of a value in a table +--@param tab the table to search into +--@param item the searched value +--@return a boolean indicating whether the value has been found or not +local function contains(tab, item) + for _, val in pairs(tab) do + if val == item then + return true + end + end + return false +end + +--- iterate over the list of gathered keys and look for duplicate hosts (sharing the same hostkeys) +local function postaction() + local hostkeys = {} + local output = {} + + -- create a reverse mapping key_fingerprint -> host(s) + for ip, keys in pairs(nmap.registry.sshhostkey) do + for _, key in ipairs(keys) do + local fp = ssh1.fingerprint_hex(key.fingerprint, key.algorithm, key.bits) + if not hostkeys[fp] then + hostkeys[fp] = {} + end + -- discard duplicate IPs + if not contains(hostkeys[fp], ip) then + table.insert(hostkeys[fp], ip) + end + end + end + + -- look for hosts using the same hostkey + for key, hosts in pairs(hostkeys) do + if #hostkeys[key] > 1 then + local str = 'Key ' .. key .. ' used by:' + for _, host in ipairs(hostkeys[key]) do + str = str .. '\n ' .. host + end + table.insert(output, str) + end + end + + if #output > 0 then + return 'Possible duplicate hosts\n' .. table.concat(output, '\n') + end +end + +local ActionsTable = { + -- portrule: retrieve ssh hostkey + portrule = portaction, + -- postrule: look for duplicate hosts (same hostkey) + postrule = postaction +} + +-- execute the action function corresponding to the current rule +action = function(...) return ActionsTable[SCRIPT_TYPE](...) end +