OpenSSL Heartbleed flaw

Heartbleed flaw is a serious vulnerability in OpenSSL library. This problem has been found by Neel Mehta of Google Security and the fix has been developed by Adam Langley  and Bodo Moeller. This big bug allows anyone who is connected to Internet the read the server or client memory if they run a vulnerable version of OpenSSL. If the memory of the server can be read, a potential high risk to find the private secret used to encrypt/decrypt traffic can be stolen by the attacker. A team of specialists have tested this vulnerability against their own system and they have successfully stolen the secret keys of x.509 certificates, users names, passwords and a lot of confidential business data without any special privileges.

The vulnerability

It’s very important to understand that this not a TLS design flaw but just an error of implementation in OpenSSL library. I think it’s very interesting to know and understand why this vulnerability exists. The problem comes from a missing bounds check in the handling of the TLS heartbeat extension which allow a buffer over read. This missing can be used to reveal up to 64k of memory to a connected client or server. In other word, an attacker can make a memory dump without any privileges.

In OpenSSL, when a heartbeat packet is received, the length field of the packet is read, and OpenSSL instance simply reads length bytes and return them. An hacker can forge a packet with a length value of 65’535 but set a payload of 1 byte. The result is a buffer over read. Note that an attacker can dump 64KB of memory per heartbeat packet ! An attacker cannot choose which memory he want to read, but if he try enough times, his request’s data structure is likely to wind up next to something interesting, such as your private keys, or users’ cookies or passwords.

In more friendly words : “Heartbeat extension allows one endpoint to go “I’m sending you some data, echo it back to me”. It supports up to about 64 KB. You send both a length figure and the data itself. Unfortunately, if you use the length field to claim “I’m sending 64 KB of data” (for example) and then only really send, say, one byte, OpenSSL would send you back your one byte and 64 KB (minus one) of other data from RAM.

Which OpenSSL releases are affected ?

“Only” 🙂 1.0.1 and 1.0.2-beta releases of OpenSSL are affected including 1.0.1f and 1.0.2-beta1.

Am i affected ?

An online tool can be used to test if a server is affected or not. Test your server to heartbleed bug

How to fix it ?

Affected users should upgrade to OpenSSL 1.0.1g. Users who are unable to immediately upgrade can alternatively recompile OpenSSL with -DOPENSSL_NO_HEARTBEATS option to exclude heartbeat extension. Be careful with your Linux distribution because a lot have the affected release of OpenSSL. The next list is probably not complete:

  • Debian Wheezy (stable), OpenSSL 1.0.1e-2+deb7u4
  • Ubuntu 12.04.4 LTS, OpenSSL 1.0.1-4ubuntu5.11
  • CentOS 6.5, OpenSSL 1.0.1e-15
  • Fedora 18, OpenSSL 1.0.1e-4
  • OpenBSD 5.3 (OpenSSL 1.0.1c 10 May 2012) and 5.4 (OpenSSL 1.0.1c 10 May 2012)
  • FreeBSD 10.0 – OpenSSL 1.0.1e 11 Feb 2013
  • NetBSD 5.0.2 (OpenSSL 1.0.1e)
  • OpenSUSE 12.2 (OpenSSL 1.0.1c)

source : http://heartbleed.com/

The next piece of code shows the official git diff applied to the main C file which have the flaw.

index 7a5596a..2e8cf68 100644 (file)
--- a/ssl/d1_both.c
+++ b/ssl/d1_both.c
@@ -1459,26 +1459,36 @@ dtls1_process_heartbeat(SSL *s)
        unsigned int payload;
        unsigned int padding = 16; /* Use minimum padding */

-       /* Read type and payload length first */
-       hbtype = *p++;
-       n2s(p, payload);
-       pl = p;
-
        if (s->msg_callback)
                s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
                        &s->s3->rrec.data[0], s->s3->rrec.length,
                        s, s->msg_callback_arg);

+       /* Read type and payload length first */
+       if (1 + 2 + 16 > s->s3->rrec.length)
+               return 0; /* silently discard */
+       hbtype = *p++;
+       n2s(p, payload);
+       if (1 + 2 + payload + 16 > s->s3->rrec.length)
+               return 0; /* silently discard per RFC 6520 sec. 4 */
+       pl = p;
+
        if (hbtype == TLS1_HB_REQUEST)
                {
                unsigned char *buffer, *bp;
+               unsigned int write_length = 1 /* heartbeat type */ +
+                                           2 /* heartbeat length */ +
+                                           payload + padding;
                int r;

+               if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
+                       return 0;
+
                /* Allocate memory for the response, size is 1 byte
                 * message type, plus 2 bytes payload length, plus
                 * payload, plus padding
                 */
-               buffer = OPENSSL_malloc(1 + 2 + payload + padding);
+               buffer = OPENSSL_malloc(write_length);
                bp = buffer;

                /* Enter response type, length and copy payload */
@@ -1489,11 +1499,11 @@ dtls1_process_heartbeat(SSL *s)
                /* Random padding */
                RAND_pseudo_bytes(bp, padding);

-               r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
+               r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);

                if (r >= 0 && s->msg_callback)
                        s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
-                               buffer, 3 + payload + padding,
+                               buffer, write_length,
                                s, s->msg_callback_arg);

                OPENSSL_free(buffer);

The most important part of this fix is the following piece of code:

/* Read type and payload length first */
if (1 + 2 + 16 > s->s3->rrec.length)
    return 0; /* silently discard */

hbtype = *p++;
n2s(p, payload);

if (1 + 2 + payload + 16 > s->s3->rrec.length)
    return 0; /* silently discard per RFC 6520 sec. 4 */
pl = p;

For more details : OpenSSL GIT , Detailed diagnostic of the fix

Research more information

If you have more information about this flaw, you can send me your details by e-mail using the contact form : Contact me

References

Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.