Skip to content

Instantly share code, notes, and snippets.

Created March 25, 2015 19:04
Show Gist options
  • Save bonsaiviking/bbfb168db99371f76e40 to your computer and use it in GitHub Desktop.
Save bonsaiviking/bbfb168db99371f76e40 to your computer and use it in GitHub Desktop.
tls-hellofirst - Audit TLS implementations for handshake reversal.
local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
local table = require "table"
local bin = require "bin"
local tls = require "tls"
description = [[
Tries to confuse a TLS server into sending a ClientHello by first sending a HelloRequest.
No server implementations are known to be vulnerable
-- @usage
-- nmap --script=tls-hellofirst
-- 443/tcp open https
-- | tls-hellofirst:
-- | type: handshake
-- | body:
-- |
-- | type: client_hello
-- | data: \x00\x00U\x12\xF8{j\xEA\x05fp\xD4\xDA\xA0\xE4s8\x83\xD5!.:\x89S\x7F\xA1\xAC\xCE\xEB\x87e\xBA\x94\x0C\x00\x00\x08\x00\x04\x00\x05\x00 \x00
-- | \x01\x00
-- | length: 51
-- |_ protocol: TLSv1.0
-- @xmloutput
-- <elem key="type">handshake</elem>
-- <table key="body">
-- <table>
-- <elem key="type">client_hello</elem>
-- <elem key="data">\x00\x00U\x12\xF8{j\xEA\x05fp\xD4\xDA\xA0\xE4s8\x83\xD5!.:\x89S\x7F\xA1\xAC\xCE\xEB\x87e\xBA\x94\x0C\x00\x00\x08\x00\x04\x00\x05\x00&#x9;\x00&#xa;\x01\x00</elem>
-- </table>
-- </table>
-- <elem key="length">51</elem>
-- <elem key="protocol">TLSv1.0</elem>
author = "Daniel Miller"
license = "Same as Nmap--See"
categories = {"discovery"}
portrule = shortport.ssl
local wrong_hello = function(host, port)
local hello_request = tls.record_write( "handshake", "SSLv3",
bin.pack(">Cxxx", tls.TLS_HANDSHAKETYPE_REGISTRY["hello_request"]))
-- Connect to the target server
local sock = nmap.new_socket()
local ct = stdnse.get_timeout(host)
-- fast timeout for TCP connect
local status, err = sock:connect(host, port)
if not status then
stdnse.debug1("Can't send: %s", err)
return false
-- slower timeout for TLS host processing
-- Some services send stuff right away: that's not what we're looking for
-- Example: osiris Host IDS agent sends a client_hello immediately on connect.
status, err = sock:receive_bytes(1)
if status then
stdnse.debug1("Service isn't server TLS (Sent data first)")
return false
-- Send HelloRequest to the target server
status, err = sock:send(hello_request)
if not status then
stdnse.debug1("Couldn't send: %s", err)
return false
-- Read response
local response
status, response, err = tls.record_buffer(sock)
if not status then
stdnse.debug1("Couldn't receive: %s", err)
return false
return true, response
local check_response = function(response)
local i, record = tls.record_read(response, 0)
if record == nil then
stdnse.debug1("Unknown response from server")
return nil
if record.type == "alert" then
stdnse.debug1("Server properly sent alert")
return nil
return record
action = function(host, port)
local status, response
-- Send hello-request
status, response = wrong_hello(host, port)
if status and response then
-- Analyze response
local results = check_response(response)
return results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment