POC详情: 9baaa8965a07925ab1bd6dce299f176078f153cc

来源
关联漏洞
标题: OpenSSL 缓冲区错误漏洞 (CVE-2014-0160)
描述:OpenSSL是OpenSSL团队开发的一个开源的能够实现安全套接层(SSL v2/v3)和安全传输层(TLS v1)协议的通用加密库,它支持多种加密算法,包括对称密码、哈希算法、安全散列算法等。 OpenSSL的TLS和DTLS实现过程中的d1_both.c和t1_lib.c文件中存在安全漏洞,该漏洞源于当处理Heartbeat Extension数据包时,缺少边界检查。远程攻击者可借助特制的数据包利用该漏洞读取服务器内存中的敏感信息(如用户名、密码、Cookie、私钥等)。以下版本的OpenSSL受到
描述
The Heartbleed bug `CVE-2014-0160` is a severe implementation flaw in the OpenSSL library, which enables attackers to steal data from the memory of the victim server. The contents of the stolen data depend on what is there in the memory of the server. It could potentially contain private keys, TLS session keys, usernames, passwords, credit cards, etc. The vulnerability is in the implementation of the Heartbeat protocol, which is used by SSL/TLS to keep the connection alive.
介绍
# Heartbleed

[![License](https://img.shields.io/github/license/Piercealston/Heartbleed?color=black)](LICENSE)

The Heartbleed bug `CVE-2014-0160` is a severe implementation flaw in the OpenSSL library, which enables attackers to steal data from the memory of the victim server. The contents of the stolen data depend on what is there in the memory of the server. It could potentially contain private keys, TLS session keys, usernames, passwords, credit cards, etc. The vulnerability is in the implementation of the Heartbeat protocol, which is used by SSL/TLS to keep the connection alive.

The affected OpenSSL version range is from 1.0.1 to 1.0.1f. The version in the Ubuntu VM is 1.0.1.

The Heartbleed attack is based on the Heartbeat request. This request just sends some data to the server, and the server will copy the data to its response packet, so all the data are echoed back. In the normal case, suppose that the request includes 3 bytes of data ”ABC”, so the length field has a value 3. The server will place the data in the memory, and copy 3 bytes from the beginning of the data to its response packet. In the attack svcenario, the request may contain 3 bytes of data, but the length field may say 1003. When the server constructs its response packet, it copies from the starting of the data (i.e. “ABC”), but it copies 1003 bytes, instead of 3 bytes. These extra 1000 types obviously do not come from the request packet; they come from the server’s private memory, and they may contain other user’s information, secret keys, password, etc.

<p align="center">
    <img src="assets/heartbeat.png">
</p>

Next, change the length field of the request. First, let’s understand how the Heartbeat response packet is built from the figure above. When the Heartbeat request packet comes, the server will parse the packet to get the payload and the `Payload_length` value (which is highlighted above). Here, the payload is only a 3-byte string `"ABC"` and the `Payload_length` value is exactly 3. The server program will blindly take this length value from the request packet. It then builds the response packet by pointing to the memory storing `"ABC"` and copy `Payload_length` bytes to the response payload. In this way, the response packet would contain a 3-byte string `"ABC"`.

Next, launch the Heartbleed attack like what is shown in the figure below. Keep the same payload (3 bytes), but set the `Payload_length` field to 1003. The server will again blindly take this `Payload_length` value when building the response packet. This time, the server program will point to the string `"ABC"` and copy 1003 bytes from the memory to the response packet as a payload. Besides the string `”ABC”`, the extra 1000 bytes are copied into the response packet, which could be anything from the memory, such as secret activity, logging information, password and so on.

The attack code allows the `Payload_length` value to change. By default, the value is set to a quite large one (0x4000), but it can reduced.

<p align="center">
    <img src="assets/heartbleed.png">
</p>

The easiest way to fix the Heartbleed vulnerability is to update the OpenSSL library to the newest version. However, the objective is to patch the vulnerability via the source code.

**Format of the Heartbeat request/response packet**

```c
struct {
    HeartbeatMessageType type;  // 1 byte: request or the response
    uint16 payload_length;      // 2 byte: the length of the payload
    opaque payload[HeartbeatMessage.payload_length];
    opaque padding[padding_length];
} HeartbeatMessage;
```

The first field (1 byte) of the packet is the type information, and the second field (2 bytes) is the payload length, followed by the actual payload and paddings. The size of the payload should be the same as the value in the payload length field, but in the attack scenario, payload length can be set to a different value. The following code snippet shows how the server copies the data from the request packet to the response packet.

**Process the Heartbeat request packet and generate the response packet**

```c
/* Allocate memory for the response, size is 1 byte
 * message type, plus 2 bytes payload length, plus
 * payload, plus padding
*/

unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */

// Read from type field first
hbtype = *p++; /* After this instruction, the pointer
                * p will point to the payload_length field */

// Read from the payload_length field from the request packet
n2s(p, payload); /* Function n2s(p, payload) reads 16 bits
                  * from pointer p and store the value
                  * in the INT variable "payload". */

pl = p; // pl points to the beginning of the payload content

if (hbtype == TLS1_HB_REQUEST)
{
    unsigned char *buffer, *bp;
    int r;

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

    // copy payload
    memcpy(bp, pl, payload);   /* pl is the pointer which
                                * points to the beginning
                                * of the payload content */
    bp += payload;

    // Random padding
    RAND_pseudo_bytes(bp, padding);

    // this function will copy the 3+payload+padding bytes
    // from the buffer and put them into the heartbeat response
    // packet to send back to the request client side.
    OPENSSL_free(buffer);
    r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
}
```

**The vulnerability lies here**

```c
    // copy payload
    memcpy(bp, pl, payload);
```

There is no check to determine if `pl` is valid or not. Therefore, a memory breach can occur.

Patches:

-   Bounds checking before `memcpy()` is executed
-   Server calculates packet size at runtime which requires additional overhead

> Patches were made in the VM but are not shown in this repo.

---

Thank you for your interest, this project was fun and insightful!
文件快照

[4.0K] /data/pocs/9baaa8965a07925ab1bd6dce299f176078f153cc ├── [4.0K] assets │   ├── [573K] attack_screenshots_vm.pdf │   ├── [ 86K] heartbeat.png │   └── [ 88K] heartbleed.png ├── [ 19K] attack.py ├── [1.1K] LICENSE ├── [6.0K] README.md └── [ 43] secret.txt 1 directory, 7 files
神龙机器人已为您缓存
备注
    1. 建议优先通过来源进行访问。
    2. 如果因为来源失效或无法访问,请发送邮箱到 f.jinxu#gmail.com 索取本地快照(把 # 换成 @)。
    3. 神龙已为您对POC代码进行快照,为了长期维护,请考虑为本地POC付费,感谢您的支持。