Heartbleed Vulnerability

Heartbleed Vulnerability | Sanket R Jain

What is Heartbleed Vulnerability ?

A typical Heartbleed request consists of payload and payload length that is sent by client to server. When client sends this request, server would revert back with respective response. The Vulnerability existed due to lack in check of payload length. As of which an attacker can send a payload with variable length irrespective of what is in payload. (Mpofu, Elisa and Gati, 2014).

 

Heartbleed Vulnerability | Sanket R Jain

Simplified_Heartbleed_explanation

The above diagram explains how an attacker sends letter “Bird” with length as 500 instead 4. Hence, server would reply “Bird” as well as 496 character along with it resulting in server information may be credentials.

Technicality behind Heartbleed

As mentioned above, vulnerability existed in TLS Heartbleed extension. The C code for the function where this vulnerability existed in listed below.

struct
{ HeartbeatMessageType type;
uint16 payload_length;
opaque payload[HeartbeatMessage.payload_length];
opaque padding[padding_length];
} HeartbeatMessage;

The above code is the Heartbleed request code. The HeartbleedMessage arrives from structure called “SSSL3_RECORD_ST” that lays down the basic building block of communication. (The Register, 2015). The Original C code that lead to the bug is listed below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
unsigned intpayload = 18; /* Sequence number + random bytes */
unsigned intpadding = 16; /* Use minimum padding */
/* Check if padding is too long, payload and padding
* must not exceed 2^14 - 3 = 16381 bytes in total.
*/
OPENSSL_assert(payload + padding <= 16381);
/* Create HeartBeat message, we just use a sequence number
 * as payload to distuingish different messages and add
 * some random stuff.
 *  - Message Type, 1 byte
 *  - Payload Length, 2 bytes (unsigned int)
 *  - Payload, the sequence number (2 bytes uint)
 *  - Payload, random bytes (16 bytes uint)
 *  - Padding
 */
buf = OPENSSL_malloc(1 + 2 + payload + padding);
p = buf;
/* Message Type */
*p++ = TLS1_HB_REQUEST;
/* Payload length (18 bytes here) */
s2n(payload, p);
/* Sequence number */
s2n(s->tlsext_hb_seq, p);
/* 16 random bytes */
RAND_pseudo_bytes(p, 16);
p += 16;
/* Random padding */
RAND_pseudo_bytes(p, padding);
ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding)

Code says that payload and padding length should not exceed than 16381 is due to the reason that maximum size of the Heartbleed comprises of 1 byte of TLS1_HB_REQUEST and 2 bytes is the payload data length.

/* Read type and payload length first */
hbtype = *p++;
n2s(p, payload);
pl = p;

When Heartbleed message is received, pointer p would point to start of the message. Thus message is placed on hbtype and pointer is incremented. Macros n2s would write 16 bit length Heartbleed payload in variable payload and finally pointer is been incremented by2 bytes and pointed to the contents of payload.The corresponding SSSL3_RECORD_ST is been listed below with the fields.

struct ssl3_record_st
{
unsigned int length; /* How many bytes available */
[…]
unsigned char *data; /* pointer to the record data */
[…]
} SSL3_RECORD;

The attribute length is the number of bytes of HeartbleedMessage and data refers to HeartbleedMessage to itself. The original C code for the Heartbleed response to request is listed below.

/* 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);

bp = buffer;

/* Enter response type, length and copy payload */

*bp++ = TLS1_HB_RESPONSE;

s2n(payload, bp);

memcpy(bp, pl, payload);

bp += payload;

/* Random padding */

RAND_pseudo_bytes(bp, padding);

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

The code would run to the end of the data and collects everything that is been defined next o to the memory at the other end of connection which is this case was potential data leak of 64KB (Naked Security, 2014).

/* Enter response type, length and copy payload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);

This code would start responding and initiates with response type of the buffer followed by increment in buffer pointer. Macros s2n would write 16-bit payload length to memory and increased buffer pointer by 2 bytes. Thus the final response would be Heartbleed payload + 1 byte to store message type and two bytes to store payload length and some bytes of padding.

HeartBledd Vulnerability | Saanket R JainThus bug can be showed in diagrammatic representation with respect to the code.The attacker sends 4 bytes payload that is correctly acknowledged by SSL3_recored but length mentioned 65535 has not been verified. Requested HeartbleedMessage would be consisting of payload data of 4 bytes but length of payload would be 65535. Responded HeartbleedMessage would be consisting of payload data and length of 65535 bytes.

Please follow and like us:

1 Comment

  1. Neha Subhanje

    Thank you Mr. Jain for this information!
    some part of my work is done :p

    Reply

Leave a Comment

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