1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 20:51:30 +00:00

Fix a crash in ssl-enum-ciphers when parsing unsupported cert types

This commit is contained in:
dmiller
2016-08-30 16:07:08 +00:00
parent c82915cb71
commit 8779c1e376
4 changed files with 21 additions and 8 deletions

View File

@@ -1,5 +1,10 @@
# Nmap Changelog ($Id$); -*-text-*- # Nmap Changelog ($Id$); -*-text-*-
o [NSE] Fix a crash when parsing TLS certificates that OpenSSL doesn't support,
like DH certificates or corrupted certs. When this happens, ssl-enum-ciphers
will label the ciphersuite strength as "unknown." Reported by Bertrand
Bonnefoy-Claudet. [Daniel Miller]
o [NSE] Fix two issues in sslcert.lua that prevented correct operations o [NSE] Fix two issues in sslcert.lua that prevented correct operations
against LDAP services when version detection or STARTTLS were used. against LDAP services when version detection or STARTTLS were used.
[Tom Sellers] [Tom Sellers]

View File

@@ -134,6 +134,7 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/err.h>
extern "C" extern "C"
{ {
@@ -455,16 +456,15 @@ int lua_push_ecdhparams(lua_State *L, EVP_PKEY *pubkey) {
nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group));
if (nid == NID_X9_62_prime_field) { if (nid == NID_X9_62_prime_field) {
lua_pushstring(L, "explicit_prime"); lua_pushstring(L, "explicit_prime");
lua_setfield(L, -2, "ec_curve_type");
} }
else if (nid == NID_X9_62_characteristic_two_field) { else if (nid == NID_X9_62_characteristic_two_field) {
lua_pushstring(L, "explicit_char2"); lua_pushstring(L, "explicit_char2");
lua_setfield(L, -2, "ec_curve_type");
} }
else { else {
/* Something weird happened. */ /* Something weird happened. */
return luaL_error(L, "Unknown EC field type in certificate."); lua_pushstring(L, "UNKNOWN");
} }
lua_setfield(L, -2, "ec_curve_type");
} }
lua_setfield(L, -2, "curve_params"); lua_setfield(L, -2, "curve_params");
EC_KEY_free(ec_key); EC_KEY_free(ec_key);
@@ -549,6 +549,11 @@ static int parse_ssl_cert(lua_State *L, X509 *cert)
lua_setfield(L, -2, "pem"); lua_setfield(L, -2, "pem");
pubkey = X509_get_pubkey(cert); pubkey = X509_get_pubkey(cert);
if (pubkey == NULL) {
lua_pushnil(L);
lua_pushfstring(L, "Error parsing cert: %s", ERR_error_string(ERR_get_error(), NULL));
return 2;
}
lua_newtable(L); lua_newtable(L);
#if OPENSSL_VERSION_NUMBER < 0x10100000L #if OPENSSL_VERSION_NUMBER < 0x10100000L
pkey_type = EVP_PKEY_type(pubkey->type); pkey_type = EVP_PKEY_type(pubkey->type);

View File

@@ -43,7 +43,8 @@ _ENV = stdnse.module("sslcert", stdnse.seeall)
--@name parse_ssl_certificate --@name parse_ssl_certificate
--@class function --@class function
--@param der DER-encoded certificate --@param der DER-encoded certificate
--@return table containing decoded certificate --@return table containing decoded certificate or nil on failure
--@return error string if parsing failed
--@see nmap.get_ssl_certificate --@see nmap.get_ssl_certificate
_ENV.parse_ssl_certificate = nmap.socket.parse_ssl_certificate _ENV.parse_ssl_certificate = nmap.socket.parse_ssl_certificate
@@ -893,10 +894,10 @@ function getCertificate(host, port)
return false, "Server sent no certificate" return false, "Server sent no certificate"
end end
cert = parse_ssl_certificate(certs.certificates[1]) cert, err = parse_ssl_certificate(certs.certificates[1])
if not cert then if not cert then
mutex "done" mutex "done"
return false, "Unable to get cert" return false, ("Unable to get cert: %s"):format(err)
end end
else else
-- If we don't already know the service is TLS wrapped check to see if -- If we don't already know the service is TLS wrapped check to see if

View File

@@ -685,8 +685,10 @@ local function find_ciphers_group(host, port, protocol, group, scores)
-- This may not always be the case, so -- This may not always be the case, so
-- TODO: reorder certificates and validate entire chain -- TODO: reorder certificates and validate entire chain
-- TODO: certificate validation (date, self-signed, etc) -- TODO: certificate validation (date, self-signed, etc)
local c = sslcert.parse_ssl_certificate(certs.certificates[1]) local c, err = sslcert.parse_ssl_certificate(certs.certificates[1])
if c.pubkey.type == kex.pubkey then if not c then
stdnse.debug1("Failed to parse certificate: %s", err)
elseif c.pubkey.type == kex.pubkey then
local sigalg = c.sig_algorithm:match("([mM][dD][245])") local sigalg = c.sig_algorithm:match("([mM][dD][245])")
if sigalg then if sigalg then
-- MD2 and MD5 are broken -- MD2 and MD5 are broken