這次OpenSSL HeartBleed漏洞是怎么一回事呢?

漫畫圖解
服務器君一共花費了115.050 ms進行了4次數據庫查詢,努力地為您提供了這個頁面。
試試閱讀模式?希望聽取您的建議

“心臟出血”(Heartbleed)被稱為互聯網史上最嚴重的安全漏洞之一,波及了大量常用網站、服務,包括很多人每天都在用的 Gmail 等等,可能導致用戶的密碼、信用卡輕易泄露。但是我們可能對它還不是很了解,可能覺得,這不關我事。

我隨便找了個規模還算比較大的網站(域名就不說了),然后在調試器里看看返回信息:

可以看到,這個網站的服務器也用了OpenSSL。其實 OpenSSL 的使用率還是挺高的,如果你經常上網,那么可以說,你幾乎每天都在跟 OpenSSL 打交道,你的各種個人信息存儲在各種各樣的網站上,一旦某個網站因為 Heartbleed 泄漏了你的重要信息,比如信用卡,銀行卡什么的,那么可能你就會因此有所損失。

好奇的人們或許更想知道OpenSSL的程序員到底犯了什么錯誤,好在有 xkcd 這樣的geek網站,用最最通俗易懂的方式,向大家展示了這個漏洞的原理:

正好煎蛋那邊有翻譯:

所謂heartbleed的說法,源自于「心跳檢測」,就是用戶發通過起TSL 加密鏈接,發起 Client Hello詢問,測服務器是否正常在線干活(形象的比喻就是心臟脈搏),服務器發回Server hello,表明正常建立SSL通信。每次詢問都會附加一個詢問的字符長度pad length,bug來了,如果這個pad length大于實際的長度,服務器還是會返回同樣規模的字符信息,于是造成了內存里信息的越界訪問……

漫畫里,用戶meg請求返回 “HAT 五百個字母”,然后色服器返回了內存中包括HAT之后的前500個字,也就是說伺服器將 “五百個字母” 這句話理解為了 顯示500個字母 然后將其他人在同時伺服器里操作的前500個字母返回給meg看,而這里面包含很多私密信息。

看起來這個內存泄露越界BUG很2嗎?

那么在代碼層面再看看?假設心跳信息結構體定義為:

struct hb {
      int type;
      int length;
      unsigned char *data;                                                    
};

type為心跳的類型,length為data的大小,其中關于data字段的內容結構為:

type字段占一個字節,payload字段占兩個字節,其余的為payload的具體內容,詳情如下所示:

字節序號 備注
0 type
1-2 data中具體的內容的大小為payload
3-len 具體的內容pl

當服務器收到消息后,會對該消息進行解析,也就是對data中的字符串進行解析,通過解析第0位得到type,第1-2位得到payload,接著申請(1+2+payload)大小的內存,然后再將相應的數據拷貝到該新申請的內存中。

以下舉個簡單的示例來說明該問題,假如客戶端發送的data數據為"006abcdef",那么服務器端解析可以得到type=0, payload=06, pl='abcdef',申請(1+2+6=9)大小的內存,然后再將type, payload, pl寫到新申請的內存中。

如果大家都是老實人,那么上述流程不會出現任何問題。可是世界上總是存在著那么多不“安分”的人,他們會非常的不誠實,比如客戶端發送的字符串“abcdef”明明只有6個,而我非得把payload設置為500,如果服務器傻不拉幾的不做任何邊界檢查,直接申請(1+2+500)大小內存,而且更過分的是還把"abcdef********"所有的內容拷貝到新申請的內存處,并發回給客戶端。

這樣那些不安分的人就獲得了服務器上很多非常敏感的信息,這些信息可能包括銀行帳號信息,電子交易信息等等諸多安全信息。

當然真實的結構體定義是這樣的:

typedef struct ssl3_record_st
{
	int type;               /* type of record */
	unsigned int length;    /* How many bytes available */
	unsigned int off;       /* read/write offset into 'buf' */
	unsigned char *data;    /* pointer to the record data */
	unsigned char *input;   /* where the decode bytes are */
	unsigned char *comp;    /* only used with decompression - malloc()ed */
	unsigned long epoch;    /* epoch number, needed by DTLS1 */
	unsigned char seq_num[8]; /* sequence number, needed by DTLS1 */
} SSL3_RECORD;

每條SSLv3記錄中包含一個類型域(type)、一個長度域(length)和一個指向記錄數據的指針(data)。

在 dtls1_process_heartbeat 里有這樣的語句:

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

SSLv3記錄的第一個字節標明了心跳包的類型。宏n2s從指針p指向的數組中取出前兩個字節,并把它們存入變量payload中——這實際上是心跳包載荷的長度域(length)。注意程序并沒有檢查這條SSLv3記錄的實際長度。變量pl則指向由訪問者提供的心跳包數據。

經常看到很多漏洞利用工具命名變量時,都會使用變量名payload,莫非 OpenSSL 的編寫者也經常搞漏洞之類的東西么?

本文地址:http://www.zqhthc.tw/librarys/veda/detail/2622,歡迎訪問原出處。

不打個分嗎?

轉載隨意,但請帶上本文地址:

http://www.zqhthc.tw/librarys/veda/detail/2622

如果你認為這篇文章值得更多人閱讀,歡迎使用下面的分享功能。
小提示:您可以按快捷鍵 Ctrl + D,或點此 加入收藏

大家都在看

閱讀一百本計算機著作吧,少年

很多人覺得自己技術進步很慢,學習效率低,我覺得一個重要原因是看的書少了。多少是多呢?起碼得看3、4、5、6米吧。給個具體的數量,那就100本書吧。很多人知識結構不好而且不系統,因為在特定領域有一個足夠量的知識量+足夠良好的知識結構,系統化以后就足以應對大量未曾遇到過的問題。

奉勸自學者:構建特定領域的知識結構體系的路徑中再也沒有比學習該專業的專業課程更好的了。如果我的知識結構體系足以囊括面試官的大部分甚至吞并他的知識結構體系的話,讀到他言語中的一個詞我們就已經知道他要表達什么,我們可以讓他坐“上位”畢竟他是面試官,但是在知識結構體系以及心理上我們就居高臨下。

所以,閱讀一百本計算機著作吧,少年!

《軟件隨想錄:程序員部落酋長Joel談軟件》 Joel Spolsky (作者), 阮一峰 (譯者)

《軟件隨想錄:程序員部落酋長Joel談軟件》是一部關于軟件技術、人才、創業和企業管理的隨想文集,作者以詼諧幽默的筆觸將自己在軟件行業的親身感悟娓娓道來,觀點新穎獨特,內容簡潔實用。全書分為 36講,每一講都是一個獨立的專題。《軟件隨想錄:程序員部落酋長Joel談軟件》從不同側面滿足了軟件開發人員、設計人員、管理人員及從事軟件相關工作的人員的學習與工作需要。

更多計算機寶庫...

英超直播吻球网