CVSS2
Attack Vector
NETWORK
Attack Complexity
LOW
Authentication
NONE
Confidentiality Impact
NONE
Integrity Impact
PARTIAL
Availability Impact
NONE
AV:N/AC:L/Au:N/C:N/I:P/A:N
EPSS
Percentile
65.9%
PolarSSL 1.3.8 does not properly negotiate the signature algorithm to use, allowing remote attackers to conduct downgrade attacks.
This plugin sends a list of hash algorithms (SHA512, SHA384, SHA256, SHA224, SHA1, and MD5) in descending order, and checks if the server selects MD5.
#TRUSTED a63b12c204006332a94c61c2224e273777ee6b31edf738a967c8ccb44ce08fdf64628ba81906666bdc4985ad20eaf27c85d610a43114d978ff2f316582f0e14ccb30f9be94bcaf7bbccead8d07b8482f1dfe0c4389f2784e91b0d87e3da8012b930a31077e35a81d9658b06f62ea093d3ecfab127129c1ab23754a3e7d158dc4ed590e4205185fc30c58dbedf6da51fef8d3849ba475b4f31981ac0fe85370da45c6184ee0e64fbb9fdf736a8e85885b05b124aacd864dec7da5b0a6c4fa8c31006ea8a0a801b3b85b514dee71ce19824ec583f49d4842c091951849486dd745c9dcd4662072d0797587b7cd3f1506dafbc02b7113247ce831212d2f1f917ca8a1f6aa63f56e759bd5b3ade94c5611b027ce1394e2b1512e6d1ac6735b177eb6215531db9076b585c45899ea6b62ae7da1fe21db859c751d7f797464ae42752d4f1bef01af87ed1ffdc979f487fa9fd6c7c48bfdc76ccf24fa0126b2964e3e8a0b8135b62804de128954f500b645f16e61f986c55914d7913a65dd27a3370304fe75e4d4b73b7456e20f982bea01a9b08546f3ff3ce982ae457202f99e8aa74e27fda9da695000c51c4ecab9ee7357eb60c05ff4f84abf11f40c45a1dcfe3f5c6c245c9f1066aa47334432756373a4a08278c4eb2f8177f079d24fb48dd5c2f56b8a60f9b3f552b5b26f5b003b3ba43ba24fc280526004d5deabb30cf22ac07f
#
# (C) Tenable Network Security, Inc.
#
include("compat.inc");
if (description)
{
script_id(80399);
script_version("1.12");
script_set_attribute(attribute:"plugin_modification_date", value:"2020/06/12");
script_cve_id("CVE-2014-8627");
script_bugtraq_id(70902);
script_name(english:"PolarSSL Weak Signature Algorithm Negotiation");
script_summary(english:"Attempts to negotiate a weak signature algorithm.");
script_set_attribute(attribute:"synopsis", value:
"The remote TLS server negotiates a weaker signature algorithm.");
script_set_attribute(attribute:"description", value:
"PolarSSL 1.3.8 does not properly negotiate the signature algorithm to
use, allowing remote attackers to conduct downgrade attacks.
This plugin sends a list of hash algorithms (SHA512, SHA384, SHA256,
SHA224, SHA1, and MD5) in descending order, and checks if the server
selects MD5.");
script_set_attribute(attribute:"see_also", value:"https://tls.mbed.org/tech-updates/releases/polarssl-1.3.9-released");
script_set_attribute(attribute:"see_also", value:"https://bugzilla.redhat.com/show_bug.cgi?id=1159845");
script_set_attribute(attribute:"solution", value:
"Use a PolarSSL version other than 1.3.8.");
script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:N/I:P/A:N");
script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C");
script_set_cvss3_base_vector("CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N");
script_set_cvss3_temporal_vector("CVSS:3.0/E:U/RL:O/RC:C");
script_set_attribute(attribute:"cvss_score_source", value:"CVE-2014-8627");
script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");
script_set_attribute(attribute:"exploit_available", value:"false");
script_set_attribute(attribute:"vuln_publication_date", value:"2014/11/22");
script_set_attribute(attribute:"patch_publication_date", value:"2014/11/22");
script_set_attribute(attribute:"plugin_publication_date", value:"2015/01/07");
script_set_attribute(attribute:"plugin_type", value:"remote");
script_set_attribute(attribute:"cpe", value:"cpe:/a:polarssl:polarssl");
script_end_attributes();
script_category(ACT_GATHER_INFO);
script_family(english:"General");
script_copyright(english:"This script is Copyright (C) 2015-2020 and is owned by Tenable, Inc. or an Affiliate thereof.");
script_dependencies("ssl_supported_versions.nasl");
script_require_keys("SSL/Supported");
exit(0);
}
include("byte_func.inc");
include("ftp_func.inc");
include("global_settings.inc");
include("kerberos_func.inc");
include("ldap_func.inc");
include("misc_func.inc");
include("nntp_func.inc");
include("smtp_func.inc");
include("ssl_funcs.inc");
include("telnet2_func.inc");
include("audit.inc");
##
# Negotiate hash algorithm part of SignatureAndHashAlgorithm
#
# @param port TLS server port
# @param sighash client supported list of SignatureAndHashAlgorithms (encoded)
# @remark script exits on function failure
##
function get_hash_alg(port, sighash)
{
local_var ec_list, exts, exts_len, i, soc, version;
local_var cipher, cipher_desc, cipherspec, cspeclen, chello;
local_var data, hellodone, name, rec, shello, skex;
local_var alert;
# Create a socket for SSL handshake
soc = open_sock_ssl(port);
if ( ! soc ) exit(1, "Failed to open an SSL socket on port "+port+".");
# We need to include EC extensions because it seems PolarSSL server
# will abort the handshake if a EC-based cipher suite is negotiated
# but a EC extension is not offered by the client.
#
# PolarSSL as of 1.3.9 does not seem to support
# explicit_prime and explicit_char2 curve types
ec_list = make_list(
1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28
);
data = ssl_vldata_put(data:sighash, len:2);
exts = tls_ext(type:13, data:data) + tls_ext_ec(ec_list) + tls_ext_ec_pt_fmt();
exts_len = mkword(strlen(exts));
# Signature algorithms extension is only available
# in TLS version 1.2
version = TLS_12;
# Use ciphersuites that do ephemeral key exchange.
# This is to force the server to send a ServerKeyExchange
# in which DH/EC parameters are signed with negotiated
# SignatureAndHashAlgorithms.
cipherspec = NULL;
foreach cipher (keys(ciphers))
{
if(strlen(ciphers[cipher]) == 2 && 'DHE' >< cipher)
{
cipherspec += ciphers[cipher];
}
}
cspeclen = mkword(strlen(cipherspec));
# Send ClientHello
chello = client_hello(v2hello:FALSE, version: mkword(version),
extensions:exts,extensionslen:exts_len,
cipherspec : cipherspec,
cspeclen : cspeclen
);
send(socket:soc, data: chello);
hellodone = shello = skex = NULL;
i = 0;
while (! hellodone)
{
# Receive a record from the server.
data = recv_ssl(socket:soc, timeout:30);
if (isnull(data)) break;
# ServerHello
if(! shello)
{
shello = ssl_find(
blob:data,
'content_type', SSL3_CONTENT_TYPE_HANDSHAKE,
'handshake_type', SSL3_HANDSHAKE_TYPE_SERVER_HELLO
);
if (shello)
{
# Check handshake version returned by the server
# signtuare_alorithms extension first supported in TLS 1.2
if (shello['handshake_version'] != TLS_12)
{
close(soc);
exit(0, 'The service listening on port ' + port + ' does not support TLS 1.2.');
}
name = cipher_name(id:shello['cipher_spec']);
cipher_desc = ciphers_desc[name];
if(! cipher_desc)
{
close(soc);
exit(1, 'Failed to get info about the negotiated cipher suite.');
}
}
else
{
alert = ssl_find(
blob:data,
'content_type', SSL3_CONTENT_TYPE_ALERT
);
if(alert)
{
close(soc);
exit(1, 'Alert received from service listening on port '+ port +': level '+ alert['level'] + ', description code ' + alert['description'] + '.');
}
}
}
# Server Key Exchange.
if(! skex)
{
rec = ssl_find(
blob:data,
'content_type', SSL3_CONTENT_TYPE_HANDSHAKE,
'handshake_type', SSL3_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE
);
if (rec['data'])
{
skex = ssl_parse_srv_kex(blob:rec['data'], cipher:cipher_desc, version: version);
if(!skex)
{
close(soc);
exit(1, 'Failed to parse ServerKeyExchange received from service listening on port '+ port +'.');
}
}
}
# Server Hello Done.
if(! hellodone)
{
hellodone = ssl_find(
blob:data,
'content_type', SSL3_CONTENT_TYPE_HANDSHAKE,
'handshake_type', SSL3_HANDSHAKE_TYPE_SERVER_HELLO_DONE
);
if(hellodone) break;
}
# ServerHelloDone not seen after a higher number of TLS records
# Something is very wrong
if(i++ > 16) break;
}
close(soc);
# Make sure we got a ServerHelloDone
if(! hellodone)
{
exit(1, 'ServerHelloDone not received from service listening on port '+ port +'.');
}
# Make sure we got a ServerKeyExchange
# Server uses the negotiated SignatureAndHashAlgorithms
# to sign the DH parameters
if(! skex)
{
exit(1, 'ServerKeyExchange not received from service listening on port '+ port +'.');
}
if(isnull(skex['hash_alg']))
{
exit(1, 'Failed to get the hash algorithm in ServerKeyExchange received from service listening on port '+ port +'.');
}
return skex['hash_alg'];
}
#
# MAIN
#
# Get an SSL port
port = get_ssl_ports(fork:TRUE);
if (isnull(port))
exit(0, "The host does not appear to have any SSL-based services.");
# TLS signature extension is first supported in TLS 1.2
# Make sure remote TLS server supports TLS 1.2
#
tls12 = FALSE;
list = get_kb_list('SSL/Transport/'+port);
if(! isnull(list))
{
list = make_list(list);
foreach encap (list)
{
if (encap == COMPAT_ENCAPS_TLSv12)
{
tls12 = TRUE;
break;
}
}
}
if(! tls12)
exit(0, 'The SSL-based service listening on port '+port+' does not appear to support TLS 1.2.');
sighash_sha = raw_string(
6, 1, # sha512/rsa
5, 1, # sha384/rsa
4, 1, # sha256/rsa
3, 1, # sha224/rsa
2, 1, # sha1/rsa
6, 2, # sha512/dsa
5, 2, # sha384/dsa
4, 2, # sha256/dsa
3, 2, # sha224/dsa
2, 2, # sha1/dsa
6, 3, # sha512/ecdsa
5, 3, # sha384/ecdsa
4, 3, # sha256/ecdsa
3, 3, # sha224/ecdsa
2, 3 # sha1/ecdsa
);
# Check if server supports any of SHA hash algoritms
hash_alg = get_hash_alg(port:port, sighash: sighash_sha);
# If so, check if server selects MD5 even higher hash algoirthms are available
if(hash_alg)
{
# SignatureAndHashAlgorithm list is in descending order.
# PolarSSL only uses the Hash part to select the SignatureAndHashAlgorithm.
# Vulnerable PolarSSL (1.3.8) will select MD5.
# Correct TLS implementations will select highest common hash algorithm
sighash = raw_string(
6, 1, # sha512/rsa
5, 1, # sha384/rsa
4, 1, # sha256/rsa
3, 1, # sha224/rsa
2, 1, # sha1/rsa
6, 2, # sha512/dsa
5, 2, # sha384/dsa
4, 2, # sha256/dsa
3, 2, # sha224/dsa
2, 2, # sha1/dsa
6, 3, # sha512/ecdsa
5, 3, # sha384/ecdsa
4, 3, # sha256/ecdsa
3, 3, # sha224/ecdsa
2, 3, # sha1/ecdsa
1, 3, # md5/ecdsa
1, 2, # md5/dsa
1, 1 # md5/rsa
);
hash_alg = get_hash_alg(port:port, sighash: sighash);
# PolarSSL only negotiates the hash algorithm part
# in SignatureAndHashAlgorithms.
#
# Vulnerable server selects the lowest common hash alg (MD5)
if(hash_alg == 1)
security_warning(port:port);
else
exit(0, 'The TLS service listening on port ' + port + ' is not affected.');
}
# never reached