1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-05 22:19:03 +00:00

Let tls-nextprotoneg use tls.lua library

Required fixes to tls lib's extensions (did not previously support
extension data)
This commit is contained in:
dmiller
2014-01-16 18:10:02 +00:00
parent 35148980ef
commit 760da1788f
2 changed files with 53 additions and 78 deletions

View File

@@ -5,6 +5,7 @@ local stdnse = require "stdnse"
local table = require "table"
local bin = require "bin"
local os = require "os"
local tls = require "tls"
description = [[
Enumerates a TLS server's supported protocols by using the next protocol negotiation extension.
@@ -52,40 +53,18 @@ portrule = shortport.ssl
local client_hello = function(host, port)
local sock, status, response, err, cli_h
-- Craft Client Hello
-- Content Type: Client Handshake
cli_h = bin.pack(">C", 0x16)
-- Version: TLS 1.0
cli_h = cli_h .. bin.pack(">S", 0x0301)
-- Length, fixed
cli_h = cli_h .. bin.pack(">S", 0x0037)
-- Handshake protocol
-- Handshake Type: Client Hello
cli_h = cli_h .. bin.pack(">C", 0x01)
-- Length, fixed
cli_h = cli_h .. bin.pack(">CS", 0x00, 0x0033)
-- Version: TLS 1.0
cli_h = cli_h .. bin.pack(">S", 0x0301)
-- Random: epoch time
cli_h = cli_h .. bin.pack(">I", os.time())
-- Random: random 28 bytes
cli_h = cli_h .. stdnse.generate_random_string(28)
-- Session ID length
cli_h = cli_h .. bin.pack(">C", 0x00)
-- Cipher Suites length
cli_h = cli_h .. bin.pack(">S", 0x0006)
-- Ciphers
cli_h = cli_h .. bin.pack(">S", 0xc011)
cli_h = cli_h .. bin.pack(">S", 0x0039)
cli_h = cli_h .. bin.pack(">S", 0x0004)
-- Compression Methods length
cli_h = cli_h .. bin.pack(">C", 0x01)
-- Compression Methods: null
cli_h = cli_h .. bin.pack(">C", 0x00)
-- Extensions length
cli_h = cli_h .. bin.pack(">S", 0x0004)
-- TLS NPN Extension
cli_h = cli_h .. bin.pack(">I", 0x33740000)
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"] = {
["next_protocol_negotiation"] = "",
},
})
-- Connect to the target server
sock = nmap.new_socket()
@@ -120,53 +99,36 @@ end
--@args response Response to parse.
--@return results List of found protocols.
local check_npn = function(response)
local results = {}
local shlength, npndata, protocol
if not response then
stdnse.print_debug(SCRIPT_NAME .. ": Didn't get response.")
return results
end
-- If content type not handshake
if string.sub(response,1,1) ~= string.char(22) then
stdnse.print_debug(SCRIPT_NAME .. ": Response type not handshake.")
return results
end
-- If handshake protocol not server hello
if string.sub(response, 6, 6) ~= string.char(02) then
stdnse.print_debug(SCRIPT_NAME .. ": Handshake response not server hello.")
return results
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
-- Get the server hello length
local _
_, shlength = bin.unpack(">S", response, 4)
local serverhello = string.sub(response, 6, 6 + shlength)
if record.type == "handshake" and record.body.type == "server_hello" then
if record.body.extensions == nil then
stdnse.print_debug("%s: Server does not support TLS NPN extension.", SCRIPT_NAME)
return nil
end
local results = {}
npndata = record.body.extensions["next_protocol_negotiation"]
if npndata == nil then
stdnse.print_debug("%s: Server does not support TLS NPN extension.", SCRIPT_NAME)
return nil
end
-- Parse data
i = 0
local protocol
while i < #npndata do
i, protocol = bin.unpack(">p", npndata, i)
table.insert(results, protocol)
end
-- If server didn't return TLS NPN extension
local npnextension, _ = string.find(serverhello, string.char(0x33) .. string.char(0x74))
if not npnextension then
stdnse.print_debug(SCRIPT_NAME .. ": Server doesn't support TLS NPN extension.")
return results
return results
else
stdnse.print_debug("%s: Server response was not server_hello", SCRIPT_NAME)
return nil
end
-- Get NPN data length
local _, npnlen = bin.unpack(">S", serverhello:sub(npnextension + 2, npnextension + 3))
if not npnlen then
return results
end
npndata = serverhello:sub(npnextension + 4, npnextension + 4 + npnlen)
-- Parse data
local i, len = 1
while i < #npndata do
len = npndata:byte(i)
protocol = npndata:sub(i+1, i+len)
table.insert(results, protocol)
i = i + len + 1
end
return results
end
action = function(host, port)