Lucene search

K
nessusThis script is Copyright (C) 2015-2020 and is owned by Tenable, Inc. or an Affiliate thereof.POLARSSL_CVE-2014-8627.NASL
HistoryJan 07, 2015 - 12:00 a.m.

PolarSSL Weak Signature Algorithm Negotiation

2015-01-0700:00:00
This script is Copyright (C) 2015-2020 and is owned by Tenable, Inc. or an Affiliate thereof.
www.tenable.com
23

CVSS2

5

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

0.003

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

CVSS2

5

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

0.003

Percentile

65.9%