Vulnerabilidad de OpenSSL CVE-2015-0205

5

Parece que no puedo entender la siguiente vulnerabilidad en OpenSSL:

DH client certificates accepted without verification [Server] (CVE-2015-0205)
=============================================================================

Severity: Low

An OpenSSL server will accept a DH certificate for client authentication
without the certificate verify message. This effectively allows a client
to authenticate without the use of a private key. This only affects servers
which trust a client certificate authority which issues certificates
containing DH keys: these are extremely rare and hardly ever encountered.

This issue affects OpenSSL versions: 1.0.1 and 1.0.0.

OpenSSL 1.0.1 users should upgrade to 1.0.1k.
OpenSSL 1.0.0 users should upgrade to 1.0.0p.

This issue was reported to OpenSSL on 22nd October 2014 by Karthikeyan
Bhargavan of the PROSECCO team at INRIA. The fix was developed by Stephen
Henson of the OpenSSL core team.

La razón por la que lo anterior no tiene sentido es que cuando el cliente utiliza un certificado DH, no se espera que el cliente envíe un mensaje de verificación de certificado, un por RFC 5246, sección 7.4.8 :

  This message is used to provide explicit verification of a client
  certificate.  This message is only sent following a client
  certificate that has signing capability (i.e., all certificates
  except those containing fixed Diffie-Hellman parameters).

Y aquí está lo que RFC 5246, sección F.1.1.3 dice:

  When Diffie-Hellman key exchange is used, the server can either
  supply a certificate containing fixed Diffie-Hellman parameters or
  use the server key exchange message to send a set of temporary
  Diffie-Hellman parameters signed with a DSA or RSA certificate.
  Temporary parameters are hashed with the hello.random values before
  signing to ensure that attackers do not replay old parameters.  In
  either case, the client can verify the certificate or signature to
  ensure that the parameters belong to the server.

  If the client has a certificate containing fixed Diffie-Hellman
  parameters, its certificate contains the information required to
  complete the key exchange.  Note that in this case the client and
  server will generate the same Diffie-Hellman result (i.e.,
  pre_master_secret) every time they communicate.  To prevent the
  pre_master_secret from staying in memory any longer than necessary,
  it should be converted into the master_secret as soon as possible.
  Client Diffie-Hellman parameters must be compatible with those
  supplied by the server for the key exchange to work.

Además, no veo cómo se puede hacer pasar por el cliente (es decir, calcular el pre_master_secret) sin conocer la clave secreta del cliente.

Puedo ver cómo un error en OpenSSL podría permitir que un atacante omita la autenticación, por ejemplo, si OpenSSL aceptaría los parámetros DH en el mensaje de Intercambio de claves del cliente, es decir, si OpenSSL no aplicó correctamente esta parte de RFC 5246, sección 7.4.7 :

  When the client is using an ephemeral Diffie-Hellman exponent,
  then this message contains the client's Diffie-Hellman public
  value.  If the client is sending a certificate containing a static
  DH exponent (i.e., it is doing fixed_dh client authentication),
  then this message MUST be sent but MUST be empty.

Pero fix no admite esta interpretación. De hecho, parece que requiere un mensaje de verificación de certificado.

¿Alguien puede darle sentido a esto?

    
pregunta Erwan Legrand 26.01.2015 - 19:29
fuente

2 respuestas

3

Al final, la siguiente hipótesis de mi pregunta anterior resultó ser cierta:

  

Puedo ver cómo un error en OpenSSL podría permitir a un atacante eludir   autenticación, por ejemplo, si OpenSSL aceptaría parámetros DH en   el mensaje de intercambio de claves del cliente, es decir, si OpenSSL no se realizó correctamente   haga cumplir esta parte de RFC 5246, sección 7.4.7

Este código proviene de la función ssl3_get_client_key_exchange() en OpenSSL:

enlace

if (n == 0L) {
  /* Get pubkey from cert */
  EVP_PKEY *clkey = X509_get_pubkey(s->session->peer);
  if (clkey) {
    if (EVP_PKEY_cmp_parameters(clkey, skey) == 1)
      dh_clnt = EVP_PKEY_get1_DH(clkey);
  }
  if (dh_clnt == NULL) {
    al = SSL_AD_HANDSHAKE_FAILURE;
    SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
    SSL_R_MISSING_TMP_DH_KEY);
    goto f_err;
  }
  EVP_PKEY_free(clkey);
  pub = dh_clnt->pub_key;
} else
  pub = BN_bin2bn(p, i, NULL);
if (pub == NULL) {
  SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB);
  goto err;
}

El código anterior no impide que el cliente (o un MITM) proporcione al mismo tiempo un certificado DH y parámetros DH en el mensaje de Intercambio de claves del cliente. Cuando el mensaje no está vacío, se lee la clave pública del mensaje:

} else
  pub = BN_bin2bn(p, i, NULL);

¡Por lo tanto, un atacante podría proporcionar un certificado y realizar el intercambio de claves DH utilizando otra clave pública que no sea la del certificado!

Por alguna razón, los desarrolladores de OpenSSL eligen no requerir un mensaje de intercambio de clave de cliente vacío cuando el cliente proporciona un certificado DH. (Aunque esto es requerido por el RFC).

La razón por la que la solución del equipo de OpenSSL no interrumpe la autenticación del cliente con certificados DH es que no se llama a la función ssl3_get_cert_verify () si ssl3_get_client_key_exchange () lee la clave del certificado. La lógica es algo complicada pero ... bueno, ¡funciona!

    
respondido por el Erwan Legrand 28.01.2015 - 16:25
fuente
1

Estoy completamente de acuerdo contigo. No hay un alcance de mensaje de verificación de certificado en el caso de DH efímero ya que la firma no está involucrada en ninguna parte de la autenticación.

    
respondido por el user45475 27.01.2015 - 06:45
fuente

Lea otras preguntas en las etiquetas