mirror of
https://github.com/nmap/nmap.git
synced 2026-01-27 16:49:01 +00:00
Add TLS_FALLBACK_SCSV checking to ssl-poodle
This commit is contained in:
@@ -68,6 +68,7 @@ TLS_ALERT_REGISTRY = {
|
||||
["protocol_version"] = 70,
|
||||
["insufficient_security"] = 71,
|
||||
["internal_error"] = 80,
|
||||
["inappropriate_fallback"] = 86,
|
||||
["user_canceled"] = 90,
|
||||
["no_renegotiation"] = 100,
|
||||
["unsupported_extension"] = 110,
|
||||
@@ -398,7 +399,6 @@ CIPHERS = {
|
||||
["TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"] = 0x00BD,
|
||||
["TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"] = 0x00BE,
|
||||
["TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"] = 0x00BF,
|
||||
["TLS_EMPTY_RENEGOTIATION_INFO_SCSV"] = 0x00FF,
|
||||
["TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"] = 0x00C0,
|
||||
["TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"] = 0x00C1,
|
||||
["TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"] = 0x00C2,
|
||||
@@ -583,6 +583,11 @@ CIPHERS = {
|
||||
["SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"] = 0xFEFF,
|
||||
}
|
||||
|
||||
SCSVS = {
|
||||
["TLS_EMPTY_RENEGOTIATION_INFO_SCSV"] = 0x00FF, -- rfc5746
|
||||
["TLS_FALLBACK_SCSV"] = 0x5600, -- draft-ietf-tls-downgrade-scsv-00
|
||||
}
|
||||
|
||||
local function find_key(t, value)
|
||||
local k, v
|
||||
|
||||
@@ -768,7 +773,14 @@ function client_hello(t)
|
||||
if t["ciphers"] ~= nil then
|
||||
-- Add specified ciphers.
|
||||
for _, cipher in pairs(t["ciphers"]) do
|
||||
table.insert(ciphers, bin.pack(">S", CIPHERS[cipher]))
|
||||
if type(cipher) == "string" then
|
||||
cipher = CIPHERS[cipher] or SCSVS[cipher]
|
||||
end
|
||||
if type(cipher) == "number" and cipher > 0 and cipher <= 0xffff then
|
||||
table.insert(ciphers, bin.pack(">S", cipher))
|
||||
else
|
||||
stdnse.debug1("Unknown cipher in client_hello: %s", cipher)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Use NULL cipher
|
||||
|
||||
@@ -226,7 +226,7 @@ local function find_ciphers_group(host, port, protocol, group)
|
||||
ctx_log(1, protocol, "%d ciphers and/or protocol rejected. (No handshake)", #group)
|
||||
end
|
||||
break
|
||||
elseif record["protocol"] ~= protocol then
|
||||
elseif record["protocol"] ~= protocol or record["body"][1]["protocol"] and record.body[1].protocol ~= protocol then
|
||||
ctx_log(1, protocol, "Protocol rejected.")
|
||||
protocol_worked = nil
|
||||
break
|
||||
@@ -299,6 +299,29 @@ local function find_ciphers(host, port, protocol)
|
||||
return results
|
||||
end
|
||||
|
||||
-- check if draft-ietf-tls-downgrade-scsv-00 is implemented as a mitigation
|
||||
local function check_fallback_scsv(host, port, protocol, ciphers)
|
||||
local results = {}
|
||||
local t = {
|
||||
["protocol"] = protocol,
|
||||
["extensions"] = tcopy(base_extensions),
|
||||
}
|
||||
if host.targetname then
|
||||
t["extensions"]["server_name"] = tls.EXTENSION_HELPERS["server_name"](host.targetname)
|
||||
end
|
||||
|
||||
t["ciphers"] = tcopy(ciphers)
|
||||
t.ciphers[#t.ciphers+1] = "TLS_FALLBACK_SCSV"
|
||||
|
||||
local record = try_params(host, port, t)
|
||||
|
||||
if record["type"] == "alert" and record["body"][1]["description"] == "inappropriate_fallback" then
|
||||
ctx_log(2, protocol, "TLS_FALLBACK_SCSV rejected properly.")
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
portrule = function (host, port)
|
||||
return shortport.ssl(host, port) or sslcert.getPrepareTLSWithoutReconnect(port)
|
||||
end
|
||||
@@ -334,16 +357,16 @@ action = function(host, port)
|
||||
local ciphers = find_ciphers(host, port, 'SSLv3')
|
||||
if ciphers == nil then
|
||||
vuln_table.check_results = { "SSLv3 not supported" }
|
||||
return report:make_output(vuln_table)
|
||||
end
|
||||
|
||||
if #ciphers == 0 then
|
||||
elseif #ciphers == 0 then
|
||||
vuln_table.check_results = { "No CBC ciphersuites found" }
|
||||
return report:make_output(vuln_table)
|
||||
else
|
||||
vuln_table.check_results = ciphers
|
||||
if check_fallback_scsv(host, port, 'SSLv3', ciphers) then
|
||||
table.insert(vuln_table.check_results, "TLS_FALLBACK_SCSV properly implemented")
|
||||
vuln_table.state = vulns.STATE.LIKELY_VULN
|
||||
else
|
||||
vuln_table.state = vulns.STATE.VULN
|
||||
end
|
||||
end
|
||||
|
||||
-- else
|
||||
vuln_table.check_results = ciphers
|
||||
vuln_table.state = vulns.STATE.VULN
|
||||
return report:make_output(vuln_table)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user