Exploiting Heartbleed

April 18, 2014 by Ninj@S3c

This article explains the Heartbleed bug and shows how it can be exploited.


Heartbleed is a flaw in implementing the Heartbeat extension of OpenSSL. It is just an extension of OpenSSL which keeps the session alive for HTTPS connections, much like the Keep-Alive header in HTTP.

As per RFC, the formal structure of Heartbeat is:

This is request/ response pair. The code for the Heartbeat packet is:

{ HeartbeatMessageType type; //length 1 Byte
uint16 payload_length; // length 2 Bytes
opaque payload[HeartbeatMessage.payload_length];
opaque padding[padding_length];
} HeartbeatMessage;

Where the Message type has a length of 1 Byte, Payload has a length of 3 bytes and the rest of them are padding lengths. The payload variable seems to be a vulnerable one. Ideally the code must check the payload data length with the actual length of data sent in the Heartbeat request. So if the payload exceeds the standard length in the request, the server may return more data in response than what it should ideally return.

This is a case of Buffer Overflow (BoF). Notice the following vulnerable code:

p = &s->s3->rrec.data[0]

buffer = OPENSSL_malloc(1 + 2 + payload + padding);
bp = buffer;
memcpy(bp, pl, payload);

The rrec contains all the incoming request data. The code reads the data. The
first byte is to check if it’s a Heartbeat protocol and then another 2 bytes determine the length of the Heartbeat payload. Ideally the length must be equal to the payload sent in the Heartbeat request. As discussed above, the code is not checking actual length sent in the Heartbeat request. So the code copies the amount of data requested by incoming requests to the outgoing server response (see memcpy function), and possibly more than requested in some cases. This may leak valuable information to attackers, such as session IDs, tokens, keys, etc.

The fix to this bug is to check the length of the payload, which should not exceed 16 bytes.

What can be leaked

So, as said earlier, much sensitive information from the server’s memory can be sent in through the response. Some of them are session-related information such as session ID, different tokens, keys, and some other sensitive internal information such as queries, internal data, etc. A real example shows what we can receive in the responses:


The easiest way is to hijack an already logged-in user’s session.

Since we can get all the session IDs and possible csrf tokens, we can hijack a user’s session. However in my case, it was very laborious and had some constraints:

  • I had to collect a lot of session IDs, tokens and other dependencies required for login.
  • It’s a trial and error method as session IDs may be old/not valid/cached.
  • As soon as a valid session ID is encountered, hijacking is possible.

The first step was to collect as many session IDs as possible, along with their corresponding nuances, if any. The major challenge was that sometimes they were expired/not valid, so we had a really tough time constructing a valid cookie. But keep trying. One of the valid cookies I was able to construct:


Now you know what to do. Just try to access the internal page of the vulnerable site and replay the cookie. The website was using the vulnerable version, which was also confirmed by the response header:

And replaying the supposedly valid cookie and trying to access the internal page enters us into someone’s profile:



And many more resources over the internet…

Posted: April 18, 2014
Articles Author
View Profile

Ninj@S3c is a Security Analyst with a leading MNC. He is predominantly focused on Application Security, Network Security and Wireless Security. Beyond this, he’s interested in Reverse Engineering and Forensics.

3 responses to “Exploiting Heartbleed”

  1. slackbone says:

    Good article. BTW, the github link is broken.

  2. Abhishek Dashora says:

    Nice Article 🙂

  3. Ninj@S3c says:

    Thanks stackbone and Abhishek !

Leave a Reply

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