小錯(cuò)誤引發(fā)大危機(jī)——心臟出血到底是什么?
心臟出血漏洞可以追根溯源到開源代碼庫(kù)OpenSSL里的一行代碼上。本文將告訴你心臟出血的工作原理、利用狀況以及怎樣修復(fù)未打補(bǔ)丁的服務(wù)器。
2014年4月,心臟出血漏洞進(jìn)入了公眾視野,該漏洞為攻擊者提供了前所未有的敏感信息獲取途徑,并且成千上萬(wàn)的網(wǎng)絡(luò)服務(wù)器上存在心臟出血漏洞,就連雅虎這樣的網(wǎng)絡(luò)巨頭也在此列。
開源代碼庫(kù)OpenSSL中的一個(gè)漏洞是引發(fā)心臟出血的罪魁禍?zhǔn)?,該漏洞使用了傳輸層安全協(xié)議(TLS)和加密套接字協(xié)議層(SSL)協(xié)議。通過這個(gè)漏洞,簡(jiǎn)而言之,惡意用戶可以很容易地誘騙一個(gè)脆弱的網(wǎng)絡(luò)服務(wù)器發(fā)送用戶名和密碼等敏感信息。
心臟出血漏洞的工作原理
要了解心臟出血(CVE-2014-0160)的工作原理,你必須對(duì)TLS/SSL協(xié)議的運(yùn)作模式和內(nèi)存存儲(chǔ)信息的方式有些許的認(rèn)識(shí)。
TLS / SSL協(xié)議的一個(gè)重要組成部分被稱為“心跳”。從本質(zhì)上講,心跳就是兩臺(tái)電腦互相通信從而讓對(duì)方知道它們?nèi)匀幌噙B,即使用戶沒有下載或上傳任何東西。每過一段時(shí)間,一方會(huì)發(fā)送一個(gè)加密的數(shù)據(jù)到另一臺(tái)電腦上,這被稱為心跳請(qǐng)求。第二臺(tái)電腦會(huì)回復(fù)同樣的加密數(shù)據(jù),來證明連接仍然存在。至關(guān)重要的是,心跳請(qǐng)求里包含自己的長(zhǎng)度信息。
舉個(gè)例子,如果你正在翻閱你的雅虎郵箱,但是在一段時(shí)間內(nèi)沒有進(jìn)行加載信息到操作,網(wǎng)頁(yè)瀏覽器可能會(huì)給雅虎的服務(wù)器發(fā)送一個(gè)信號(hào),該信號(hào)本質(zhì)上是“這是一個(gè)40KB的消息,你如果能獲得它,把它發(fā)回給我”(請(qǐng)求信號(hào)可以最多可以達(dá)到64KB)。雅虎的服務(wù)器收到消息時(shí),會(huì)分配一個(gè)內(nèi)存緩沖區(qū)(一個(gè)物理內(nèi)存區(qū)域用以存儲(chǔ)信息),該區(qū)域的存儲(chǔ)空間和心跳請(qǐng)求信號(hào)里的長(zhǎng)度一致,即40KB。接下來,它會(huì)存儲(chǔ)請(qǐng)求信號(hào)的加密數(shù)據(jù)到內(nèi)存緩沖區(qū),然后讀取數(shù)據(jù)并將其發(fā)送回你的瀏覽器。
這是“心跳”的理想工作方式。心臟出血漏洞的出現(xiàn)是因?yàn)?,OpenSSL的心跳功能缺少了一個(gè)至關(guān)重要的安全維護(hù)手段:計(jì)算機(jī)接受心跳請(qǐng)求時(shí)從不檢查該請(qǐng)求和它聲稱的內(nèi)容是否一致。如果請(qǐng)求說自身的長(zhǎng)度是40KB,但其實(shí)只有20KB,接收電腦會(huì)預(yù)留40KB的內(nèi)存緩沖區(qū),然后只存儲(chǔ)實(shí)際接受的20KB數(shù)據(jù),然后發(fā)送回20KB的原數(shù)據(jù)和接下來20KB的未知內(nèi)容內(nèi)存。這額外的20KB的數(shù)據(jù)就是攻擊者從網(wǎng)站服務(wù)器中提取的信息。
這是操作的關(guān)鍵部分。即使計(jì)算機(jī)處理過某些信息,這些信息會(huì)留在內(nèi)存緩沖區(qū)直到新的信息出現(xiàn)并覆蓋它。如果你是攻擊者,你沒有辦法提前知道剛剛從服務(wù)器獲取的20KB里究竟有什么,但是你可以推測(cè)出一些可能。這些信息有可能是胡言亂語(yǔ)或者無用而繁瑣的東西,也有可能是SSL私鑰,這會(huì)把服務(wù)器的安全通信暴露給攻擊者(這個(gè)可能性很小,但是卻是攻擊者的最高追求)。更常見的是,攻擊者可能會(huì)獲得用戶名和密碼,服務(wù)器上的應(yīng)用或服務(wù)收集并保存了這些信息,這將給予攻擊者登錄和訪問渠道。
蘭德爾·門羅的網(wǎng)絡(luò)漫畫xkcd因?yàn)閷?fù)雜的科學(xué)概念通過淺顯易懂的形式表達(dá)而出名,門羅尤其擅長(zhǎng)就計(jì)算機(jī)領(lǐng)域的問題作畫。這個(gè)2014年誕生的漫畫很好地總結(jié)了心臟出血漏洞是怎樣簡(jiǎn)單而高效地運(yùn)作的。
心臟出血錯(cuò)誤代碼
導(dǎo)致心臟出血漏洞的編程錯(cuò)誤可以歸于一行代碼:
- memcpy(bp, pl, payload);
memcpy()是復(fù)制數(shù)據(jù)的命令。bp是被復(fù)制的數(shù)據(jù)的存儲(chǔ)區(qū)域,pl是被復(fù)制的數(shù)據(jù)的來源,payload是被復(fù)制的數(shù)據(jù)長(zhǎng)度。問題在于,該命令沒有檢驗(yàn)pl復(fù)制的數(shù)據(jù)是否和payload給予的長(zhǎng)度相符。
諷刺的是,OpenSSL是開源軟件。任何人都可以查看代碼,大概幾百人曾訪問過這段代碼,但是沒有人注意到相當(dāng)基本的編碼錯(cuò)誤。
心臟出血的利用狀況
我們至今不知道,在心臟出血廣為人知前,是否有利用該漏洞的現(xiàn)實(shí)攻擊。很可能早在2013年被某些安全公司偵測(cè)到的攻擊就是基于該漏洞的,有人甚至認(rèn)為這些攻擊是由政府安全部門發(fā)起的。
在2014年4月心臟出血漏洞被公開后,企業(yè)爭(zhēng)先恐后地更新了系統(tǒng)。但是黑客仍然能夠在一些情況下利用該漏洞。一起對(duì)社區(qū)衛(wèi)生系統(tǒng)的攻擊被歸咎于心臟出血漏洞,結(jié)果是病人數(shù)據(jù)被大量竊取,與之類似的是加拿大稅務(wù)署數(shù)以百計(jì)的社會(huì)身份號(hào)碼被盜。
如何修復(fù)心臟出血漏洞
心臟出血?jiǎng)偙唤衣恫痪?,OpenSSL就發(fā)布了補(bǔ)丁,而且百分之八九十的受影響服務(wù)器及時(shí)更新了補(bǔ)丁,但是,總會(huì)有些對(duì)你來說至關(guān)重要的服務(wù)器多年來從未進(jìn)行合適的升級(jí),因此,在你不明了某個(gè)服務(wù)器是否已經(jīng)安全的情況下,不妨做個(gè)測(cè)試。Pentest-tools.com有一個(gè)免費(fèi)的網(wǎng)絡(luò)測(cè)試,你可以輸入一個(gè)URL來檢測(cè)服務(wù)器是否已經(jīng)正確地修復(fù)了該漏洞。
修補(bǔ)心臟出血漏洞的方式是更新最新的OpenSSL版本,你可以在官網(wǎng)上獲取相關(guān)鏈接。
因?yàn)镺penSSL是開源的,以下是修復(fù)過的代碼,感興趣的話你可以讀一下:
- * Read type and payload length first */
- if (1 + 2 + 16 > s->s3->relent)
- return 0;
- /* silently discard */
- hbtype = *p++;
- n2s(p, payload);
- if (1 + 2 + payload + 16 > s->s3->rrec.length)
- return 0;
- /* silently discard per RFC 6520 sec. 4 */
- ppl = p;
代碼的第一部分的功能是確定心跳請(qǐng)求的大小不是0KB,不然可能會(huì)出錯(cuò)。第二部分用來檢驗(yàn)心跳的長(zhǎng)度是否和它聲稱的相符。
如果你發(fā)現(xiàn)自己控制的某臺(tái)服務(wù)器已經(jīng)暴露在該漏洞下有一段時(shí)間,你需要做的就不僅僅是更新OpenSSL的代碼了。例如,你應(yīng)該改變SSL證書服務(wù)器,因?yàn)樗鼈兛赡芤呀?jīng)被無聲無息地滲透了。此外,較為麻煩但重要的是:服務(wù)器上保有賬戶信息的用戶應(yīng)該更改密碼。
【本文是51CTO專欄作者“”李少鵬“”的原創(chuàng)文章,轉(zhuǎn)載請(qǐng)通過安全牛(微信公眾號(hào)id:gooann-sectv)獲取授權(quán)】