Tracking OpenSSL | Nihal Pasham

BMI Salaf Ramadan Promo (A5 Flyer)

 

Vulnerability  – CVE-2014-0224

 

This vulnerability exposes a corner case within the OpenSSL implementation [versions ()] allowing an attacker (MITM) to inject change cipher spec messages at any  point during the TLS handshake, altering the key generation process.

Some background on TLS :

TLS record Protocol is layered protocol i.e. it is consists 4 different protocols ( the handshake protocol, the alert protocol, the change cipher spec protocol  and the application data protocol) – each designed for a specific function.

This vulnerability is to do with the Change cipher spec protocol (one of the four).

Here’s a typical TLS workflow. This is what it looks like (from RFC 2246)

                           Client                                                                       Server

                           ClientHello                           ——–>

                                                                                                            ServerHello

                                                                                                            Certificate*

                                                                                                            ServerKeyExchange*

                                                                                                            CertificateRequest*

                                                                         <——–                    ServerHelloDone

                           Certificate*

                           ClientKeyExchange

                           CertificateVerify*

                           [ChangeCipherSpec]

                           Finished                                ——–>

                                                                                                             [ChangeCipherSpec]

                                                                          <——–                     Finished

                           Application Data                <——->                    Application Data

                                                 Message flow for a full handshake

                          * Indicates optional or situation-dependent messages that are not

                            always sent.

A deeper look

The handshake protocol allows for negotiating cryptographic parameters like the encryption, compression algorithms acceptable to both parties, exchanging random  values (for use later in the key generation process) and sending an encrypted ‘pre-master secret’ in the ‘client key exchange message’.

 

Client Hello Server Hello Certificate (server) + Server Hello Done

Then each endpoint derives a 48 byte master secret‘ from the ‘pre-master secret‘ and the exchanged random nonces using a pseudo random function.

master_secret = PRF(pre_master_secret, “master secret”, ClientHello.random + ServerHello.random)  [0..47];

the second argument ‘master secret’ is just an ASCII label

which is in-turn used by each recipient to verify the final Finished message – a PRF digest of all the previous handshake messages.

verify_data   =  PRF(master_secret, finished_label, MD5(handshake_messages) + SHA-1(handshake_messages)) [0..11];

 * PRF is a “Pseudo-Random Function” defined in the RFC. It takes 3 arguments – a secret, an ASCII label, the seed data, runs its through a keyed-Hash Message Authentication Code (HMAC) and produces an output of arbitrary length. Essentially – a secure digest of some data protected by a secret. TLS’s PRF is a bit unique in that it uses two hashing functions (MD5 and SHA1) for additional security i.e. the secret is halved and each half provided as input to one of the hash functions. The PRF is then defined as the result of mixing the two pseudorandom streams by exclusive-or’ing them together.

                      PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed);

Client key exchange + CCS + Finsihed (of client) CCS + Finished (of server)

Assuming that the check succeeds, both generate session keys (or rather a block of cryptographic key material) from the master secret along with the random nonces and proceed  to send cryptographically-protected application data.

To generate the key material, we compute

key_block = PRF(SecurityParameters.master_secret, “key expansion”, SecurityParameters.server_random + SecurityParameters.client_random);

 

Now for the implications :

Essentially handshake protocol is a state machine which starts out with a connection state that does not use any encryption and switches to connection state  that uses encryption.

When starting a new handshake, messages used in the negotiation of the security parameters are sent in the clear i.e. the initial current state always specifies  that no encryption, compression, or MAC. The change cipher spec message (sent by both client and server) signals to the recipient that all future messages/data  from the sender will now be encrypted with negotiated security parameters (keys, ciphers, MAC etc.)

Although the RFC explicitly calls out the need for the change cipher spec message to be sent during the handshake, after the security parameters have been agreed  upon, but before the finished message , it doesn’t say much on when a recipient should/can accept and process a change cipher spec message.

Now if an attacker (MITM) injects CCS messages into a connection just before master key is generated, he could alter the key generation process and bypass the  finished message verification. Put it simply – the injected CCS message would signal a state change to the recipient, leading to the premature computation of session keys and finished messages with information available to a MITM attacker i.e. without the ‘master secret’ – the only unique parameter in the above PRF calculations.

 

OpenSSL’s Change cipher spec implementation :

 

int ssl3_do_change_cipher_spec(SSL *s)                          # ‘CSS messages invoke this function’   

{

int i;

const char *sender;

int slen;

 

if (s->state & SSL_ST_ACCEPT)

 

i=SSL3_CHANGE_CIPHER_SERVER_READ;

else

i=SSL3_CHANGE_CIPHER_CLIENT_READ;

if (s->s3->tmp.key_block == NULL)

{

if (s->session == NULL)

{

/* might happen if dtls1_read_bytes() calls this */

SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC,SSL_R_CCS_RECEIVED_EARLY);

return (0);

}

 

s->session->cipher=s->s3->tmp.new_cipher;

 if (!s->method->ssl3_enc->setup_key_block(s)) return(0);                 # ends up setting the key_block (includes session keys) prematurely 

}

if (!s->method->ssl3_enc->change_cipher_state(s,i))

return(0);

 

/* we have to record the message digest at

* this point so we can get it before we read

* the finished message */

if (s->state & SSL_ST_CONNECT)

{

sender=s->method->ssl3_enc->server_finished_label;

slen=s->method->ssl3_enc->server_finished_label_len;

}

else

{

sender=s->method->ssl3_enc->client_finished_label;

slen=s->method->ssl3_enc->client_finished_label_len;

}

 

  i = s->method->ssl3_enc->final_finish_mac(s, sender,slen,s->s3->tmp.peer_finish_md);             # and premature verifying the expected ‘finished’ hashes

if (i == 0)

{

SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR);

return 0;

}

s->s3->tmp.peer_finish_md_len = i;

return(1);

}

 

Comments :

To be fair, I think the cause for this vulnerability is more to do with the ambiguity in the RFC than a lapse in the OpenSSL implementation, considering that the RFC is pretty much mute on ‘WHEN’ recipients should accept ‘Change cipher spec’ messages.

Fix :

Only accept change cipher spec when it is expected instead of at any time. This prevents premature setting of session keys before the master secret is determined which an attacker could use as a MITM attack.

 

References

http://ccsinjection.lepidum.co.jp/blog/2014-06-05/CCS-Injection-en/index.html

http://tools.ietf.org/html/rfc2246

https://www.imperialviolet.org/2014/06/05/earlyccs.html

 

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s