Last active
August 29, 2015 13:57
-
-
Save bonsaiviking/9921180 to your computer and use it in GitHub Desktop.
Nmap NSE script to check for TLS Extended Random support. Requires Nmap (http://nmap.org) and the latest version of the tls.lua library from https://svn.nmap.org/nmap/nselib/tls.lua
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local nmap = require "nmap" | |
local shortport = require "shortport" | |
local stdnse = require "stdnse" | |
local bin = require "bin" | |
local tls = require "tls" | |
description = [[ | |
Checks for server support of the Extended Random TLS extension, which was | |
allegedly created to make exploitation of the Dual EC DRBG weakness easier. The | |
extension was never widely adopted, and IANA did not assign an ExtensionType | |
number, but the RSA BSAFE library uses 0x0028 for this purpose. Note that if | |
this extension number is used for some other purpose, it is possible that this | |
script will return a false-positive. | |
References: | |
* http://tools.ietf.org/html/draft-rescorla-tls-extended-random-02 | |
* https://developer-content.emc.com/docs/rsashare/share_for_c/1.1/api_guide/group___t_l_s___e_x_t___t_y_p_e.html | |
* https://projectbullrun.org/dual-ec/ext-rand.html | |
]] | |
--- | |
-- @usage | |
-- nmap --script=tls-extended-random <targets> | |
-- | |
--@output | |
-- 443/tcp open https | |
-- |_tls-extended-random: Supported. | |
-- | |
-- @xmloutput | |
-- <elem>true</elem> | |
author = "Daniel Miller" | |
license = "Same as Nmap--See http://nmap.org/book/man-legal.html" | |
categories = {"discovery", "safe"} | |
portrule = shortport.ssl | |
local RANDDATA = "DUAL_EC DRBG YO!" | |
--- Function that sends a client hello packet with the TLS Extended Random extension to the | |
-- target host and returns the response | |
--@args host The target host table. | |
--@args port The target port table. | |
--@return status true if response, false else. | |
--@return response if status is true. | |
local client_hello = function(host, port) | |
local sock, status, response, err, cli_h | |
cli_h = tls.client_hello({ | |
["protocol"] = "TLSv1.0", | |
["ciphers"] = { | |
"TLS_ECDHE_RSA_WITH_RC4_128_SHA", | |
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA", | |
"TLS_RSA_WITH_RC4_128_MD5", | |
}, | |
["compressors"] = {"NULL"}, | |
["extensions"] = { | |
[0x0028] = bin.pack(">P", RANDDATA) | |
}, | |
}) | |
-- Connect to the target server | |
sock = nmap.new_socket() | |
sock:set_timeout(5000) | |
status, err = sock:connect(host, port) | |
if not status then | |
sock:close() | |
stdnse.print_debug("Can't send: %s", err) | |
return false | |
end | |
-- Send Client Hello to the target server | |
status, err = sock:send(cli_h) | |
if not status then | |
stdnse.print_debug("Couldn't send: %s", err) | |
sock:close() | |
return false | |
end | |
-- Read response | |
status, response, err = tls.record_buffer(sock) | |
if not status then | |
stdnse.print_debug("Couldn't receive: %s", err) | |
sock:close() | |
return false | |
end | |
return true, response | |
end | |
--- Function that checks for the response to a Extended Random extension request. | |
--@args response Response to parse. | |
--@return results The random data generated by the server, or nil if the extension is not supported | |
local check_rand = function(response) | |
local i, record = tls.record_read(response, 0) | |
if record == nil then | |
stdnse.print_debug("%s: Unknown response from server", SCRIPT_NAME) | |
return nil | |
end | |
if record.type == "handshake" and record.body[1].type == "server_hello" then | |
if record.body[1].extensions == nil then | |
stdnse.print_debug("%s: Server does not support TLS Extended Random extension.", SCRIPT_NAME) | |
return nil | |
end | |
local randdata = record.body[1].extensions[0x0028] | |
if randdata == nil then | |
stdnse.print_debug("%s: Server does not support TLS Extended Random extension.", SCRIPT_NAME) | |
return nil | |
end | |
-- Parse data | |
local _, results = bin.unpack(">P", randdata, 0) | |
return results | |
else | |
stdnse.print_debug("%s: Server response was not server_hello", SCRIPT_NAME) | |
return nil | |
end | |
end | |
action = function(host, port) | |
local status, response | |
-- Send crafted client hello | |
status, response = client_hello(host, port) | |
if status and response then | |
-- Analyze response | |
local results = check_rand(response) | |
if results then --#results == #RANDDATA then | |
return true, "Supported." | |
end | |
end | |
return nil | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment