Nmap Development mailing list archives
Re: [NSE script] SSH2 hostkey
From: Sven Klemm <sven () c3d2 de>
Date: Tue, 05 Aug 2008 19:18:07 +0200
Hi Brandon,
You might consider only displaying the key fingerprint instead of the full key unless verbose is set to at least 2. Here is what that would look like:Starting Nmap 4.68 ( http://nmap.org ) at 2008-08-05 16:34 CEST Interesting ports on localhost (127.0.0.1): PORT STATE SERVICE 22/tcp open ssh | SSH2-Hostkey: ssh-rsa 2048 f0:58:ce:f4:aa:a4:59:1c:8e:dd:4d:07:44:c8:25:11 |_ ssh-dss 1024 23:23:8c:73:26:22:4a:63:d8:5d:41:eb:86:cf:a0:58You'll have to dig into the standard spec to figure out what part of the key you compute the hash over. For RSA it is probably the modulus but I'm not sure for DSA.
I've attached a new version that implements your proposal. Sample output: > ./nmap --script SSH2-hostkey -p 22 localhost Starting Nmap 4.68 ( http://nmap.org ) at 2008-08-05 19:13 CEST Interesting ports on localhost (127.0.0.1): PORT STATE SERVICE 22/tcp open ssh| SSH2-Hostkey: ssh-rsa 2048 f0:58:ce:f4:aa:a4:59:1c:8e:dd:4d:07:44:c8:25:11
|_ ssh-dsa 1024 23:23:8c:73:26:22:4a:63:d8:5d:41:eb:86:cf:a0:58 Nmap done: 1 IP address (1 host up) scanned in 0.06 seconds Sample output with verbosity 2: > ./nmap --script SSH2-hostkey -p 22 localhost -vv Starting Nmap 4.68 ( http://nmap.org ) at 2008-08-05 19:12 CEST Initiating Ping Scan at 19:12 Scanning 127.0.0.1 [1 port] Completed Ping Scan at 19:12, 0.00s elapsed (1 total hosts) Initiating Connect Scan at 19:12 Scanning localhost (127.0.0.1) [1 port] Discovered open port 22/tcp on 127.0.0.1 Completed Connect Scan at 19:12, 0.00s elapsed (1 total ports) SCRIPT ENGINE: Initiating script scanning. Initiating SCRIPT ENGINE at 19:12 Completed SCRIPT ENGINE at 19:12, 0.03s elapsed Host localhost (127.0.0.1) appears to be up ... good. Scanned at 2008-08-05 19:12:40 CEST for 0s Interesting ports on localhost (127.0.0.1): PORT STATE SERVICE 22/tcp open ssh| SSH2-Hostkey: ssh-rsa 2048 f0:58:ce:f4:aa:a4:59:1c:8e:dd:4d:07:44:c8:25:11 AAAAB3NzaC1yc2EAAAABIwAAAQEAwVuv2gcr0maaKQ69VVIEv2ob4OxnuI64fkeOnCXD1lUx5tTA+vefXUWEMxgMuA7iX4irJHy2zer0NQ3Z3yJvr5scPgTYIaEOp5Uo/eGFG9Agpk5wE8CoF0e47iCAPHqzlmP2V7aNURLMODb3jVZuI07A2ZRrMGrD8d888E2ORVORv1rYeTYCqcMMoVFmX9l3gWEdk4yx3w5sD8v501Iuyd1v19mPfyhrI5E1E1nl/Xjp5N0/xP2GUBrdkDMxKaxqTPMie/f0dXBUPQQN697a5q+5lBRPhKYOtn6yQKCd9s1Q22nxn72Jmi1RzbMyYJ52FosDT755Qmb46GLrDMaZMQ== |_ ssh-dsa 1024 23:23:8c:73:26:22:4a:63:d8:5d:41:eb:86:cf:a0:58 AAAAB3NzaC1kc3MAAACBAJD6ApUbSAGL/jKRaxE0QQLGB3eH7sEPxAFYhWz1nEiwOIh50ONd0Nr2UAFsQlYvnk7Bchx7tElWP57eHpyr9BWZwFOTQQAEM77dKNbUzqQhoSppRqnbFjErTp/PnvwY95M05Kdm98MnxA6ngE4Nz8C0eL69sm/oFRQ6ahGmWcSLAAAAFQCW+NG4KsuIgk/9LuuKmUy/9MMQ1wAAAIA8vwBaH5evPRJi1rmo/QGhJiC8iQCnwbXqwnJGVIWFvYuofQCERs0xzfcrMOi8J3AMd1qhOjUC0YTg6xXtxPlW3Un7cmLcia3IVPUewjsNfLUIQ6TVXqAP8yU9elSE39zrBNrC0o30K2fMDB/ngn+ml/G9gd0/W0XStfx8svglsQAAAIEAgXXWoZej/rbTwTd61Gz+XpLwwqJkPT9EHgPVSVRD399BN3zxP9ghib+K9c6snavFvhWxrTgU/ZZZmiyOwOMcltp08REErOj5U54dzM/hYbYio0Ke83y1/llnFwoOimCHdJ0NSr/a69ZudNN3j8651ufIp13kDETBmEMMCGy8OqY=
Read data files from: . Nmap done: 1 IP address (1 host up) scanned in 0.10 seconds Cheers, Sven -- Sven Klemm http://cthulhu.c3d2.de/~sven/
id = "SSH2-Hostkey" author = "Sven Klemm <sven () c3d2 de>" description = "Show SSH2 Hostkey" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"safe"} require("stdnse") require("shortport") require("openssl") require("bin") require("base64") require("hash") portrule = shortport.port_or_service(22, "ssh") local ssh2 ssh2 = { transport = { build = function( payload ) local packet_length, padding_length padding_length = 8 - ( (payload:len() + 1 + 4 ) % 8 ) packet_length = payload:len() + padding_length + 1 return bin.pack( ">IcAA", packet_length, padding_length, payload, openssl.rand_pseudo_bytes( padding_length ) ) end, payload = function( packet ) local packet_length, padding_length, payload_length, payload, offset offset, packet_length, padding_length = bin.unpack( ">Ic", packet ) payload_length = packet_length - padding_length - 1 offset, payload = bin.unpack( ">A" .. payload_length, packet, offset ) return payload end, dh_gex_request = function( min, opt, max ) return bin.pack( ">cIII", 34, min, opt, max ) end, kexdh_init = function( e ) return bin.pack( ">cIA", 30, e:num_bytes(), e:to_bin() ) end, kex_init = function( cookie, options ) options = options or {} kex_algorithms = "diffie-hellman-group1-sha1" host_key_algorithms = options['host_key_algorithms'] or "ssh-dss,ssh-rsa" encryption_algorithms = "aes128-cbc,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr" mac_algorithms = "hmac-md5,hmac-sha1,hmac-ripemd160" compression_algorithms = "none" languages = "" local payload = bin.pack( ">cAaa", 20, cookie, kex_algorithms, host_key_algorithms ) payload = payload .. bin.pack( ">aa", encryption_algorithms, encryption_algorithms ) payload = payload .. bin.pack( ">aa", mac_algorithms, mac_algorithms ) payload = payload .. bin.pack( ">aa", compression_algorithms, compression_algorithms ) payload = payload .. bin.pack( ">aa", languages, languages ) payload = payload .. bin.pack( ">cI", 0, 0 ) return payload end }, fetch_host_key = function( host, port, key_type ) local socket = nmap.new_socket() local catch = function() socket:close() end local try = nmap.new_try(catch) -- oakley group 2 prime taken from rfc 2409 local prime = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF" try(socket:connect(host.ip, port.number)) -- fetch banner try(socket:receive_lines(1)) -- send our banner try(socket:send("SSH-2.0-Nmap-SSH2-Hostkey\r\n")) local cookie = openssl.rand_bytes( 16 ) local packet = ssh2.transport.build( ssh2.transport.kex_init( cookie, {host_key_algorithms=key_type} ) ) try(socket:send( packet )) local kex_init = try(socket:receive_bytes(1)) kex_init = ssh2.transport.payload( kex_init ) -- check for proper msg code if kex_init:byte(1) ~= 20 then return end local e, g, x, p -- e = g^x mod p g = openssl.bignum_dec2bn( "2" ) p = openssl.bignum_hex2bn( prime ) x = openssl.bignum_pseudo_rand( 1024 ) e = openssl.bignum_mod_exp( g, p, x ) packet = ssh2.transport.build( ssh2.transport.kexdh_init( e ) ) try(socket:send( packet )) local kexdh_reply = try(socket:receive_bytes(1)) kexdh_reply = ssh2.transport.payload( kexdh_reply ) -- check for proper msg code if kexdh_reply:byte(1) ~= 31 then return end local public_host_key _, _, public_host_key = bin.unpack( ">ca", kexdh_reply ) return public_host_key end } local format_fingerprint = function( fp ) local s = fp:sub( 1, 2 ) for i = 3, #fp, 2 do s = s .. ':' .. fp:sub( i, i + 1 ) end return s end action = function(host, port) local output = "" local rsa_key = ssh2.fetch_host_key( host, port, "ssh-rsa" ) if rsa_key then local key_type, e, n _, key_type, e, n = bin.unpack( ">aaa", rsa_key ) output = output .. "ssh-rsa " .. openssl.bignum_bin2bn( n ):num_bits() .. " " .. format_fingerprint( hash.md5( rsa_key ) ) if nmap.verbosity() > 1 then output = output .. ' ' .. base64.enc( rsa_key ) end output = output .. '\n' end local dsa_key = ssh2.fetch_host_key( host, port, "ssh-dss" ) if dsa_key then local key_type,p,q,g,y _, key_type, p, q, g, y = bin.unpack( ">aaaaaa", dsa_key ) output = output .. "ssh-dsa " .. openssl.bignum_bin2bn( p ):num_bits() .. " " .. format_fingerprint( hash.md5( dsa_key ) ) if nmap.verbosity() > 1 then output = output .. ' ' .. base64.enc( dsa_key ) end end return output end
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://SecLists.Org
Current thread:
- [NSE script] SSH2 hostkey Sven Klemm (Aug 05)
- Re: [NSE script] SSH2 hostkey Brandon Enright (Aug 05)
- Re: [NSE script] SSH2 hostkey Sven Klemm (Aug 05)
- Re: [NSE script] SSH2 hostkey Brandon Enright (Aug 05)