OpenSSl HeartBleed 漏洞分析及驗證
前段時間寫的漏洞的分析報告貼上來~
OpenSSlHeartBleed 漏洞分析及驗證
一.漏洞爆出
OpenSSL是一個使用非常廣泛的開源加密庫,用來實現網路通訊的加密。本次爆出的OpenSSL 是TLS心跳造成遠端資訊洩露漏洞 (CVE-2014-0160)
在處理TLS心跳擴充套件中缺失了邊界檢查,可導致伺服器端64K記憶體資訊的洩露
影響版本:OpenSSL Project OpenSSL 1.0.2-beta
OpenSSL Project OpenSSL 1.0.1
漏洞公佈的資訊
二.漏洞成因
TLS心跳延長首次記載是在RFC6520,心跳被用作“保持活動”的資料包,這樣的加密連線的兩端都同意保持會話開啟,即使他們沒有交換任何官方資料。因為心跳由一個答覆,並匹配響應,不僅使會話是確認開放的,也表明終端對終端的連線是否正常工作
上面這個連結是漏洞發現者的分析,我們這裡簡要說明下這個漏洞的成因
心跳請求:
OpenSSL heartbeat request code looks like this:
unsigned int payload = 18; /* Sequencenumber + random bytes */
unsigned int padding = 16; /* Use minimumpadding */
/* Check if padding is too long, payloadand padding
* must not exceed 2^14 - 3 = 16381 bytes intotal.
*本人注:在RFC6520中要求心跳最大尺寸為2^14(16K)個位元組
*其實這個地方通過傳送心跳的包來看,這個地方限制在了14個位元組
*其他三個位元組分別為1個位元組心跳請求訊號TLS1_HB_REQUEST和2個位元組的請求中指明的payload長度,也就是這個地方出現了bug,我們繼續分析
*p.s這個漏洞一直說可以可以dump64K的記憶體處理,但是修改攻擊程式碼,還是隻能取得16K,*可能就跟這個地方有關係
*/
OPENSSL_assert(payload + padding <=16381);
/* Create HeartBeat message, we just use asequence number
* as payload to distuingish differentmessages and add
* some random stuff.
* - Message Type, 1 byte
* - Payload Length, 2 bytes(unsigned int)
* - Payload, the sequencenumber (2 bytes uint)
* - Payload, random bytes (16bytes 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);
該程式碼然後傳送包括心跳的標準請求:
· 單位元組0x01(表示這是一個TLS1_HB_REQUEST)。
· payload大小,兩個位元組
· payload的序列號,兩個位元組
· payload中的隨機位元組,16個位元組
· padding,16個位元組的隨機填充字元
這裡我們可以根據攻擊POC中直觀的看到定義的這種心跳資料結構,構造的包為
hb=h2bin('''1803020003014000''')
其中0x18 0x03 0x02為TLS1.1版本的版本資訊,0x00 0x03 為心跳包請求的長度,0x01即為TLS1_HB_REQUEST,0x40 0x00即為payload的長度,這個是可修改的,這個POC沒有隨機字元和padding,所以請求包長度為3個位元組,網路包大位元組序
回覆心跳請求
當OpenSSL的1.0.1版本,在處理接收到的心跳資料時,
/* Enter response type, length and copypayload */
*bp++ = TLS1_HB_RESPONSE;
s2n(payload, bp);
memcpy(bp, pl, payload);
心跳答覆都應該包含來自請求的有效載荷資料的副本,這裡通過memcpy直接將pl指向的地址資料中,將具有payload長度的資料回覆給請求端,沒有進行payload長度的驗證,也就是說你可以傳送一個小的心跳請求,但你偷偷有效載荷長度欄位設定為0xFFFF(65535位元組)。然後,OpenSSL的將毫無怨言地從你的請求資料包複製65535位元組,即使你沒有送跨越很多位元組,這意味著給OpenSSL傳送一個畸形的心跳請求,則會將64K的記憶體資料洩露。
三.漏洞驗證
我們這裡採用攻擊POC進行驗證分析(不公佈測試POC,網上流傳著很多版本,但是注意各利用裡內容,小心直接弄個反彈就不好了)
我們只進行測試性驗證,比如某雲服務(好像圖貼不過來了啊,那就算了)
我們從中看到了uername,password,經過驗證時可以登入成功的
我們看另外一個驗證結果,是一款聊天通訊軟體,我們看看測試結果
收集到的資訊包括使用者名稱,密碼,還有登陸的其他資訊等等,儘管這個密碼是MD5加密的,但是md5加密的結果還是部分能夠解開的,所以危害同樣巨大
四. 漏洞危害
該漏洞利用的成本低,可以一直這麼dump記憶體出來,儘管裡邊包含了很多無用和截斷資訊,但是還是可以收集到很多隱私資訊的,比如私鑰,使用者名稱,密碼,cookie等等
淘寶,yahoo,12306等等網站,好多都存在這種問題,而且危害被逐漸挖掘出來,比如服務端和客戶端對打~
五. 建議
1. 立即更新補丁
OpenSSL Project已經為此釋出了一個安全公告(secadv_20140407)以及相應補丁
2.比如在IPS裝置上檢測這種漏洞可以用請求包的長度和次數做檢測
Since OpenSSL uses hardcoded values thatnormally result in a 61 byte heartbeat message size
比如可以參考:alert tcp $EXTERNAL_NET any -> $HOME_NET 443(msg:"SERVER-OTHER OpenSSL TLSv1.1 heartbeat read overrun attempt";flow:to_server,established; content:"|18 03 02|"; depth:3;dsize:>40; detection_filter:track by_src,
count 3, seconds 1;metadata:policy balanced-ips drop, policy security-ips drop, service ssl;reference:cve,2014-0160; classtype:attempted-recon; sid:30512; rev:2;)
alert tcp $HOME_NET 443 -> $EXTERNAL_NET any (msg:"SERVER-OTHER TLSv1.1large heartbeat response - possible ssl heartbleed attempt";flow:to_client,established; content:"|18 03 02|"; depth:3;byte_test:2,>,128,0,relative; detection_filter:track by_dst, count 5,seconds
60; metadata:policy balanced-ips drop, policy security-ips drop,service ssl; reference:cve,2014-0160; classtype:attempted-recon; sid:30516;rev:3;)
埠並不要一定要限定在443,比如POP3收郵件就是POP3 SSL 995埠
後來又出來一種基於SSL加密管道下,然後再進行heartbleed打的情況,這種情況,一般IPS是很難搞定的
3.最近如果登陸過這些網站,注意修改密碼