Vulnerabilità OpenSSL CVE-2015-0205

5

Non riesco a dare un senso alla seguente vulnerabilità in 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.

Il motivo per cui quanto sopra non ha senso è che quando il client utilizza un certificato DH, il client non dovrebbe inviare un messaggio di verifica certificato, a per RFC 5246, sezione 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).

Ed ecco cosa RFC 5246, sezione 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.

Inoltre, non riesco a vedere come si potrebbe impersonare il client (cioè calcolare il pre_master_secret) senza conoscere la chiave segreta del client.

Riesco a vedere come un bug in OpenSSL potrebbe consentire a un utente malintenzionato di ignorare l'autenticazione, ad esempio se OpenSSL accetta i parametri DH nel messaggio Scambio chiavi client, ovvero se OpenSSL non ha applicato correttamente questa parte di RFC 5246, sezione 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.

Tuttavia la correzione non supporta questa interpretazione. Effettivamente, sembra richiedere un messaggio Verifica certificato!

Qualcuno può dare un senso a questo?

    
posta Erwan Legrand 26.01.2015 - 19:29
fonte

2 risposte

3

Alla fine, la seguente ipotesi dalla mia domanda sopra si è rivelata vera:

I can see how a bug in OpenSSL could allow an attacker to bypass authentication, for example if OpenSSL would accept DH parameters in the Client Key Exchange message, i.e. if OpenSSL did not properly enforce this part of RFC 5246, section 7.4.7

Questo codice proviene dalla funzione ssl3_get_client_key_exchange() in OpenSSL:

link

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;
}

Il codice sopra non impedisce al client (o al MITM) di fornire contemporaneamente un certificato DH e parametri DH nel messaggio Scambio chiavi client. Quando il messaggio non è vuoto, la chiave pubblica viene letta dal messaggio:

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

Quindi un utente malintenzionato potrebbe fornire un certificato ed eseguire lo scambio di chiavi DH utilizzando un'altra chiave pubblica diversa da quella presente nel certificato!

Per qualche motivo, gli sviluppatori OpenSSL scelgono di non richiedere un messaggio di Scambio chiavi client vuoto quando il cliente fornisce un certificato DH. (Anche se questo è richiesto dalla RFC.)

Il motivo per cui la correzione dal team OpenSSL non interrompe l'autenticazione del client con certificati DH è la funzione ssl3_get_cert_verify () non viene chiamata se ssl3_get_client_key_exchange () legge la chiave dal certificato. La logica è alquanto complicata ma ... beh, funziona!

    
risposta data 28.01.2015 - 16:25
fonte
1

Sono completamente d'accordo con te. Non c'è spazio per il messaggio di verifica del certificato nel caso di DH temporaneo poiché la firma non è coinvolta in alcuna parte dell'autenticazione.

    
risposta data 27.01.2015 - 06:45
fonte

Leggi altre domande sui tag