陳希 胡峻潔 張亮 嚴(yán)義兵 雷敏
摘 要:OpenSSL在實(shí)現(xiàn)心跳邏輯時,存在編碼上的缺陷,導(dǎo)致了HeartBleed漏洞的發(fā)生。由于在沒有正確執(zhí)行邊界檢查的前提下,就執(zhí)行memcpy( )函數(shù)調(diào)用受害用戶輸入內(nèi)容作為長度參數(shù),使得攻擊者可以利用該漏洞遠(yuǎn)程讀取存在漏洞版本的OpenSSL服務(wù)器內(nèi)存中多達(dá)64KB的數(shù)據(jù)。論文文通過分析OpenSSL的工作原理,闡明了HeartBleed漏洞產(chǎn)生的根本原因;設(shè)計(jì)并實(shí)現(xiàn)自動化檢測工具,判斷服務(wù)器是否存在該漏洞,并在實(shí)際測試中被成功應(yīng)用。
關(guān)鍵詞:OpenSSL; HeartBleed漏洞; 自動化檢測
中圖分類號:TP312 文獻(xiàn)標(biāo)識碼:A
Design and implementation of automated detection tool for openssl heartbleed vulnerability
Abstract: Heartbeat logic in OpenSSL has a code flaw, leading to the occurrence of HeartBleed vulnerability. The execution of the memcpy( ) function invokes the victim user input content as a length parameter without the proper execution of the boundary check, allowing the attacker to remotely read up to 64KB of data in the OpenSSL server memory where the vulnerability exists. This paper analyzes the principle of OpenSSL and clarifies the root cause of the HeartBleed vulnerability. On this basis, this paper designs and implements the automated detection tool which is successfully applied in the actual test to judge whether the server exists the vulnerability.
Key words: OpenSSL; heartbleed vulnerability; automated detection
1 引言
OpenSSL是一款功能齊全的安全套接字層密碼庫,其作用是為了實(shí)現(xiàn)網(wǎng)絡(luò)通信的加密與認(rèn)證功能。OpenSSL囊括了主要的密碼算法、常用的密鑰和證書封裝管理功能以及SSL(Secure Sockets Layer,安全套接層)協(xié)議,并提供多樣的應(yīng)用程序供使用,保障了網(wǎng)絡(luò)通信的安全。
2014年4月8日,OpenSSL 曝出一種名為HeartBleed (CVE ID:CVE-2014-0160)[1]的嚴(yán)重安全漏洞。該漏洞首先被Google研究員尼爾·梅塔(Neel Mehta)發(fā)現(xiàn),起因是他可以從特定服務(wù)器上隨機(jī)獲取64KB的工作日志。利用該漏洞,黑客可直接對個人電腦發(fā)起“心臟出血”攻擊,從存在漏洞版本的OpenSSL服務(wù)器內(nèi)存中讀取請求存儲位置之外的多達(dá)64 KB的數(shù)據(jù),這段內(nèi)存數(shù)據(jù)可能包含用戶名與密碼、證書私鑰、重要的商業(yè)文檔等數(shù)據(jù)。OpenSSL所具有的強(qiáng)大功能使其被廣泛應(yīng)用于各大網(wǎng)銀、在線支付、電商網(wǎng)站、門戶網(wǎng)站、電子郵件等領(lǐng)域,因此HeartBleed漏洞勢必引發(fā)巨大的網(wǎng)絡(luò)災(zāi)難。目前,中國國家信息安全漏洞共享平臺(CNVD)將該漏洞定級為“高?!盵2]。
鑒于HeartBleed漏洞的危害程度和影響范圍,本文通過研究HeartBleed漏洞原理,設(shè)計(jì)并編寫Python腳本以完成自動化檢測的目的[3],幫助用戶能夠及時發(fā)現(xiàn)安全問題所在,并在最后以內(nèi)網(wǎng)中一臺存在OpenSSL HeartBleed漏洞的主機(jī)(試驗(yàn)機(jī))為例,測試了腳本的運(yùn)行結(jié)果。
2 漏洞原理
2.1 OpenSSL工作原理
OpenSSL是一款實(shí)現(xiàn)了SSL協(xié)議和TLS (Transport Layer Security,安全傳輸層)協(xié)議的開源工具,被廣泛地應(yīng)用于互聯(lián)網(wǎng)各大應(yīng)用中。
SSL協(xié)議位于TCP/IP協(xié)議與各種應(yīng)用層協(xié)議之間,是Netscape公司所研究開發(fā)的一項(xiàng)用于保障網(wǎng)絡(luò)安全的協(xié)議,其通過傳輸層對網(wǎng)絡(luò)連接進(jìn)行加密保護(hù),保障了互聯(lián)網(wǎng)傳輸過程中數(shù)據(jù)的安全性。
SSL協(xié)議主要可分為兩個部分[4]。
(1)SSL記錄協(xié)議(SSL Record Protocol)
記錄協(xié)議處于可靠的傳輸協(xié)議(如TCP)之上,可以實(shí)現(xiàn)高層協(xié)議的數(shù)據(jù)封裝、壓縮、加密等基本功能。明文傳送情況下,SSL記錄協(xié)議的結(jié)構(gòu)如圖1所示。
在圖1中,類型、版本和長度統(tǒng)稱為“記錄頭信息”,共為5個字節(jié),其中:類型占1個字節(jié),用來表示該記錄攜帶的數(shù)據(jù)類型;版本占2個字節(jié),用來表示該記錄的協(xié)議版本,分為主要版本和次要版本,各占1個字節(jié);長度占2個字節(jié),用來表示所攜帶數(shù)據(jù)的長度,但是并不包含記錄頭信息中的5個字節(jié),因此整個記錄的長度應(yīng)為“長度+5”。
(2)SSL握手協(xié)議(SSL Handshake Protocol)
握手協(xié)議位于SSL記錄協(xié)議之上,用于在實(shí)際的數(shù)據(jù)傳輸開始前,為客戶端與服務(wù)器提供身份認(rèn)證、協(xié)商加密算法、交換加密密鑰等服務(wù)[5]。SSL握手協(xié)議的過程如圖2所示。
TLS位于傳輸層和應(yīng)用層之間,其作用是實(shí)現(xiàn)數(shù)據(jù)的安全加密功能??蛻舳讼蚍?wù)器發(fā)送TLS心跳數(shù)據(jù)包,其中用兩個字節(jié)表明有效負(fù)載數(shù)據(jù)長度,而服務(wù)器端OpenSSL將根據(jù)這個有效負(fù)載長度構(gòu)造一個新的數(shù)據(jù)包返回給用戶,用以確認(rèn)彼此在線,以便實(shí)現(xiàn)持續(xù)通信功能。此次“心臟出血”事件中的HeartBleed漏洞正是存在于OpenSSL的TLS Hearbeat擴(kuò)展中,利用了心跳包的正常工作,以獲取到持續(xù)溢出的“心跳信號”數(shù)據(jù)。
2.2 漏洞利用方式
OpenSSL在實(shí)現(xiàn)TLS心跳邏輯時,存在編碼上的缺陷,其心跳處理邏輯并沒有檢測心跳包中的數(shù)據(jù)長度是否和返還的數(shù)據(jù)長度相符合。具體來說,這一漏洞是由于在沒有正確進(jìn)行邊界檢查的前提下就執(zhí)行memcpy( )函數(shù)調(diào)用受害用戶輸入內(nèi)容作為長度參數(shù)所導(dǎo)致的[6]。攻擊者通過追蹤OpenSSL所分配的64KB緩存,將超出必要范圍的字節(jié)信息復(fù)制到緩存中再返回緩存內(nèi)容,這樣一來OpenSSL的內(nèi)存內(nèi)容就會以每次64KB的速度遭受泄露[7]。
利用這一方式,攻擊者可以獲取到網(wǎng)站服務(wù)器中用于加密信息的網(wǎng)絡(luò)密鑰,而后從中截取用戶的個人信息;或者通過直接潛伏在OpenSSL服務(wù)器的內(nèi)存中,達(dá)到隨時且快捷的獲取眾多網(wǎng)站用戶信息的目的。
根據(jù)文獻(xiàn)[8]的標(biāo)準(zhǔn)說明,心跳信息在C語言中的表現(xiàn)形式如下:
這條心跳信息使用SSL3_RECORD結(jié)構(gòu)進(jìn)行傳輸,進(jìn)一步觀察分析SSL3_RECORD結(jié)構(gòu)的定義:
其中,SSL3記錄中的data指向接收到的心跳信息的起始位置;length表示接收到的心跳信息的字節(jié)數(shù)量;而心跳信息中的payload length則表示被返回的有效負(fù)載的字節(jié)數(shù)量。心跳信息的發(fā)送方可以決定payload length,同時SSL3_RECORD結(jié)構(gòu)中的length 字段卻沒有進(jìn)行校驗(yàn),這樣便導(dǎo)致了內(nèi)存溢出情況的發(fā)生[9]。
在接收到心跳信息之后,OpenSSL將對其進(jìn)行如下處理:
其中,p為指向所接收到的HeartbeatMessage的起始處的指針;bp為指向HeartbeatMessage回復(fù)起始位置的指針。根據(jù)上述代碼分析可得:OpenSSL服務(wù)器端是根據(jù)發(fā)送端提供的載荷長度來拷貝數(shù)據(jù)的,然而發(fā)送端用戶可以控制變量payload,即心跳載荷長度和pl的心跳數(shù)據(jù)。
假設(shè)攻擊者指定了最大的payload為65535字節(jié),但是發(fā)往服務(wù)器的心跳數(shù)據(jù)僅為0或1字節(jié),那么memcpy函數(shù)就會把服務(wù)端內(nèi)存中這條SSLv3記錄之后的數(shù)據(jù)復(fù)制到新分配的最大空間的內(nèi)存區(qū)域,并返回給攻擊者。依照上述方法,攻擊者可以重復(fù)獲取服務(wù)器大段內(nèi)存進(jìn)行數(shù)據(jù)分析,得到密碼內(nèi)容等重要信息。
3 檢測工具的設(shè)計(jì)與實(shí)現(xiàn)
3.1 有效攻擊載荷生成
對于檢測工具的設(shè)計(jì)與實(shí)現(xiàn),考慮到Python擁有強(qiáng)大的類庫,非常適合用以快速開發(fā),被廣泛應(yīng)用于眾多自動化測試項(xiàng)目中,因此本文使用Python語言設(shè)計(jì)并編寫OpenSSL HeartBleed漏洞自動化檢測腳本[10]。
通過閱讀心跳拓展協(xié)議RFC 6520,可以分析得到有效攻擊載荷的數(shù)據(jù)結(jié)構(gòu)為:
依據(jù)該結(jié)構(gòu),腳本設(shè)計(jì)了如下攻擊載荷:
hb = h2bin('''
18 03 02 00 03
01 ff ff
''')
其中,“18”表示Heartbeat Type;“03 02”表示TLS的版本號,此處應(yīng)為TLS v1.1;“00 03”表示Heartbeat Message的長度,也就是payload的長度;“01”表示heartbeat_request;“ff ff”表示payload length。而payload和padding都不設(shè)數(shù)據(jù),以便利用漏洞將后續(xù)內(nèi)存中的數(shù)據(jù)復(fù)制出來。
3.2 腳本設(shè)計(jì)
基于OpenSSL的工作原理以及HeartBleed漏洞的利用方式,本文按照如圖3思路設(shè)計(jì)編寫自動化檢測腳本,如圖3所示。
首先,自動化檢測腳本需先建立socket連接,關(guān)鍵代碼如下:
Tcp socket建立完成后,發(fā)送SSL/TLS Client Hello請求,關(guān)鍵代碼如下:
若Server Hello消息返回,則說明SSL/TLS會話已建立成功。其中,在接收服務(wù)器返回的數(shù)據(jù)包時程序調(diào)用了recvmsg函數(shù),該函數(shù)內(nèi)容如下:
該函數(shù)實(shí)現(xiàn)了讀取返回信息的功能,在函數(shù)執(zhí)行的第一步時又調(diào)用了recvall函數(shù),用以從返回的數(shù)據(jù)包中讀取長度為5個字節(jié)的數(shù)據(jù),而后函數(shù)將所讀取的5個字節(jié)以1、2、2字節(jié)分割,其中typ表示數(shù)據(jù)包類型,ver表示TSL版本,ln表示數(shù)據(jù)包長度。recvall函數(shù)關(guān)鍵代碼如下:
下一步,腳本利用hit_hb函數(shù)向服務(wù)器發(fā)送偽造的心跳包,并讀取返回的信息,檢測漏洞是否存在:
如果成功接收到溢出的數(shù)據(jù),那么則表示服務(wù)器存在HeartBleed漏洞,得出檢測結(jié)果:
3.3 實(shí)際測試
實(shí)際測試環(huán)境為安裝了OpenSSL 1.0.1版本的docker鏡像,如圖4所示,首先使用如下命令拉取鏡像到本地:
$ docker pull medicean/vulapps:o_openssl_heartbleed
啟動配置好的安裝有OpenSSL 1.0.1版本的docker鏡像,如圖5所示。
接著,運(yùn)行自動化檢測腳本,如圖6所示。
查看結(jié)果,成功接收到了溢出數(shù)據(jù),實(shí)現(xiàn)了自動化檢測HeartBleed漏洞的目的,如圖7所示。
4 結(jié)束語
OpenSSL在被廣泛應(yīng)用的同時,其安全性也應(yīng)受到更多的重視及研究。本文通過分析OpenSSL的工作原理,闡明了HeartBleed漏洞產(chǎn)生的根本原因及可能被利用的方式,提出編寫Python腳本以實(shí)現(xiàn)自動化檢測的目的。用戶使用本文所設(shè)計(jì)的自動化工具,可以在不損害服務(wù)器的情況下,對服務(wù)器進(jìn)行漏洞檢測,并快速發(fā)現(xiàn)安全問題。
參考文獻(xiàn)
[1] 美國國家標(biāo)準(zhǔn)與技術(shù)所.國家漏洞數(shù)據(jù)庫[EB/OL]. http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2014-0160.
[2] 中國國家信息安全漏洞共享平臺[EB/OL]. http://www.cnvd.org.cn/flaw/show/CNVD-2014-02175.
[3] 丁敏.基于Python語言實(shí)現(xiàn)自動化測試的研究[J].數(shù)字技術(shù)與應(yīng)用,2010(3):88-88.
[4] 檀亞樂,胡曦明,馬苗. SSL協(xié)議工作過程探析[J].網(wǎng)絡(luò)安全技術(shù)與應(yīng)用,2017,(07):36-38.
[5] 胡仁林,張立武.基于模糊綜合分析的SSL/TLS協(xié)議配置安全評估模型研究[J].信息安全研究,2017,3(06):538-547.
[6] 馬虹哲.源代碼安全漏洞檢測方法探討[J].網(wǎng)絡(luò)空間安全,2016,7(Z2):55-58.
[7] 安思華,易平,王春新,李朝峰. OpenSSL Heartbleed漏洞攻擊原理及防范方法研究[J]. 通信技術(shù),2014,47(07):795-799.
[8] SEGGELMANN R,TUEXEN M. Transport Layer Security(TLS) and Datagram Transport Layer Security(DTLS) Heartbeat Extension[EB/OL]. IETF RFC6520. https://tools.ietf.oor/html/rfc6520.
[9] 杜江,羅權(quán).基于代碼審計(jì)技術(shù)的OpenSSL脆弱性分析[J].計(jì)算機(jī)系統(tǒng)應(yīng)用,2017,26(09):253-258.
[10] 錢劼,雷敏,鄒仕洪.Java反序列化漏洞自動檢測腳本設(shè)計(jì)[J].網(wǎng)絡(luò)安全技術(shù)與應(yīng)用,2017,(08):66-68.