Overview 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: [plain] Struct { HeartbeatMessageType type; //length 1 Byte uint16 payload_length; // length 2 Bytes opaque payload[HeartbeatMessage.payload_length]; opaque padding[padding_length]; } HeartbeatMessage; [/plain] 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: [plain] p = &s->s3->rrec.data[0] ….. buffer = OPENSSL_malloc(1 + 2 + payload + padding); bp = buffer; ……. memcpy(bp, pl, payload); [/plain] 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:
Exploiting 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:
References: http://heartbleed.com https://github.com/musalbas/heartbleed-masstest/blob/master/top10000.txt http://www.garage4hackers.com/blog.php?b=2551 And many more resources over the internet…