網絡安全-Heartbleed攻擊

Heartbleed攻擊防范

概述

Heartbleed是一個出現(xiàn)在加密程序庫OpenSSL的安全漏洞,該程序庫廣泛用于實現(xiàn)互聯(lián)網的傳輸層(TLS)協(xié)議.它于2012年被引入了軟件中,2014年4月首次向公眾披露.只要使用的是存在缺陷的OpenSSL實例,無論是服務器還是客戶端,都可能因此而受到攻擊.此問題的原因是在實現(xiàn)TLS的心跳協(xié)議時沒有對輸入進行適當驗證(缺少邊界檢查),讀取的數(shù)據(jù)比應該允許讀取的還多.當前主流OpenSSL中已經不存在這樣的漏洞了,本期實驗需要在陳舊的Ubuntu12系統(tǒng)中完成.

實驗環(huán)境

本期實驗基于2臺Linux系統(tǒng),一臺作為攻擊者,一臺作為受害者.
攻擊者為咱們的主機kali linux,受害者為咱們提供的SEED Ubuntu.
實驗中我們需要用到開源的HTTPS網站ELGG社交網站,在SEED Ubuntu中已經搭建好了.

SEED Ubuntu下載地址如下:
鏈接: https://pan.baidu.com/s/1qRFpF8d5pz6MWNDRW164Bg
密碼: yi4s

實驗環(huán)境下載好了之后,咱們需要在攻擊者系統(tǒng)上配置一下,以便于成功訪問ELGG網站.
咱們的SEED Ubuntu系統(tǒng)的IP地址為192.168.59.148.
\etc\hosts中添加配置192.168.59.148 www.heartbleedlabelgg.com.

現(xiàn)在,我們可以在攻擊者主機成功訪問ELGG網站了. 如圖所示:

成功訪問ELGG網站

任務1:實現(xiàn)Heartbleed攻擊

  • 理解心跳協(xié)議

心跳協(xié)議包含2種報文,心跳請求報文和心跳應答報文.客戶端向服務端發(fā)送心跳請求報文,當服務端收到請求報文之后,將請求報文的消息段copy,在心跳應答報文中返回給客戶端.心跳協(xié)議的目的是確保連接的有效性.如圖所示:

理解心跳協(xié)議
  • 實現(xiàn)Heartbleed攻擊

1.訪問https://www.heartbleedlabelgg.com.

2.登錄(用戶名:admin,密碼:seedelgg).

3.添加好友(點擊More -> Members 點擊 Boby -> Add Friend).

4.發(fā)送消息.

5.多次運行攻擊腳本($ ./attack.py www.heartbleedlabelgg.com).

獲取用戶名和密碼:

獲取用戶名和密碼

獲取發(fā)送消息:

獲取發(fā)送消息

任務2:找出Heartbleed漏洞原因

Heartbleed攻擊基于Heartbeat請求.這個請求只是發(fā)送一些數(shù)據(jù)到服務器,服務器會將數(shù)據(jù)復制到它的響應數(shù)據(jù)包中,所有的數(shù)據(jù)都會被回顯.
在正常情況下,假設請求包含3個字節(jié)的數(shù)據(jù)“ABC”,長度字段的值為3.服務器將數(shù)據(jù)放入內存中,并從數(shù)據(jù)的開頭復制3個字節(jié)到其響應包.
在攻擊場景中,請求可能包含3個字節(jié)的數(shù)據(jù),但長度字段可能表示為1003.當服務器構造其響應數(shù)據(jù)包時,它從數(shù)據(jù)的起始處(即“ABC”)復制,但它復制1003字節(jié),這些額外的1000字節(jié)顯然不是來自請求包,它們來自服務器的私有內存,并且可能包含用戶名,密碼等隱私數(shù)據(jù).

良性請求:

良性請求

惡意請求:

惡意請求

嘗試不同的payload長度值,當載荷長度減小的時候,我們獲取到的額外數(shù)據(jù)量在減少,
當載荷值小于等于22的時候,獲取不到額外的數(shù)據(jù).
$./attack.py www.heartbleedlabelgg.com --length 22

image

任務3:修復Heartbleed漏洞

升級OpenSSL.
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get dist-upgrade

源代碼分析:
心跳請求\應答報文數(shù)據(jù)結構:

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;

處理心跳請求,構造心跳應答的過程:

1 /* Allocate memory for the response, size is 1 byte
2 * message type, plus 2 bytes payload length, plus
3 * payload, plus padding
4 */
5
6 unsigned int payload;
7 unsigned int padding = 16; /* Use minimum padding */
8
9 // Read from type field first
10 hbtype = *p++; /* After this instruction, the pointer
11 * p will point to the payload_length field *.
12
13 // Read from the payload_length field
14 // from the request packet
15 n2s(p, payload); /* Function n2s(p, payload) reads 16 bits
16 * from pointer p and store the value
17 * in the INT variable "payload". */
18
19
20 pl=p; // pl points to the beginning of the payload content
21
22 if (hbtype == TLS1_HB_REQUEST)
23 {
24 unsigned char *buffer, *bp;
25 int r;
26
27 /* Allocate memory for the response, size is 1 byte
28 * message type, plus 2 bytes payload length, plus
29 * payload, plus padding
30 */
31
32 buffer = OPENSSL_malloc(1 + 2 + payload + padding);
33 bp = buffer;
34
35 // Enter response type, length and copy payload
36 *bp++ = TLS1_HB_RESPONSE;
37 s2n(payload, bp);
38
39 // copy payload
40 memcpy(bp, pl, payload); /* pl is the pointer which
41 * points to the beginning
42 * of the payload content */
43
44 bp += payload;
45
46 // Random padding
47 RAND_pseudo_bytes(bp, padding);
48
49 // this function will copy the 3+payload+padding bytes
50 // from the buffer and put them into the heartbeat response
51 // packet to send back to the request client side.
52 OPENSSL_free(buffer);
53 r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
54 3 + payload + padding);
55 }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容