mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 05:01:29 +00:00
Add tls.servername script-arg. Closes #540
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
# Nmap Changelog ($Id$); -*-text-*-
|
# Nmap Changelog ($Id$); -*-text-*-
|
||||||
|
|
||||||
|
o [NSE][GH#540] Add tls.servername script-arg for forcing a name to be used for
|
||||||
|
TLS Server Name Indication extension. The argument overrides the default use
|
||||||
|
of the host's targetname. [Bertrand Bonnefoy-Claudet]
|
||||||
|
|
||||||
o [NSE] Script fingerprint-strings will print the ASCII strings it finds in the
|
o [NSE] Script fingerprint-strings will print the ASCII strings it finds in the
|
||||||
service fingerprints that Nmap shows for unidentified services. [Daniel Miller]
|
service fingerprints that Nmap shows for unidentified services. [Daniel Miller]
|
||||||
|
|
||||||
|
|||||||
@@ -1502,4 +1502,20 @@ function record_buffer(sock, buffer, i)
|
|||||||
return true, buffer
|
return true, buffer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Get a server_name for use with the TLS Server Name Indication extension.
|
||||||
|
--
|
||||||
|
-- This returns the value of the script argument "tls.servername" if given. Otherwise, it
|
||||||
|
-- returns the target name of the host parameter.
|
||||||
|
--
|
||||||
|
-- @param host Host table as received by the action function
|
||||||
|
-- @return String of the selected host name
|
||||||
|
function servername(host)
|
||||||
|
local script_arg = stdnse.get_script_args("tls.servername")
|
||||||
|
if script_arg then
|
||||||
|
return script_arg
|
||||||
|
elseif type(host) == "table" then
|
||||||
|
return host.targetname
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return _ENV;
|
return _ENV;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ local shortport = require "shortport"
|
|||||||
local sslcert = require "sslcert"
|
local sslcert = require "sslcert"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local string = require "string"
|
local string = require "string"
|
||||||
|
local tls = require "tls"
|
||||||
local unicode = require "unicode"
|
local unicode = require "unicode"
|
||||||
|
|
||||||
description = [[
|
description = [[
|
||||||
@@ -264,6 +265,7 @@ local function output_str(cert)
|
|||||||
end
|
end
|
||||||
|
|
||||||
action = function(host, port)
|
action = function(host, port)
|
||||||
|
host.targetname = tls.servername(host)
|
||||||
local status, cert = sslcert.getCertificate(host, port)
|
local status, cert = sslcert.getCertificate(host, port)
|
||||||
if ( not(status) ) then
|
if ( not(status) ) then
|
||||||
stdnse.debug1("getCertificate error: %s", cert or "unknown")
|
stdnse.debug1("getCertificate error: %s", cert or "unknown")
|
||||||
|
|||||||
@@ -633,11 +633,10 @@ local function get_dhe_params(host, port, protocol, ciphers)
|
|||||||
local t = {}
|
local t = {}
|
||||||
local pos = 1
|
local pos = 1
|
||||||
t.protocol = protocol
|
t.protocol = protocol
|
||||||
t.extensions = {}
|
local tlsname = tls.servername(host)
|
||||||
|
t.extensions = {
|
||||||
if host.targetname then
|
server_name = tlsname and tls.EXTENSION_HELPERS["server_name"](tlsname),
|
||||||
t.extensions.server_name = tls.EXTENSION_HELPERS.server_name(host.targetname)
|
}
|
||||||
end
|
|
||||||
|
|
||||||
-- Keep ClientHello record size below 255 bytes and the number of ciphersuites
|
-- Keep ClientHello record size below 255 bytes and the number of ciphersuites
|
||||||
-- to 64 or less in order to avoid implementation issues with some TLS servers
|
-- to 64 or less in order to avoid implementation issues with some TLS servers
|
||||||
|
|||||||
@@ -499,26 +499,17 @@ local function remove_high_byte_ciphers(t)
|
|||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Claim to support every elliptic curve and EC point format
|
-- Get TLS extensions
|
||||||
local base_extensions = {
|
local function base_extensions(host)
|
||||||
-- Claim to support every elliptic curve
|
local tlsname = tls.servername(host)
|
||||||
["elliptic_curves"] = tls.EXTENSION_HELPERS["elliptic_curves"](sorted_keys(tls.ELLIPTIC_CURVES)),
|
return {
|
||||||
-- Claim to support every EC point format
|
-- Claim to support every elliptic curve
|
||||||
["ec_point_formats"] = tls.EXTENSION_HELPERS["ec_point_formats"](sorted_keys(tls.EC_POINT_FORMATS)),
|
["elliptic_curves"] = tls.EXTENSION_HELPERS["elliptic_curves"](sorted_keys(tls.ELLIPTIC_CURVES)),
|
||||||
}
|
-- Claim to support every EC point format
|
||||||
|
["ec_point_formats"] = tls.EXTENSION_HELPERS["ec_point_formats"](sorted_keys(tls.EC_POINT_FORMATS)),
|
||||||
-- Recursively copy a table.
|
-- Enable SNI if a server name is available
|
||||||
-- Only recurs when a value is a table, other values are copied by assignment.
|
["server_name"] = tlsname and tls.EXTENSION_HELPERS["server_name"](tlsname),
|
||||||
local function tcopy (t)
|
}
|
||||||
local tc = {};
|
|
||||||
for k,v in pairs(t) do
|
|
||||||
if type(v) == "table" then
|
|
||||||
tc[k] = tcopy(v);
|
|
||||||
else
|
|
||||||
tc[k] = v;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return tc;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get a message body from a record which has the specified property set to value
|
-- Get a message body from a record which has the specified property set to value
|
||||||
@@ -587,11 +578,8 @@ local function find_ciphers_group(host, port, protocol, group, scores)
|
|||||||
local results = {}
|
local results = {}
|
||||||
local t = {
|
local t = {
|
||||||
["protocol"] = protocol,
|
["protocol"] = protocol,
|
||||||
["extensions"] = tcopy(base_extensions),
|
["extensions"] = base_extensions(host),
|
||||||
}
|
}
|
||||||
if host.targetname then
|
|
||||||
t["extensions"]["server_name"] = tls.EXTENSION_HELPERS["server_name"](host.targetname)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- This is a hacky sort of tristate variable. There are three conditions:
|
-- This is a hacky sort of tristate variable. There are three conditions:
|
||||||
-- 1. false = either ciphers or protocol is bad. Keep trying with new ciphers
|
-- 1. false = either ciphers or protocol is bad. Keep trying with new ciphers
|
||||||
@@ -775,11 +763,8 @@ local function get_chunk_size(host, protocol)
|
|||||||
local len_t = {
|
local len_t = {
|
||||||
protocol = protocol,
|
protocol = protocol,
|
||||||
ciphers = {},
|
ciphers = {},
|
||||||
extensions = tcopy(base_extensions),
|
extensions = base_extensions(host),
|
||||||
}
|
}
|
||||||
if host.targetname then
|
|
||||||
len_t.extensions.server_name = tls.EXTENSION_HELPERS.server_name(host.targetname)
|
|
||||||
end
|
|
||||||
local cipher_len_remaining = 255 - #tls.client_hello(len_t)
|
local cipher_len_remaining = 255 - #tls.client_hello(len_t)
|
||||||
-- if we're over 255 anyway, just go for it.
|
-- if we're over 255 anyway, just go for it.
|
||||||
-- Each cipher adds 2 bytes
|
-- Each cipher adds 2 bytes
|
||||||
@@ -815,11 +800,8 @@ local function find_compressors(host, port, protocol, good_ciphers)
|
|||||||
local t = {
|
local t = {
|
||||||
["protocol"] = protocol,
|
["protocol"] = protocol,
|
||||||
["ciphers"] = good_ciphers,
|
["ciphers"] = good_ciphers,
|
||||||
["extensions"] = tcopy(base_extensions),
|
["extensions"] = base_extensions(host),
|
||||||
}
|
}
|
||||||
if host.targetname then
|
|
||||||
t["extensions"]["server_name"] = tls.EXTENSION_HELPERS["server_name"](host.targetname)
|
|
||||||
end
|
|
||||||
|
|
||||||
local results = {}
|
local results = {}
|
||||||
|
|
||||||
@@ -896,11 +878,8 @@ local function compare_ciphers(host, port, protocol, cipher_a, cipher_b)
|
|||||||
local t = {
|
local t = {
|
||||||
["protocol"] = protocol,
|
["protocol"] = protocol,
|
||||||
["ciphers"] = {cipher_a, cipher_b},
|
["ciphers"] = {cipher_a, cipher_b},
|
||||||
["extensions"] = tcopy(base_extensions),
|
["extensions"] = base_extensions(host),
|
||||||
}
|
}
|
||||||
if host.targetname then
|
|
||||||
t["extensions"]["server_name"] = tls.EXTENSION_HELPERS["server_name"](host.targetname)
|
|
||||||
end
|
|
||||||
local records = try_params(host, port, t)
|
local records = try_params(host, port, t)
|
||||||
local server_hello = records.handshake and get_body(records.handshake, "type", "server_hello")
|
local server_hello = records.handshake and get_body(records.handshake, "type", "server_hello")
|
||||||
if server_hello then
|
if server_hello then
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ local sslcert = require "sslcert"
|
|||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local string = require "string"
|
local string = require "string"
|
||||||
local table = require "table"
|
local table = require "table"
|
||||||
|
local tls = require "tls"
|
||||||
|
|
||||||
description = [[
|
description = [[
|
||||||
Queries Google's Certificate Catalog for the SSL certificates retrieved from
|
Queries Google's Certificate Catalog for the SSL certificates retrieved from
|
||||||
@@ -41,6 +42,7 @@ end
|
|||||||
portrule = shortport.ssl
|
portrule = shortport.ssl
|
||||||
|
|
||||||
action = function(host, port)
|
action = function(host, port)
|
||||||
|
host.targetname = tls.servername(host)
|
||||||
local lines, sha1, query
|
local lines, sha1, query
|
||||||
local status, cert = sslcert.getCertificate(host, port)
|
local status, cert = sslcert.getCertificate(host, port)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ local nmap = require "nmap"
|
|||||||
local shortport = require "shortport"
|
local shortport = require "shortport"
|
||||||
local stdnse = require "stdnse"
|
local stdnse = require "stdnse"
|
||||||
local sslcert = require "sslcert"
|
local sslcert = require "sslcert"
|
||||||
|
local tls = require "tls"
|
||||||
local bin = require "bin"
|
local bin = require "bin"
|
||||||
|
|
||||||
-- -*- mode: lua -*-
|
-- -*- mode: lua -*-
|
||||||
@@ -108,6 +109,7 @@ portrule = shortport.ssl
|
|||||||
|
|
||||||
action = function(host, port)
|
action = function(host, port)
|
||||||
-- Get script arguments.
|
-- Get script arguments.
|
||||||
|
host.targetname = tls.servername(host)
|
||||||
local path = stdnse.get_script_args("ssl-known-key.fingerprintfile") or FINGERPRINT_FILE
|
local path = stdnse.get_script_args("ssl-known-key.fingerprintfile") or FINGERPRINT_FILE
|
||||||
local status, result = get_fingerprints(path)
|
local status, result = get_fingerprints(path)
|
||||||
if not status then
|
if not status then
|
||||||
|
|||||||
@@ -174,13 +174,17 @@ local function remove_high_byte_ciphers(t)
|
|||||||
return output
|
return output
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Claim to support every elliptic curve and EC point format
|
local function base_extensions(host)
|
||||||
local base_extensions = {
|
local tlsname = tls.servername(host)
|
||||||
-- Claim to support every elliptic curve
|
return {
|
||||||
["elliptic_curves"] = tls.EXTENSION_HELPERS["elliptic_curves"](sorted_keys(tls.ELLIPTIC_CURVES)),
|
-- Claim to support every elliptic curve
|
||||||
-- Claim to support every EC point format
|
["elliptic_curves"] = tls.EXTENSION_HELPERS["elliptic_curves"](sorted_keys(tls.ELLIPTIC_CURVES)),
|
||||||
["ec_point_formats"] = tls.EXTENSION_HELPERS["ec_point_formats"](sorted_keys(tls.EC_POINT_FORMATS)),
|
-- Claim to support every EC point format
|
||||||
}
|
["ec_point_formats"] = tls.EXTENSION_HELPERS["ec_point_formats"](sorted_keys(tls.EC_POINT_FORMATS)),
|
||||||
|
-- Enable SNI if a server name is available
|
||||||
|
["server_name"] = tlsname and tls.EXTENSION_HELPERS["server_name"](tlsname),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
-- Recursively copy a table.
|
-- Recursively copy a table.
|
||||||
-- Only recurs when a value is a table, other values are copied by assignment.
|
-- Only recurs when a value is a table, other values are copied by assignment.
|
||||||
@@ -202,11 +206,8 @@ local function find_ciphers_group(host, port, protocol, group)
|
|||||||
results = {}
|
results = {}
|
||||||
local t = {
|
local t = {
|
||||||
["protocol"] = protocol,
|
["protocol"] = protocol,
|
||||||
["extensions"] = tcopy(base_extensions),
|
["extensions"] = base_extensions(host),
|
||||||
}
|
}
|
||||||
if host.targetname then
|
|
||||||
t["extensions"]["server_name"] = tls.EXTENSION_HELPERS["server_name"](host.targetname)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- This is a hacky sort of tristate variable. There are three conditions:
|
-- This is a hacky sort of tristate variable. There are three conditions:
|
||||||
-- 1. false = either ciphers or protocol is bad. Keep trying with new ciphers
|
-- 1. false = either ciphers or protocol is bad. Keep trying with new ciphers
|
||||||
@@ -303,11 +304,8 @@ local function check_fallback_scsv(host, port, protocol, ciphers)
|
|||||||
local results = {}
|
local results = {}
|
||||||
local t = {
|
local t = {
|
||||||
["protocol"] = protocol,
|
["protocol"] = protocol,
|
||||||
["extensions"] = tcopy(base_extensions),
|
["extensions"] = base_extensions(host),
|
||||||
}
|
}
|
||||||
if host.targetname then
|
|
||||||
t["extensions"]["server_name"] = tls.EXTENSION_HELPERS["server_name"](host.targetname)
|
|
||||||
end
|
|
||||||
|
|
||||||
t["ciphers"] = tcopy(ciphers)
|
t["ciphers"] = tcopy(ciphers)
|
||||||
t.ciphers[#t.ciphers+1] = "TLS_FALLBACK_SCSV"
|
t.ciphers[#t.ciphers+1] = "TLS_FALLBACK_SCSV"
|
||||||
|
|||||||
Reference in New Issue
Block a user