mirror of
https://github.com/nmap/nmap.git
synced 2026-01-01 12:29:03 +00:00
Structured output for sslv2, s/cypher/cipher/
This commit is contained in:
@@ -2,6 +2,8 @@ local nmap = require "nmap"
|
||||
local shortport = require "shortport"
|
||||
local string = require "string"
|
||||
local table = require "table"
|
||||
local bin = require "bin"
|
||||
local stdnse = require "stdnse"
|
||||
|
||||
description = [[
|
||||
Determines whether the server supports obsolete and less secure SSLv2, and discovers which ciphers it
|
||||
@@ -11,13 +13,28 @@ supports.
|
||||
---
|
||||
--@output
|
||||
-- 443/tcp open https syn-ack
|
||||
-- | sslv2: server still supports SSLv2
|
||||
-- | SSL2_RC4_128_WITH_MD5
|
||||
-- | SSL2_DES_192_EDE3_CBC_WITH_MD5
|
||||
-- | SSL2_RC2_CBC_128_CBC_WITH_MD5
|
||||
-- | SSL2_DES_64_CBC_WITH_MD5
|
||||
-- | SSL2_RC4_128_EXPORT40_WITH_MD5
|
||||
-- |_ SSL2_RC2_CBC_128_CBC_WITH_MD5
|
||||
-- | sslv2:
|
||||
-- | SSLv2 supported
|
||||
-- | ciphers:
|
||||
-- | SSL2_DES_192_EDE3_CBC_WITH_MD5
|
||||
-- | SSL2_IDEA_128_CBC_WITH_MD5
|
||||
-- | SSL2_RC2_CBC_128_CBC_WITH_MD5
|
||||
-- | SSL2_RC4_128_WITH_MD5
|
||||
-- | SSL2_DES_64_CBC_WITH_MD5
|
||||
-- | SSL2_RC2_CBC_128_CBC_WITH_MD5
|
||||
-- |_ SSL2_RC4_128_EXPORT40_WITH_MD5
|
||||
--@xmloutput
|
||||
--<elem>SSLv2 supported</elem>
|
||||
--<table key="ciphers">
|
||||
-- <elem>SSL2_DES_192_EDE3_CBC_WITH_MD5</elem>
|
||||
-- <elem>SSL2_IDEA_128_CBC_WITH_MD5</elem>
|
||||
-- <elem>SSL2_RC2_CBC_128_CBC_WITH_MD5</elem>
|
||||
-- <elem>SSL2_RC4_128_WITH_MD5</elem>
|
||||
-- <elem>SSL2_DES_64_CBC_WITH_MD5</elem>
|
||||
-- <elem>SSL2_RC2_CBC_128_CBC_WITH_MD5</elem>
|
||||
-- <elem>SSL2_RC4_128_EXPORT40_WITH_MD5</elem>
|
||||
--</table>
|
||||
|
||||
|
||||
author = "Matthew Boyle"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
@@ -27,7 +44,7 @@ categories = {"default", "safe"}
|
||||
|
||||
portrule = shortport.ssl
|
||||
|
||||
hex2dec = function(hex)
|
||||
local hex2dec = function(hex)
|
||||
|
||||
local byte1, byte2;
|
||||
|
||||
@@ -40,18 +57,16 @@ hex2dec = function(hex)
|
||||
|
||||
end
|
||||
|
||||
cyphers = function(cypher_list, len)
|
||||
local ciphers = function(cipher_list, len)
|
||||
|
||||
-- returns names of cyphers supported by the server
|
||||
-- returns names of ciphers supported by the server
|
||||
|
||||
local cypher;
|
||||
local cypher_name;
|
||||
local byte1, byte2, byte3;
|
||||
local available_cyphers = "";
|
||||
local seen = {}
|
||||
local available_ciphers = {}
|
||||
local idx = 0;
|
||||
|
||||
local ssl_cyphers = {
|
||||
-- (cut down) table of codes with their corresponding cyphers.
|
||||
local ssl_ciphers = {
|
||||
-- (cut down) table of codes with their corresponding ciphers.
|
||||
-- inspired by Wireshark's 'epan/dissectors/packet-ssl-utils.h'
|
||||
[0x010080] = "SSL2_RC4_128_WITH_MD5",
|
||||
[0x020080] = "SSL2_RC4_128_EXPORT40_WITH_MD5",
|
||||
@@ -65,36 +80,30 @@ cyphers = function(cypher_list, len)
|
||||
|
||||
if (len == 0) then return "none"; end
|
||||
-- something's got broken along the way if these aren't equal
|
||||
if (len ~= #cypher_list) then
|
||||
return "";
|
||||
if (len ~= #cipher_list) then
|
||||
return nil
|
||||
end
|
||||
|
||||
for idx = 1, len, 3 do
|
||||
cypher = string.sub(cypher_list, idx, idx + 2);
|
||||
local _, cipher = bin.unpack(">I", "\x00" .. string.sub(cipher_list, idx, idx + 2))
|
||||
local cipher_name = ssl_ciphers[cipher];
|
||||
|
||||
byte1 = string.byte(cypher, 1);
|
||||
byte2 = string.byte(cypher, 2);
|
||||
byte3 = string.byte(cypher, 3);
|
||||
|
||||
cypher = (byte1 * 256 * 256) + (byte2 * 256) + byte3;
|
||||
|
||||
cypher_name = ssl_cyphers[cypher];
|
||||
|
||||
if (cypher_name == nil) then
|
||||
cypher_name = "unknown cypher (" .. byte1 .. "-" .. byte2 .. "-" .. byte3 .. " dec)"
|
||||
if (cipher_name == nil) then
|
||||
cipher_name = string.format("0x%06x", cipher)
|
||||
end
|
||||
|
||||
-- Check for duplicate cyphers
|
||||
if not available_cyphers:match("\t" .. cypher_name .. "\n") then
|
||||
available_cyphers = available_cyphers .. "\t" .. cypher_name .. "\n";
|
||||
-- Check for duplicate ciphers
|
||||
if not seen[cipher] then
|
||||
table.insert(available_ciphers, cipher_name)
|
||||
seen[cipher] = true
|
||||
end
|
||||
end
|
||||
|
||||
return available_cyphers
|
||||
return available_ciphers
|
||||
|
||||
end
|
||||
|
||||
give_n_bytes = function(idx, n, str)
|
||||
local give_n_bytes = function(idx, n, str)
|
||||
|
||||
-- returns the next n bytes of a string
|
||||
|
||||
@@ -116,7 +125,7 @@ action = function(host, port)
|
||||
local idx = 3; -- start reading after the end of the length record
|
||||
|
||||
local return_string = "";
|
||||
local available_cyphers = "";
|
||||
local available_ciphers;
|
||||
|
||||
local ssl_v2_hello;
|
||||
local server_hello;
|
||||
@@ -127,10 +136,10 @@ action = function(host, port)
|
||||
local certificate_type;
|
||||
local ssl_version;
|
||||
local certificate_len;
|
||||
local cyphers_len;
|
||||
local ciphers_len;
|
||||
local certificate;
|
||||
local connection_ID_len;
|
||||
local cypher_list;
|
||||
local cipher_list;
|
||||
local connection_ID;
|
||||
|
||||
-- build client hello packet (contents inspired by
|
||||
@@ -197,12 +206,12 @@ action = function(host, port)
|
||||
idx, ssl_version = give_n_bytes(idx, 2, server_hello);
|
||||
idx, certificate_len = give_n_bytes(idx, 2, server_hello);
|
||||
certificate_len = hex2dec(certificate_len);
|
||||
idx, cyphers_len = give_n_bytes(idx, 2, server_hello);
|
||||
cyphers_len = hex2dec(cyphers_len);
|
||||
idx, ciphers_len = give_n_bytes(idx, 2, server_hello);
|
||||
ciphers_len = hex2dec(ciphers_len);
|
||||
idx, connection_ID_len = give_n_bytes(idx, 2, server_hello);
|
||||
connection_ID_len = hex2dec(connection_ID_len);
|
||||
idx, certificate = give_n_bytes(idx, certificate_len, server_hello);
|
||||
idx, cypher_list = give_n_bytes(idx, cyphers_len, server_hello);
|
||||
idx, cipher_list = give_n_bytes(idx, ciphers_len, server_hello);
|
||||
idx, connection_ID = give_n_bytes(idx, connection_ID_len, server_hello);
|
||||
|
||||
-- some sanity checks:
|
||||
@@ -215,20 +224,15 @@ action = function(host, port)
|
||||
return;
|
||||
end
|
||||
|
||||
-- get a list of cyphers offered
|
||||
available_cyphers = cyphers(cypher_list, cyphers_len);
|
||||
-- get a list of ciphers offered
|
||||
available_ciphers = ciphers(cipher_list, ciphers_len);
|
||||
|
||||
-- actually run some tests:
|
||||
o = stdnse.output_table()
|
||||
if (ssl_version == string.char(0x00, 0x02)) then
|
||||
if (available_cyphers == "none") then
|
||||
return_string = "server supports SSLv2 protocol, but no SSLv2 cyphers\n";
|
||||
else
|
||||
return_string = "server still supports SSLv2\n";
|
||||
if (nmap.verbosity() > 1 or nmap.debugging() > 0) then
|
||||
return_string = return_string .. available_cyphers;
|
||||
end
|
||||
end
|
||||
table.insert(o, "SSLv2 supported")
|
||||
o["ciphers"] = available_ciphers
|
||||
end
|
||||
|
||||
return return_string;
|
||||
return o;
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user