摘要
自動(dòng)生成漏洞利用樣本(AEG)已成為評(píng)估漏洞的最重要的方式之一, 但現(xiàn)有方案在目標(biāo)系統(tǒng)部署有漏洞緩解機(jī)制時(shí)受到很大阻礙. 當(dāng)前主流的操作系統(tǒng)默認(rèn)部署多種漏洞緩解機(jī)制, 包括數(shù)據(jù)執(zhí)行保護(hù)(DEP)和地址空間布局隨機(jī)化(ASLR)等, 而現(xiàn)有AEG方案仍無法面對(duì)所有漏洞緩解情形. 提出了一種自動(dòng)化方案EoLeak, 可以利用堆漏洞實(shí)現(xiàn)自動(dòng)化的信息泄露, 進(jìn)而同時(shí)繞過數(shù)據(jù)執(zhí)行保護(hù)和地址空間布局隨機(jī)化防御. EoLeak通過動(dòng)態(tài)分析漏洞觸發(fā)樣本(POC)的程序執(zhí)行跡, 對(duì)執(zhí)行跡中的內(nèi)存布局進(jìn)行畫像并定位敏感數(shù)據(jù)(如代碼指針), 進(jìn)而基于內(nèi)存畫像自動(dòng)構(gòu)建泄漏敏感數(shù)據(jù)的原語, 并在條件具備時(shí)生成完整的漏洞利用樣本. 實(shí)現(xiàn)了EoLeak原型系統(tǒng), 并在一組奪旗賽(CTF)題目和多個(gè)實(shí)際應(yīng)用程序上進(jìn)行了實(shí)驗(yàn)驗(yàn)證. 實(shí)驗(yàn)結(jié)果表明, 該系統(tǒng)具有自動(dòng)化泄露敏感信息和繞過DEP及ASLR緩解機(jī)制的能力.
自動(dòng)生成漏洞利用樣本(automatic exploit generation, AEG)[1,2]已經(jīng)成為評(píng)估漏洞的最重要方式之一. 給定一個(gè)有漏洞的二進(jìn)制程序以及觸發(fā)漏洞的POC (proof-of-concept)樣本, AEG系統(tǒng)可以自動(dòng)分析目標(biāo)二進(jìn)制程序并生成漏洞利用樣本. AEG不僅可以輔助生成攻擊, 同樣可以輔助防御. 例如, 軟件供應(yīng)商可以使用AEG工具來評(píng)估軟件漏洞的威脅級(jí)別, 并確定漏洞修復(fù)的緊迫性.
近年來, 研究人員已提出許多AEG方案. 早期工作[3?8]主要關(guān)注對(duì)棧和格式化字符串漏洞的分析, 其漏洞利用模式相對(duì)固定、有效. 而近年來的工作[9?15]更注重堆等復(fù)雜類型漏洞, 需要更復(fù)雜的利用技巧, 例如堆內(nèi)存布局操控, 以構(gòu)建可行的漏洞利用樣本. 然而, 現(xiàn)有AEG工作很少考慮目標(biāo)環(huán)境中部署有漏洞緩解等防御機(jī)制的場景, 這些漏洞緩解機(jī)制為漏洞利用帶來極大的挑戰(zhàn). 事實(shí)上, 隨著現(xiàn)代操作系統(tǒng)廣泛部署各種漏洞緩解機(jī)制, 若攻擊者想在如今的生產(chǎn)服務(wù)環(huán)境中進(jìn)行實(shí)際攻擊, 突破目標(biāo)環(huán)境中的防御機(jī)制是必須解決的重要問題.
現(xiàn)代操作系統(tǒng)中廣泛部署了3種著名的防御機(jī)制, 包括數(shù)據(jù)執(zhí)行保護(hù)(NX/DEP)[16]、棧保護(hù)變量(Canary/ Cookie)[17]和地址空間布局隨機(jī)化(address space layout randomization, ASLR)[18]. 數(shù)據(jù)執(zhí)行保護(hù)DEP的目標(biāo)是, 防止內(nèi)存中寫入的數(shù)據(jù)被當(dāng)作代碼來執(zhí)行. 設(shè)置棧保護(hù)變量Canary可以在棧緩沖區(qū)溢出漏洞覆蓋棧幀中的函數(shù)返回地址時(shí)檢測到該破壞行為. 地址空間布局隨機(jī)化ASLR則將內(nèi)存中的代碼段、數(shù)據(jù)段、堆棧等的基地址隨機(jī)化, 使攻擊者難以找到可用的重要數(shù)據(jù)和代碼的地址, 從而使得攻擊變得更加困難. 除此之外, 還有一些其他漏洞利用緩解措施, 包括控制流完整性解決方案[19?21]等, 也可以有效緩解漏洞利用. 但是由于性能和兼容性等各種問題, 廠商尚未廣泛部署這些保護(hù)措施. 因而, 自動(dòng)生成漏洞利用樣本的AEG方案目前主要需要考慮DEP、ASLR、Canary等防御機(jī)制繞過即可.
在當(dāng)前的AEG工作中, 部分方案[4,5,22,23]假設(shè)目標(biāo)環(huán)境和程序沒有啟用防御機(jī)制, 部分方案[8,12?14]可以繞過數(shù)據(jù)執(zhí)行保護(hù)但無法對(duì)抗地址空間布局隨機(jī)化, 部分方案[3,6,7,24?26]可以通過棧漏洞繞過地址空間布局隨機(jī)化保護(hù), 或在沒有數(shù)據(jù)執(zhí)行保護(hù)的情況下通過堆漏洞繞過地址空間布局隨機(jī)化. 目前, 尚未有工作研究通過堆漏洞繞過數(shù)據(jù)執(zhí)行保護(hù)和地址空間布局隨機(jī)化的防御.
繞過地址空間布局隨機(jī)化防護(hù)的關(guān)鍵在于泄漏被隨機(jī)化的內(nèi)存地址. 目前部署在現(xiàn)代操作系統(tǒng)中的地址空間布局隨機(jī)化防御基于大尺寸的內(nèi)存段, 包括棧、堆和共享庫, 粒度相對(duì)較粗. 其中, 每個(gè)段內(nèi)的偏移是不受隨機(jī)化影響的固定值. 繞過地址空間布局隨機(jī)化的最有效策略是泄漏某個(gè)段的地址, 從這個(gè)地址可以推斷出攻擊者所需的所有在同一段內(nèi)的其他地址, 其位于固定偏移處. 因此, 我們需要找到一個(gè)包含隨機(jī)化后地址的指針進(jìn)行泄漏. 常見的方法包括借用目標(biāo)二進(jìn)制程序本身的語義或構(gòu)建新的輸出功能, 觸發(fā)輸出函數(shù)以打印出該地址. 通過這個(gè)泄漏的隨機(jī)地址, 攻擊者可以推斷其他代碼地址并基于此完成漏洞利用.
本文提出了一種面向緩解機(jī)制評(píng)估的自動(dòng)化信息泄漏系統(tǒng)EoLeak, 可以通過堆漏洞同時(shí)繞過數(shù)據(jù)執(zhí)行保護(hù)和地址空間布局隨機(jī)化, 達(dá)成利用效果. EoLeak首先通過對(duì)觸發(fā)漏洞的POC的運(yùn)行時(shí)內(nèi)存執(zhí)行過程進(jìn)行動(dòng)態(tài)分析, 定位敏感信息的變量位置, 然后自動(dòng)地為敏感信息變量構(gòu)建信息泄漏, 并根據(jù)泄漏的信息生成漏洞利用樣本. 為了定位內(nèi)存中的重要變量, 方案通過構(gòu)建內(nèi)存畫像來記錄所有有關(guān)信息并搜索可能的泄漏路徑. 為了構(gòu)建泄漏能力, 方案通過堆漏洞分析模型來實(shí)現(xiàn)對(duì)堆漏洞的初步攻擊, 擴(kuò)展了內(nèi)存利用能力. 方案還執(zhí)行了一種輕量級(jí)動(dòng)態(tài)污點(diǎn)策略, 通過監(jiān)控內(nèi)存緩沖區(qū)的傳輸操作來搜索具有用戶可控參數(shù)的庫函數(shù)調(diào)用, 降低了插樁開銷. 對(duì)于最終的漏洞利用, 方案遵循相似的策略來構(gòu)建用戶可控的庫函數(shù)調(diào)用, 并妥善處理了泄漏失敗的特殊情形.
我們?cè)诨赒EMU的記錄和重放平臺(tái)PANDA[27]上實(shí)現(xiàn)了該系統(tǒng), 并通過17個(gè)CTF堆漏洞二進(jìn)制程序和5個(gè)真實(shí)世界軟件對(duì)其進(jìn)行了評(píng)估. 結(jié)果表明, 系統(tǒng)成功生成了15個(gè)自動(dòng)泄漏樣本和14個(gè)最終利用樣本.對(duì)于真實(shí)軟件, 系統(tǒng)可以自動(dòng)分析、定位敏感信息的運(yùn)行時(shí)內(nèi)存地址和相關(guān)指針.
1 研究案例
針對(duì)堆漏洞繞過數(shù)據(jù)執(zhí)行保護(hù)和地址空間布局隨機(jī)化的AEG解決方案面臨著與分析人員手工構(gòu)造利用樣本相同的問題. 本節(jié)中, 我們通過對(duì)一個(gè)實(shí)際的堆漏洞利用案例進(jìn)行研究, 來概述所面臨的挑戰(zhàn)和本文所提出的泄漏系統(tǒng)解決方案.
1.1堆漏洞利用案例
如圖 1所示, 目標(biāo)程序邏輯簡化后可以表示為圖 1所示代碼(level參數(shù)確保合法), 其中存在一個(gè)釋放后使用(use after free)的堆漏洞. 程序在第20行調(diào)用堆塊釋放函數(shù)時(shí)未檢查指向目標(biāo)堆塊的buf指針是否合法, 也未在堆塊被釋放后將指向堆塊的buf指針置零.
圖 1堆漏洞示例代碼
POC通過構(gòu)造重疊的堆塊內(nèi)存布局來觸發(fā)漏洞. 如圖 2所示, 矩形代表堆塊頭部和堆塊區(qū)域, 側(cè)方的矩形條代表對(duì)應(yīng)堆塊指針buf的當(dāng)前指向區(qū)域. 當(dāng)依次執(zhí)行: (a) 創(chuàng)建小堆塊; (b) 釋放小堆塊; (c) 創(chuàng)建大堆塊; (d) 釋放小堆塊; (e) 創(chuàng)建小堆塊; (f) 創(chuàng)建中堆塊之后, 不僅所有堆塊所對(duì)應(yīng)的存在指示都被置為真, 且大堆塊指針和小堆塊指針發(fā)生了重疊, 都指向了(f)中小堆塊的起始地址, 還讓大堆塊指針指向的區(qū)域可以對(duì)包括小堆塊區(qū)域、中堆塊頭部、中堆塊區(qū)域在內(nèi)的內(nèi)存區(qū)域進(jìn)行覆蓋. 這樣, 對(duì)大堆塊的寫入可以造成對(duì)中堆塊頭部的堆溢出.
圖 2輸入漏洞觸發(fā)樣本時(shí)程序執(zhí)行過程中堆內(nèi)存布局變化示意
當(dāng)攻擊者試圖利用這類啟用了地址空間布局隨機(jī)化防護(hù)的漏洞時(shí), 其首先嘗試泄漏libc庫的隨機(jī)化后的地址. 通過在小堆塊中創(chuàng)建一個(gè)偽造的堆塊并執(zhí)行safe unlink攻擊, 指向小堆塊的指針將被篡改為一個(gè)略低于該指針本身地址的值, 小堆塊包含了指向大堆塊的指針. 此時(shí), 便可以通過依次修改小堆塊和大堆塊的內(nèi)容, 先后篡改大堆塊指針的值及其指向內(nèi)存區(qū)域的數(shù)據(jù), 實(shí)現(xiàn)任意地址寫. 攻擊者可以借助任意地址寫原語用輸出庫函數(shù)的過程鏈接表地址替換全局偏移表中的某個(gè)libc庫函數(shù)地址, 并在觸發(fā)該函數(shù)調(diào)用時(shí)以任意libc庫函數(shù)指針為第1個(gè)參數(shù), 從而實(shí)現(xiàn)了泄漏libc庫函數(shù)地址. 借助該泄漏地址, 攻擊者可以計(jì)算libc庫中system函數(shù)和“/bin/sh”字符串等信息的實(shí)際運(yùn)行時(shí)地址, 將其寫回堆塊中并觸發(fā)system函數(shù)調(diào)用, 以完成漏洞利用.
1.2攻擊模型
本文假定在目標(biāo)環(huán)境中啟用了3種廣泛部署的防御機(jī)制, 包括數(shù)據(jù)執(zhí)行保護(hù)[16]、棧保護(hù)變量[17]和地址空間布局隨機(jī)化[18]. 同時(shí)還假定目標(biāo)二進(jìn)制程序中存在一個(gè)常見的堆漏洞可以利用, 例如釋放后使用或堆溢出.
此外, 本文假定攻擊者擁有一個(gè)可以觸發(fā)堆漏洞的漏洞觸發(fā)樣本, 廣泛發(fā)展的漏洞發(fā)現(xiàn)工具可以滿足這一要求. 由于現(xiàn)代AEG解決方案通常都允許用戶提供對(duì)應(yīng)的漏洞利用輸入模板[28], 本文允許攻擊者對(duì)漏洞觸發(fā)樣本做一些劃分以輔助跟蹤分析. 本文還假定攻擊者可以通過最近的一些堆布局操縱工作[9?11]掌握堆風(fēng)水能力, 以便通過漏洞觸發(fā)樣本提供一個(gè)相對(duì)方便而確定的堆布局, 輔助進(jìn)一步分析.
1.3研究挑戰(zhàn)
在漏洞利用過程中, 攻擊者需要找到一個(gè)隨機(jī)化后的libc庫函數(shù)地址進(jìn)行泄漏, 然后依據(jù)泄漏的地址信息生成漏洞利用樣本. 泄漏和利用生成都要求以攻擊者控制的參數(shù)調(diào)用某些特定的庫函數(shù)(包括打印數(shù)據(jù)和系統(tǒng)函數(shù)). 為了實(shí)現(xiàn)這一目標(biāo), 需要解決以下多個(gè)挑戰(zhàn).
(1) 挑戰(zhàn)1: 哪些重要的敏感信息值得泄漏, 又如何定位其在內(nèi)存中的位置? 例如, 要繞過地址空間布局隨機(jī)化, 需要通過信息泄漏來獲得一個(gè)隨機(jī)化后的地址. 在僅給定目標(biāo)二進(jìn)制文件和POC時(shí), 需要對(duì)運(yùn)行過程中的內(nèi)存結(jié)構(gòu)構(gòu)建內(nèi)存畫像;
(2) 挑戰(zhàn)2: 如何泄漏所定位的敏感信息? 用戶只能通過向程序提供輸入來影響二進(jìn)制程序的執(zhí)行過程. 為了實(shí)現(xiàn)信息泄漏, 攻擊者需要確定正確的輸入以觸發(fā)打印特定位置數(shù)據(jù)的功能;
(3) 挑戰(zhàn)3: 如何根據(jù)泄漏的信息生成漏洞利用樣本? 即便信息遭到泄漏, 仍與漏洞利用存在一定的距離, 需要額外工作來跨越這其中的障礙.
1.4自動(dòng)泄漏方案
為了解決上述挑戰(zhàn), 本文提出了一種新穎的解決方案EoLeak, 來自動(dòng)執(zhí)行面向漏洞利用的敏感信息泄漏和相應(yīng)的漏洞利用樣本生成. 總的來說, 方案對(duì)二進(jìn)制程序執(zhí)行跡進(jìn)行動(dòng)態(tài)分析, 對(duì)運(yùn)行時(shí)內(nèi)存結(jié)構(gòu)構(gòu)建內(nèi)存畫像, 定位有價(jià)值的數(shù)據(jù)變量, 構(gòu)建用戶可控的讀寫能力, 并生成繞過地址空間布局隨機(jī)化和數(shù)據(jù)執(zhí)行保護(hù)的堆漏洞利用樣本.
方案使用給定的POC來分析二進(jìn)制文件的運(yùn)行過程, 并識(shí)別參與計(jì)算的指針和敏感變量, 將相關(guān)內(nèi)存信息及時(shí)間戳記錄在圖中, 從而可以找到通往指定內(nèi)存位置的一條嵌套指針鏈條.
為了構(gòu)建泄漏能力, 方案首先基于堆內(nèi)存模型, 利用堆漏洞來獲得更廣泛的內(nèi)存操縱能力. 通過執(zhí)行輕量級(jí)動(dòng)態(tài)污點(diǎn)分析來跟蹤用戶輸入字節(jié), 方案分析用戶可控內(nèi)存區(qū)域, 從二進(jìn)制程序執(zhí)行路徑中提取抽象的堆操作信息, 并從預(yù)先設(shè)定的堆利用模板列表中檢查相符合的堆漏洞利用條件是否被滿足. 為了減少污點(diǎn)分析性能開銷, 并直接獲得用戶輸入和內(nèi)存數(shù)據(jù)之間的聯(lián)系, 本文采用的污點(diǎn)分析只考慮內(nèi)存?zhèn)鬏敳僮髯鳛閭鞑ゲ呗?
構(gòu)建漏洞利用樣本遵循與構(gòu)建泄漏能力相似的策略. 方案通過任意或可控的內(nèi)存寫來以指定的參數(shù)調(diào)用目標(biāo)庫函數(shù), 執(zhí)行漏洞利用. 對(duì)于自動(dòng)泄漏失敗或二進(jìn)制文件受到其他高級(jí)防御機(jī)制保護(hù)的情形, 方案還嘗試使用相應(yīng)的堆漏洞利用技術(shù)來直接生成漏洞利用樣本.
2 系統(tǒng)設(shè)計(jì)
本節(jié)介紹了EoLeak方案的設(shè)計(jì)細(xì)節(jié). 如圖 3所示, 主要有3個(gè)步驟.
圖 3自動(dòng)化信息泄漏系統(tǒng)總覽
1、敏感信息定位. 給定一個(gè)有漏洞的二進(jìn)制程序和一個(gè)觸發(fā)堆漏洞的POC, 方案首先分析程序執(zhí)行跡, 提取指令語義, 通過恢復(fù)指針和有價(jià)值的內(nèi)存對(duì)象來定位它們的位置. 我們通過內(nèi)存畫像來記錄變量地址并維護(hù)一個(gè)指針圖來搜索到特定地址的泄漏路徑;
2、構(gòu)建信息泄漏. 方案利用堆模型, 通過堆漏洞利用模板來實(shí)現(xiàn)漏洞推斷, 以擴(kuò)展內(nèi)存操縱能力并執(zhí)行輕量級(jí)動(dòng)態(tài)污點(diǎn)分析, 來研究用戶輸入與庫函數(shù)調(diào)用參數(shù)之間的關(guān)系. 通過構(gòu)建讀寫功能來實(shí)現(xiàn)參數(shù)受控, 方案可以構(gòu)建泄漏原語來打印出敏感信息;
3、生成利用樣本. 方案通過與構(gòu)建泄漏能力類似的策略來依據(jù)泄漏信息生成目標(biāo)二進(jìn)制文件的最終利用樣本. 如果無法觸發(fā)選定參數(shù)的漏洞利用庫函數(shù)調(diào)用, 方案還會(huì)使用相應(yīng)的模板來處理特定的堆漏洞利用情形作為補(bǔ)充.
2.1敏感信息定位
EoLeak方案的第1步是使用POC運(yùn)行給定的有漏洞的二進(jìn)制程序, 并在執(zhí)行過程中探索敏感信息.
2.1.1重要數(shù)據(jù)
在程序的整個(gè)執(zhí)行過程中會(huì)產(chǎn)生許多指針和內(nèi)存對(duì)象參與計(jì)算. 其中, 我們認(rèn)為以下3種信息值得注意.
1、程序執(zhí)行中使用的代碼指針, 尤其是位于可寫內(nèi)存區(qū)域的代碼指針;
2、內(nèi)存對(duì)象指針, 包括由堆分配函數(shù)返回的堆塊指針;
3、程序執(zhí)行中頻繁訪問的變量, 或作為函數(shù)調(diào)用參數(shù)的變量.
可寫代碼指針在漏洞利用中非常寶貴, 因?yàn)橥ㄟ^篡改這些指針, 攻擊者可以劫持控制流. 并且可寫代碼指針在隨機(jī)化后的代碼空間中為推理共享庫的基地址提供了參考. 敏感數(shù)據(jù)通常作為成員變量被存儲(chǔ)在內(nèi)存對(duì)象中, 內(nèi)存對(duì)象的地址空間在堆管理器控制之下, 我們通過堆塊指針來掌握運(yùn)行時(shí)堆的狀態(tài), 從而推理內(nèi)存對(duì)象在內(nèi)存空間中的分布. 部分變量, 如數(shù)據(jù)結(jié)構(gòu)的起始指針經(jīng)常參與后續(xù)數(shù)據(jù)結(jié)構(gòu)的運(yùn)算, 或常作為參數(shù)被應(yīng)用程序接口調(diào)用. EoLeak方案認(rèn)為這些變量對(duì)漏洞利用生成也很重要, 記錄了這類變量的訪問頻率.
2.1.2內(nèi)存畫像
為了識(shí)別和定位上述敏感信息, EoLeak方案在執(zhí)行動(dòng)態(tài)程序執(zhí)行跡分析時(shí)構(gòu)建了內(nèi)存畫像: 對(duì)每條指令進(jìn)行反匯編以獲取其操作碼和操作數(shù)信息, 并從執(zhí)行跡中提取對(duì)應(yīng)操作數(shù)的運(yùn)行時(shí)變量值. 通過分析寄存器和內(nèi)存操作數(shù)的尋址模式, 方案識(shí)別指針并對(duì)訪問進(jìn)行計(jì)數(shù), 然后將數(shù)據(jù)添加到全局內(nèi)存指向映射中, 該映射保存了所有記錄的內(nèi)存位置和變量聲明周期時(shí)間戳.
為了定位保存libc等庫函數(shù)地址的指針, EoLeak方案首先查找所有屬于該庫內(nèi)存段的運(yùn)行時(shí)地址變量值.通過一個(gè)單獨(dú)的進(jìn)程監(jiān)控器來獲取內(nèi)存段的地址區(qū)域信息后, EoLeak方案記錄所有運(yùn)行時(shí)間接調(diào)用和跳轉(zhuǎn)目標(biāo), 檢查并過濾出屬于該內(nèi)存段的那些地址, 并執(zhí)行一個(gè)單獨(dú)的驗(yàn)證過程來比對(duì)確認(rèn)每個(gè)庫地址確實(shí)對(duì)應(yīng)于一個(gè)庫函數(shù)符號(hào).
如圖 4所示, 樣例程序的指針內(nèi)存畫像中包含了兩個(gè)指針的嵌套: 位于0x6020b0處的pS指針指向包含指針pM和pH的內(nèi)存區(qū)域0x602098, 而pM和pH這兩個(gè)指針又分別指向單獨(dú)的內(nèi)存區(qū)域. 當(dāng)pH指向的以0x175e010為起始地址的內(nèi)存區(qū)域中包含一個(gè)有價(jià)值的敏感數(shù)據(jù)時(shí), 便可以通過使用兩個(gè)連續(xù)的泄漏讀取來構(gòu)建對(duì)該重要數(shù)據(jù)的泄漏: 先讀取*pS+0x10處pH指針的值, 再讀取*pH+0x8處的敏感信息變量. 由于內(nèi)存中的偏移量是相對(duì)固定的, 只要知道第1個(gè)位于0x6020b0處的pS指針地址, 就可以沿著鏈條打印出整個(gè)鏈上的每一個(gè)節(jié)點(diǎn).
圖 4樣例漏洞程序部分運(yùn)行時(shí)指針內(nèi)存畫像
在收集到的內(nèi)存分析圖中, 我們將內(nèi)存描述為一系列由指針指向的嵌套內(nèi)存區(qū)域, 每個(gè)指針都位于特定內(nèi)存區(qū)域的某個(gè)偏移處. 給定一個(gè)用戶可以讀取的已知地址指針和一個(gè)漏洞時(shí)間范圍, EoLeak方案可以自動(dòng)搜索到指定目標(biāo)變量的指針泄漏鏈條, 從而通過連續(xù)任意讀功能應(yīng)用這條泄漏路徑.
2.2構(gòu)建信息泄漏
定位敏感信息的位置后, EoLeak方案構(gòu)建泄漏能力來打印出敏感信息. 正如在上一小節(jié)中所闡釋的, 對(duì)特定變量的泄漏可以被拆分為沒有沖突的連續(xù)任意讀取. 因此, 方案首先構(gòu)造單個(gè)任意讀取的泄漏功能, 然后將其拼接以形成任意讀取鏈條. 更具體地說, 方案分析目標(biāo)二進(jìn)制程序的語義, 結(jié)合堆漏洞構(gòu)建泄漏能力, 以目標(biāo)變量地址作為參數(shù)調(diào)用打印輸出庫函數(shù), 最后觸發(fā)函數(shù)調(diào)用完成泄漏過程.
2.2.1擴(kuò)展內(nèi)存操縱能力
開發(fā)者編寫的程序通常對(duì)用戶輸入的數(shù)據(jù)有嚴(yán)格的校驗(yàn), 避免其破壞內(nèi)存造成漏洞攻擊, 導(dǎo)致目標(biāo)二進(jìn)制程序本身往往沒有足夠的執(zhí)行語義來實(shí)現(xiàn)可控的庫函數(shù)調(diào)用. 因此, 必要的步驟是通過結(jié)合堆漏洞攻擊來提供更多的可利用原語以擴(kuò)展可用的內(nèi)存操縱范圍. 攻擊者可以手動(dòng)調(diào)整POC輸入來實(shí)現(xiàn)對(duì)堆漏洞的初始攻擊, EoLeak也提供了一套通過簡單的堆模型和漏洞利用模板來自動(dòng)推導(dǎo)和構(gòu)建這類堆利用攻擊的方案.
現(xiàn)有的堆漏洞攻擊基本上來源于成熟的堆漏洞利用技術(shù), 針對(duì)各堆管理器的攻擊方案也在發(fā)展中變得特化. glibc當(dāng)前采用的ptmalloc2為最常用的堆管理器之一, 通過arena結(jié)構(gòu)及其中的bin數(shù)組為堆上動(dòng)態(tài)分配的內(nèi)存提供高效的管理. 在ptmalloc2中, 每個(gè)malloc分配出來的內(nèi)存都有統(tǒng)一的chunk堆塊結(jié)構(gòu), 其中包含頭部數(shù)據(jù)用于管理堆結(jié)構(gòu), 存儲(chǔ)了前一堆塊的大小prev_size和該堆塊的大小size. 空閑的堆塊復(fù)用了主體部分的首段字節(jié)作為FD和BK指針(分別指向下一個(gè)和上一個(gè)空閑的堆塊). 每個(gè)分配出來的內(nèi)存堆塊依據(jù)其大小和使用狀態(tài)被歸為以下4類之一: (1) fast bin; (2) small bin; (3) large bin; (4) unsorted bin.
EoLeak針對(duì)ptmalloc2堆管理器抽象出了典型堆漏洞利用方案的模板, 包括觸發(fā)漏洞攻擊所需的條件和執(zhí)行攻擊后的利用效果. 具體來說, EoLeak提供了一個(gè)堆漏洞利用模板列表, 每個(gè)模板對(duì)應(yīng)一種堆利用攻擊方案, 包含了所需條件(如堆塊分配大小限制、堆塊頭部溢出可能性)和攻擊效果(如任意地址的堆分配).
表 1中列出了當(dāng)前支持的主要利用模板. 我們以樣例程序中執(zhí)行的safe unlink攻擊為例. 在未執(zhí)行safe unlink攻擊之前, 目標(biāo)二進(jìn)制程序內(nèi)存中沒有攻擊者可寫的指針, 無法實(shí)現(xiàn)進(jìn)一步的泄漏. safe unlink攻擊是一種釋放后使用攻擊, 它通過可控的FD和BK指針錯(cuò)誤地釋放一個(gè)已經(jīng)被釋放的small bin或unsorted bin.在堆利用模板中, EoLeak要求必須滿足以下條件才能實(shí)現(xiàn)攻擊.
表 1EoLeak當(dāng)前支持的堆漏洞利用模板列表
1、在已知地址處有一個(gè)指向某堆塊的指針;
2、該堆塊可布置為一個(gè)可以通過檢查的被釋放的堆塊, 其FD和BK對(duì)應(yīng)于偏移處都可具有的受控的內(nèi)容;
3、該堆塊的相鄰堆塊可以觸發(fā)釋放操作.
對(duì)于目標(biāo)二進(jìn)制程序而言, 條件(1)是靜態(tài)內(nèi)存狀態(tài), 可以通過內(nèi)存畫像的簡單檢查來獲得. 條件(2)要求該堆塊具有滿足約束條件的寫能力. 條件(3)則需要對(duì)相鄰的堆塊執(zhí)行釋放, 可以通過對(duì)程序執(zhí)行跡進(jìn)行分析而獲得.
該模板的攻擊效果則可被總結(jié)為: 已知指針被設(shè)置為指向略低于指針?biāo)诘刂诽?
在分析階段, EoLeak方案已經(jīng)記錄了指針及對(duì)應(yīng)的內(nèi)存區(qū)域. 通過分析包括堆塊頭部信息和雙向鏈表指針結(jié)構(gòu)的堆塊元數(shù)據(jù), EoLeak方案維護(hù)了一個(gè)表示運(yùn)行時(shí)堆布局結(jié)構(gòu)的簡易堆模型. 方案通過分析程序執(zhí)行跡來提取抽象的堆操作信息, 收集程序路徑中對(duì)堆狀態(tài)的修改語義, 并將這些修改與堆模型結(jié)合起來進(jìn)行比較, 以檢查其是否滿足任何堆漏洞攻擊模板的條件. 如果某個(gè)堆漏洞攻擊模板的所有條件都成立, 方案便會(huì)根據(jù)模板執(zhí)行堆攻擊, 驗(yàn)證這一攻擊的有效性, 并更新POC輸入和程序追蹤狀態(tài). 若后續(xù)的分析表明此攻擊無效, 則方案回退到攻擊之前, 并以此嘗試其他攻擊模板.
在執(zhí)行完P(guān)OC后, 樣例程序執(zhí)行到了如圖 2(f)所示的堆布局狀態(tài), 方案開始檢查其是否滿足safe unlink堆攻擊模板的條件. 對(duì)于條件(1), 方案在bss段找到了幾個(gè)固定地址的堆塊指針. 對(duì)于條件(2), 方案發(fā)現(xiàn)了程序路徑, 其中存在圖 4所示的pS指針, 指向的小堆塊中可以填充用戶偽造的假堆塊, 且其長度可以大于小堆塊容許的大小, 允許通過堆溢出覆蓋后續(xù)相鄰堆塊頭部的大小字段和存在標(biāo)識(shí)比特. 雖然小堆塊和大堆塊都可以填充用戶可控的內(nèi)容, 但只有pS滿足從指向內(nèi)存區(qū)域起始的可寫長度大于剩余塊大小的要求, 因此, prev_size字段和prev_in_use比特可以根據(jù)需要被覆蓋為指定內(nèi)容(標(biāo)明前一偽造塊為已釋放狀態(tài), 同時(shí)通過大小匹配檢查). 對(duì)于第3個(gè)條件, 另一條程序路徑滿足了觸發(fā)堆塊釋放的要求. 3個(gè)條件都得以滿足, 因此EoLeak方案根據(jù)模板構(gòu)造對(duì)應(yīng)的攻擊輸入, 依次執(zhí)行相應(yīng)的程序路徑, 成功更新了當(dāng)前程序狀態(tài).
2.2.2污點(diǎn)分析可控庫函數(shù)調(diào)用
收集更多內(nèi)存操縱原語后, EoLeak方案嘗試著構(gòu)造單個(gè)泄漏能力. 在獲得庫函數(shù)實(shí)際地址之前, 我們?nèi)匀灰揽磕繕?biāo)二進(jìn)制程序本身來完成泄漏過程. 因此, 需要找到目標(biāo)二進(jìn)制程序中已經(jīng)存在的輸出能力, 并以欲將泄漏的數(shù)據(jù)地址為參數(shù)進(jìn)行觸發(fā).
EoLeak方案首先在目標(biāo)二進(jìn)制程序中查找具有打印輸出語義的庫函數(shù), 這在構(gòu)建內(nèi)存畫像的過程中已經(jīng)收集獲得. 進(jìn)而, 方案分析程序執(zhí)行跡以確定是否存在合適的程序路徑來用可控的參數(shù)調(diào)用該輸出庫函數(shù), 這包括兩種可控參數(shù)情形: 參數(shù)直接來源于當(dāng)前POC輸入中的某些字節(jié), 或參數(shù)來源于當(dāng)前程序路徑中某些可控內(nèi)存區(qū)域的變量傳播. 前者可以通過修改當(dāng)前輸入進(jìn)行簡單的調(diào)整, 而后者則需要額外的寫入程序路徑來將所需的地址數(shù)據(jù)寫入相應(yīng)的內(nèi)存區(qū)域. 另一方面, 如果沒有合適的程序路徑來調(diào)用庫函數(shù), 則EoLeak方案必須首先通過劫持其他庫函數(shù)符號(hào)來構(gòu)造泄漏原語, 然后再以可控參數(shù)對(duì)該函數(shù)進(jìn)行調(diào)用. 總之, EoLeak方案需要了解用戶輸入可以影響哪些內(nèi)存區(qū)域, 也需要了解函數(shù)參數(shù)來源于哪些內(nèi)存區(qū)域.
為了跟蹤來自用戶輸入的數(shù)據(jù)流, 除了反匯編二進(jìn)制指令并獲取運(yùn)行時(shí)數(shù)據(jù)外, EoLeak方案還根據(jù)指令語義執(zhí)行一個(gè)輕量級(jí)的污點(diǎn)傳播分析來跟蹤用戶輸入. 用戶輸入庫函數(shù)的結(jié)果被標(biāo)記為污點(diǎn)源, 目標(biāo)庫函數(shù)調(diào)用參數(shù)被標(biāo)記為污點(diǎn)接受器. 由于動(dòng)態(tài)污點(diǎn)傳播是一個(gè)比較繁重的過程, 分析工作量大而無法保證精度, 為了降低性能開銷并專注于由用戶輸入字節(jié)直接控制的內(nèi)存區(qū)域, EoLeak方案僅以不超過一階的算術(shù)或位操作的內(nèi)存?zhèn)鬏敳僮髯鳛槲埸c(diǎn)傳播策略. 其背后的思路在于: 如果目標(biāo)地址完全被攻擊者所控制, 則構(gòu)成該地址的連續(xù)字節(jié)有很高的概率會(huì)作為一個(gè)整體在內(nèi)存中進(jìn)行傳輸或執(zhí)行偏移操作. 在這種情況下, 污點(diǎn)分析僅跟蹤原始用戶輸入, 降低了維護(hù)的開銷, 并且使后續(xù)漏洞利用生成分析更加簡潔.
2.2.3構(gòu)建泄漏語義
EoLeak方案對(duì)上述內(nèi)容的分析結(jié)果存在多種可能性, 包括可能存在多個(gè)讀取語義的程序路徑可以實(shí)現(xiàn)泄漏能力, 打印庫函數(shù)的參數(shù)可能來源于多個(gè)可控內(nèi)存區(qū)域, 而每個(gè)內(nèi)存區(qū)域也可以支持多種寫入方式.
方案在這些候選組成部分中進(jìn)行選取, 拼接出一個(gè)完整的泄漏原語. 由于通過指針鏈條的連續(xù)任意讀取泄漏能力要求每個(gè)任意讀取泄漏之間不能發(fā)生沖突, 方案在拼接泄漏路徑后對(duì)其執(zhí)行跡進(jìn)行分析, 計(jì)算其帶來的副作用, 包括其他內(nèi)存位置的寫入、對(duì)堆布局的額外操作等, 對(duì)每個(gè)生成的庫函數(shù)調(diào)用給予一個(gè)副作用評(píng)分, 用以衡量副作用的影響, 優(yōu)先選擇副作用較小的泄漏路徑. 具體而言, 方案提取每個(gè)執(zhí)行跡中的內(nèi)存讀寫和分配釋放操作, 并分成兩部分進(jìn)行處理. 對(duì)于執(zhí)行跡中的內(nèi)存讀寫, 方案對(duì)每個(gè)不同地址的內(nèi)存寫入計(jì)3分, 并對(duì)每一組逆序的執(zhí)行跡中內(nèi)存讀寫(即存在某個(gè)地址執(zhí)行跡先讀后寫)計(jì)1分. 對(duì)于執(zhí)行跡中的內(nèi)存分配和釋放操作, 方案對(duì)每個(gè)內(nèi)存分配和釋放計(jì)1分, 并對(duì)每一組不匹配的分配和釋放(匹配即一對(duì)分配釋放操作目標(biāo)地址相同)計(jì)1分. 在選擇泄漏路徑時(shí), 方案按內(nèi)存分配釋放分?jǐn)?shù)和內(nèi)存讀寫分?jǐn)?shù)依次優(yōu)先選擇分?jǐn)?shù)較小的泄漏路徑.
目標(biāo)程序的內(nèi)存畫像中記錄了所有與隨機(jī)化后庫函數(shù)地址相關(guān)的指針位置, EoLeak方案自動(dòng)地為每個(gè)庫函數(shù)指針計(jì)算可能的泄漏鏈條, 嘗試對(duì)任一指針進(jìn)行泄漏, 以獲得在地址空間布局隨機(jī)化后的運(yùn)行時(shí)庫函數(shù)地址. 分析人員也可以在內(nèi)存畫像圖中手動(dòng)標(biāo)記目標(biāo)敏感信息, EoLeak方案可以嘗試為該變量構(gòu)建相應(yīng)的泄漏路徑.
2.3生成利用樣本
在完成信息泄漏之后, 我們嘗試?yán)眯孤┏鰜淼膌ibc庫函數(shù)地址和此前通過模板擴(kuò)展出的可控內(nèi)存范圍來實(shí)現(xiàn)目標(biāo)二進(jìn)制程序的利用, 通過使用和構(gòu)建泄漏語義相似的策略來構(gòu)建利用語義中的庫函數(shù)調(diào)用, 例如system(“/bin/sh”), 在下文中將以此作為示例. 也有其他可用的庫函數(shù), 如execve, 只需要不同的參數(shù)組合. 自動(dòng)構(gòu)建利用樣本過程同樣可以分為兩個(gè)步驟: 使一個(gè)可被調(diào)用的代碼指針具有隨機(jī)化后的運(yùn)行時(shí)system函數(shù)地址, 并確保第1個(gè)或相應(yīng)的參數(shù)被填充為“/bin/sh”的地址.
由于在不同的隨機(jī)化基地址中, 相同庫中的兩個(gè)符號(hào)之間總具有相同的偏移量, 所以,system函數(shù)的運(yùn)行時(shí)地址可以通過泄漏出的libc庫函數(shù)地址進(jìn)行計(jì)算. 被調(diào)用的代碼指針可以選取典型代表, 如全局偏移表, 其保存程序中使用的真實(shí)庫函數(shù)地址. libc庫中包含“/bin/sh”這一字符串, 其地址亦可通過泄漏的地址進(jìn)行計(jì)算. 在某些情形下,system庫函數(shù)調(diào)用的第1個(gè)參數(shù)無法由用戶輸入值直接控制, EoLeak方案則尋求替代選項(xiàng): 將參數(shù)設(shè)置為指向具有可寫內(nèi)存區(qū)域的指針, 通過在原始POC中附加或修改字節(jié)來觸發(fā)寫入過程, 將“/bin/sh”字符串本身寫入目標(biāo)內(nèi)存區(qū)域而非其運(yùn)行時(shí)所在地址. 當(dāng)system函數(shù)地址和參數(shù)都準(zhǔn)備好后, 便可通過篡改libc庫函數(shù)符號(hào)來觸發(fā)對(duì)system函數(shù)的庫函數(shù)調(diào)用, 實(shí)現(xiàn)對(duì)目標(biāo)二進(jìn)制文件的利用.
EoLeak方案基于泄漏函數(shù)地址的方案來繞過地址空間布局隨機(jī)化防護(hù). 在泄漏和生成利用樣本階段, 無需注入shellcode, 而是基于最初堆漏洞利用模板對(duì)可用內(nèi)存范圍的擴(kuò)展, 通過對(duì)可控庫函數(shù)調(diào)用目標(biāo)地址和參數(shù)進(jìn)行分析劫持庫函數(shù)調(diào)用, 通過復(fù)用代碼以實(shí)現(xiàn)攻擊, 可以對(duì)抗數(shù)據(jù)執(zhí)行保護(hù). 在堆漏洞利用的過程中, 一般不依賴于棧溢出功能, 且可以通過內(nèi)存畫像指定棧保護(hù)變量來構(gòu)造對(duì)應(yīng)的泄漏路徑, 因此可以對(duì)抗棧保護(hù)變量的防護(hù).
3 實(shí)現(xiàn)方案
本文基于PANDA項(xiàng)目實(shí)現(xiàn)了EoLeak系統(tǒng). 具體來說, 我們用C++實(shí)現(xiàn)了部分分析代碼, 并將整個(gè)系統(tǒng)包裝為一個(gè)基于Python的服務(wù)器/客戶端架構(gòu).
3.1記錄和重放
針對(duì)隨機(jī)化保護(hù)的分析, 一直是一項(xiàng)艱巨的工作. 隨機(jī)化值僅在實(shí)際執(zhí)行過程中生成, 在此之前無法觀察到相關(guān)的隨機(jī)化程序行為. 動(dòng)態(tài)分析解決了這個(gè)問題, 但每次執(zhí)行時(shí)產(chǎn)生的隨機(jī)結(jié)果有所不同, 從而給研究人員帶來了新的困難.
EoLeak系統(tǒng)借助了記錄程序執(zhí)行跡并以確定方式進(jìn)行重放的技術(shù). 在記錄階段, 所有運(yùn)行時(shí)的環(huán)境變量照常生成并被記錄在日志文件中. 當(dāng)重放執(zhí)行跡時(shí), 每條指令都具有與最初記錄時(shí)完全相同的執(zhí)行行為. 一致的運(yùn)行環(huán)境有助于研究人員輕松地比較和分析多次重放之間同一程序執(zhí)行跡的執(zhí)行過程, 并準(zhǔn)確識(shí)別隨機(jī)化后的庫函數(shù)地址和相應(yīng)的內(nèi)存結(jié)構(gòu).
3.2PANDA插件
PANDA基于QEMU模擬器, 在TCG生命周期中有多個(gè)回調(diào)函數(shù)點(diǎn), 如PANDA_CB_INSN_TRANSLATE在基本塊首次轉(zhuǎn)換為TCG IR之前被調(diào)用, 而PANDA_CB_AFTER_INSN_EXEC在一條指令執(zhí)行后被觸發(fā). 通過這些回調(diào)函數(shù)有選擇地插入分析邏輯代碼, EoLeak系統(tǒng)能夠記錄和分析特定用戶輸入的目標(biāo)二進(jìn)制程序的執(zhí)行過程. 例如: 在Capstone反匯編工具的幫助下, 將指令在執(zhí)行前進(jìn)行反匯編, 并在全局指針映射結(jié)構(gòu)中記錄識(shí)別到的指針. 污點(diǎn)和傳播分析在這里進(jìn)行.
3.3服務(wù)器/客戶端架構(gòu)
PANDA是一個(gè)構(gòu)建在QEMU之上的分析平臺(tái), 其在啟動(dòng)目標(biāo)操作系統(tǒng)鏡像實(shí)例的新虛擬機(jī)時(shí)面臨嚴(yán)重的性能問題和時(shí)間開銷. EoLeak系統(tǒng)需要?jiǎng)討B(tài)決定目標(biāo)二進(jìn)制程序的下一個(gè)用戶輸入, 無法承擔(dān)頻繁的啟動(dòng)和關(guān)閉虛擬機(jī)的時(shí)間成本. 為此, 我們將EoLeak設(shè)計(jì)為服務(wù)器/客戶端架構(gòu), 客戶端是一個(gè)Python控制器, 用戶控制PANDA虛擬機(jī)并接受來自服務(wù)器的命令. 其包裝了常見的PANDA操作, 例如記錄給定目標(biāo)二進(jìn)制程序和對(duì)應(yīng)輸入的新程序執(zhí)行過程記錄、重放程序執(zhí)行跡并運(yùn)行分析插件進(jìn)行分析以及將服務(wù)器傳來的ISO文件注入/彈出虛擬機(jī)等. 當(dāng)分析操作完成后, 客戶端將分析結(jié)果發(fā)送回服務(wù)器. 為了降低虛擬機(jī)啟動(dòng)的時(shí)間開銷, 客戶端在后臺(tái)保留一個(gè)運(yùn)行中的客戶操作系統(tǒng)實(shí)例來接受和執(zhí)行來自服務(wù)器的命令, 并根據(jù)需要自動(dòng)重啟虛擬機(jī).
EoLeak系統(tǒng)的服務(wù)器則是另一個(gè)Python項(xiàng)目, 也是系統(tǒng)的核心分析器. 它向客戶端發(fā)送PANDA操作和分析指令, 從客戶端接收分析結(jié)果, 并驅(qū)動(dòng)自動(dòng)構(gòu)建泄漏和生成漏洞利用樣本過程. 當(dāng)生成新的程序輸入時(shí), 服務(wù)器將輸入和二進(jìn)制文件一起發(fā)送給客戶端, 以進(jìn)行另一次執(zhí)行跟蹤分析. 通過將漏洞利用分析模塊和PANDA執(zhí)行模塊拆分為服務(wù)器和客戶端架構(gòu), EoLeak系統(tǒng)可以通過連接一個(gè)服務(wù)器和多個(gè)執(zhí)行器客戶端來并行加速.
4 評(píng)估驗(yàn)證
本節(jié)介紹針對(duì)EoLeak系統(tǒng)的實(shí)驗(yàn)評(píng)估和驗(yàn)證, 主要回答了如下幾個(gè)研究問題.
1、研究問題1: EoLeak系統(tǒng)能否成功定位敏感信息?
2、研究問題2: EoLeak系統(tǒng)采用的堆攻擊模板是否有效?
3、研究問題3: EoLeak系統(tǒng)能否為堆漏洞程序生成自動(dòng)泄漏敏感信息以及能否自動(dòng)實(shí)現(xiàn)利用的樣本?
4.1敏感信息定位
如表 2所示, 我們從著名的CTF賽事和網(wǎng)站中收集了17個(gè)堆漏洞程序. 所有案例提供的POC都不可利用. 系統(tǒng)的libc版本為2.23, 啟用的防御類型在表中以SNP表示(S表示棧保護(hù)變量, N表示數(shù)據(jù)執(zhí)行保護(hù), P表示PIE, 字母存在表示目標(biāo)程序部署了對(duì)應(yīng)防御, ?表示3種防御均不存在), 系統(tǒng)采用全隨機(jī)模式地址空間隨機(jī)化保護(hù).
表 2EoLeak測試的CTF堆漏洞二進(jìn)制程序
為了回答研究問題1, 我們收集了EoLeak在動(dòng)態(tài)分析過程中記錄的libc庫函數(shù)地址指針作為敏感信息的代表. 如表 3所示, EoLeak在所有CTF二進(jìn)制文件中都成功定位到了可供泄漏的libc庫函數(shù)地址. 左列的libc地址識(shí)別數(shù)代表原始POC下識(shí)別到的存儲(chǔ)隨機(jī)化后libc庫函數(shù)相關(guān)地址值的內(nèi)存位置數(shù)量, 由動(dòng)態(tài)分析模塊給出. 右列的攻擊后libc地址識(shí)別數(shù)則代表在實(shí)現(xiàn)了初步堆攻擊后識(shí)別到的對(duì)應(yīng)內(nèi)存位置數(shù)量, 體現(xiàn)了堆攻擊對(duì)內(nèi)存操縱能力的提升. libc庫相關(guān)指的是與libc庫基址有固定偏移量的地址, 其不僅包括libc函數(shù)符號(hào), 也包括了libc數(shù)據(jù)段內(nèi)部的某些內(nèi)存結(jié)構(gòu)字段, 這些字段也可以起到泄漏libc運(yùn)行時(shí)地址的作用.
表 3EoLeak當(dāng)前支持的堆漏洞利用模板列表
我們還評(píng)估了5個(gè)真實(shí)世界程序的敏感信息定位能力. 從表 4的結(jié)果可以看出, EoLeak成功地在所有應(yīng)用程序中定位到了libc地址. 值得注意的是: 原始POC下識(shí)別到的libc庫相關(guān)地址數(shù)量與目標(biāo)二進(jìn)制文件的大小沒有明顯關(guān)系, 但與目標(biāo)二進(jìn)制文件中引用的libc符號(hào)數(shù)量大致相同. 這表明, 幾乎所有可能的用于繞過地址空間布局隨機(jī)化的libc相關(guān)地址都僅來自于全局偏移表. 另一方面, 通過初步堆攻擊所擴(kuò)展得到的libc相關(guān)地址不受此限制, 是穩(wěn)定的泄漏來源選項(xiàng).
表 4真實(shí)軟件中對(duì)libc庫相關(guān)地址的識(shí)別
4.2堆攻擊模板
為了回答研究問題2, 我們?cè)?7個(gè)CTF堆漏洞程序上驗(yàn)證EoLeak方案所采用的攻擊模板列表的有效性.結(jié)果見表 5. 17個(gè)程序中, 有5個(gè)程序可以成功匹配Fastbin攻擊模板; 有8個(gè)程序可以匹配Unlink攻擊模板; 有2個(gè)程序可以通過偽造數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)內(nèi)存寫; 還有2個(gè)程序無法匹配到對(duì)應(yīng)的攻擊模板. 即, 有88.2%的目標(biāo)程序可以由EoLeak自動(dòng)探索從堆布局不過分復(fù)雜的漏洞觸發(fā)點(diǎn)到遵循模板的堆漏洞初步攻擊.表 3中, 初步攻擊后新增識(shí)別到的libc庫相關(guān)地址體現(xiàn)了這一初步攻擊所帶來的內(nèi)存可利用性的提升. 我們也調(diào)研了2個(gè)無法成功匹配初步攻擊模板的程序案例以及在真實(shí)軟件中的情形, 具體緣由在下一小節(jié)中加以分析.
表 5CTF堆漏洞二進(jìn)制程序適用的堆攻擊模板
4.3泄漏和漏洞利用生成
為了回答研究問題3, 我們使用17個(gè)CTF堆漏洞程序來評(píng)估EoLeak系統(tǒng), 嘗試生成泄漏和漏洞利用樣本. 對(duì)于每個(gè)堆漏洞程序, 會(huì)準(zhǔn)備一個(gè)能夠觸發(fā)堆漏洞但未能利用的POC.
如表 6所示: EoLeak系統(tǒng)為17個(gè)堆漏洞程序中的15個(gè)成功構(gòu)建了泄漏, 其中14個(gè)生成了最終利用樣本.也就是說, EoLeak系統(tǒng)在構(gòu)建libc庫函數(shù)地址泄漏方面成功率達(dá)到了88.2%, 而82.4%的目標(biāo)程序得到了利用.
表 6CTF堆漏洞二進(jìn)制程序的信息泄漏構(gòu)建和利用樣本生成效果
我們進(jìn)一步調(diào)查了無法構(gòu)建泄漏的3個(gè)案例和未能生成漏洞利用的1個(gè)案例, 分析了失敗的原因.
1、多線程. vote程序是一個(gè)多線程程序, 對(duì)于當(dāng)前的分析模塊來說過于復(fù)雜. 目前, EoLeak僅支持對(duì)單線程的漏洞程序進(jìn)行分析. 出于同樣的原因, EoLeak暫時(shí)無法理解條件競爭類漏洞;
2、自定義堆結(jié)構(gòu). minesweeper程序?qū)崿F(xiàn)了自定義的堆結(jié)構(gòu)和管理器. EoLeak的堆模型推斷依賴于標(biāo)準(zhǔn)的ptmalloc2實(shí)現(xiàn), 因此目前無法處理自定義堆, 也無法為程序順利生成泄漏或最終漏洞利用;
3、尚未支持的堆利用技術(shù). mario程序需要利用_IO_file結(jié)構(gòu)來實(shí)現(xiàn)堆利用攻擊, 當(dāng)前堆模型推斷機(jī)制尚未能支持該類利用技巧. 因此, 雖然可以正常使用FD指針構(gòu)造泄漏, 但在生成漏洞利用樣本時(shí)仍是失敗的;
4、利用窗口. 實(shí)際中, 軟件路徑復(fù)雜, 大多漏洞僅允許有限的攻擊窗口, 通常僅有1次寫入的能力, 很難復(fù)用. 即使部分漏洞符合利用模板條件, 后續(xù)亦因復(fù)雜的堆布局變化而難以構(gòu)造無沖突的連續(xù)讀取鏈條, 因而難以自動(dòng)實(shí)現(xiàn)泄漏.
5 相關(guān)工作
5.1自動(dòng)生成漏洞利用樣本
早期的自動(dòng)生成漏洞利用樣本解決方案沒有考慮防御機(jī)制. APEG[22]是第一個(gè)AEG解決方案, 它將補(bǔ)丁前后出現(xiàn)差異的條件檢查與目標(biāo)二進(jìn)制文件進(jìn)行比較, 使用符號(hào)執(zhí)行來自動(dòng)構(gòu)建在補(bǔ)丁之前未能通過條件檢查的輸入. AEG[4]基于棧上的控制流劫持對(duì)源代碼進(jìn)行符號(hào)執(zhí)行, 以利用棧溢出和格式化字符串漏洞. Mayhem[5]設(shè)法為二進(jìn)制文件中的棧溢出和格式化字符串漏洞生成漏洞利用, 通過控制流劫持符號(hào)執(zhí)行實(shí)現(xiàn)執(zhí)行ret2stack-shellcode和ret2libc攻擊. PolyAEG[23]通過污點(diǎn)分析用戶可控的控制流方向, 為具有一個(gè)異常輸入的二進(jìn)制文件生成多種漏洞利用. 這些AEG解決方案都無法繞過數(shù)據(jù)執(zhí)行保護(hù)或地址空間布局隨機(jī)化.
一些研究工作設(shè)法突破防御機(jī)制, 但仍無法自動(dòng)繞過地址空間布局隨機(jī)化. HI-CFG[8]將良性輸入轉(zhuǎn)換為緩沖區(qū)之間的漏洞點(diǎn), 生成帶有緩沖區(qū)信息的控制流圖(control flow graph), 并通過讀寫操作搜索緩沖區(qū)傳輸.該工作的核心目標(biāo)是生成可以造成異常狀態(tài)的POC樣本, 如果想繞過地址空間布局隨機(jī)化防御的利用樣本, 則需要人工引導(dǎo)的介入. Revery[12]、KOOBE[13]和FUZE[14]研究如何使用模糊測試技術(shù)生成針對(duì)堆漏洞的攻擊. Revery在用戶態(tài)程序中搜索與崩潰執(zhí)行路徑相似的內(nèi)存布局, 嘗試縫合替換程序路徑. KOOBE專注于Linux內(nèi)核中的越界寫入漏洞. 另一方面, FUZE分析用于創(chuàng)建和取消引用懸空指針的時(shí)間戳. 這些解決方案將繞過地址空間布局隨機(jī)化, 被視為超出研究范圍的內(nèi)容, 因而未予考慮.
一些研究工作試圖繞過地址空間布局隨機(jī)化, 但只能通過對(duì)棧漏洞的利用實(shí)現(xiàn)繞過, 而無法在堆漏洞上成功繞過. Heelan[3]提出了一種使用符號(hào)執(zhí)行來生成已知棧溢出漏洞的解決方案, 通過跳轉(zhuǎn)寄存器引導(dǎo)向未隨機(jī)地址來繞過地址空間布局隨機(jī)化. Q[6]使用少量非隨機(jī)代碼強(qiáng)化現(xiàn)有漏洞利用, 以繞過地址空間布局隨機(jī)化. 它通過二進(jìn)制分析平臺(tái)BAP[29]構(gòu)建面向返回編程(return-oriented programming)的配件, 并匹配所提出的QooL語言以進(jìn)行棧利用. CRAX[7]通過對(duì)用戶控制的程序計(jì)數(shù)器進(jìn)行污染, 為大型真實(shí)世界的二進(jìn)制文件生成漏洞利用. 盡管它可以使用ret2libc和jmp2reg技術(shù)繞過棧上的地址空間布局隨機(jī)化, 但它無法實(shí)現(xiàn)堆漏洞上的繞過. ShellSwap[24]通過使用符號(hào)跟蹤以及漏洞利用代碼布局修復(fù)和路徑拼接的組合, 將現(xiàn)有的舊漏洞利用移植到一個(gè)有效的新漏洞利用中. 其通過一個(gè)具有可控寄存器的特定jmp指令覆蓋指令指針來繞過地址空間布局隨機(jī)化, 因而無法同時(shí)繞過數(shù)據(jù)執(zhí)行保護(hù). R2dlAEG[26]利用符號(hào)執(zhí)行探索利用return2dl-resolve攻擊技術(shù)來為棧溢出漏洞生成繞過數(shù)據(jù)執(zhí)行和地址空間布局隨機(jī)化的利用樣本. KEPLER[25]通過發(fā)現(xiàn)多個(gè)漏洞利用鏈來生成繞過現(xiàn)代緩解技術(shù)的面向返回編程的漏洞利用. 它需要劫持控制流并利用控制流劫持原語(control- flow hijacking primitive)來構(gòu)建漏洞利用的POC.
數(shù)據(jù)流分析自然可以對(duì)抗地址空間布局隨機(jī)化保護(hù). FLOWSTITCH[30]自動(dòng)生成面向數(shù)據(jù)的漏洞利用, 在不違反控制流完整性的情況下, 拼接信息泄漏或特權(quán)升級(jí). DOP[31]更進(jìn)一步, 通過構(gòu)建數(shù)據(jù)流配件來執(zhí)行面向數(shù)據(jù)的編程, 但是它們沒有在堆漏洞上繞過地址空間布局隨機(jī)化. BOPC[32]假設(shè)所有控制流緩解都已啟用.它在給定的入口點(diǎn)上搜索內(nèi)存布局, 通過多個(gè)任意內(nèi)存寫入原語來設(shè)置內(nèi)存布局(如果繞過地址空間布局隨機(jī)化, 則亦需要讀取原語), 使得后續(xù)數(shù)據(jù)流滿足所需的SPL邏輯.
解釋器上的AEG研究工作也受到了一些關(guān)注. SHRIKE[9]對(duì)PHP進(jìn)行回歸測試以提取堆操作. 此外, 它會(huì)搜索溢出塊與目標(biāo)塊相鄰的特定內(nèi)存布局. Gollum[10]自動(dòng)解決了尋找數(shù)據(jù)結(jié)構(gòu)溢出并以某種特定方式使用的問題. 它首先檢查可利用的堆布局, 然后以惰性方法搜索相應(yīng)的堆操作過程. 由于需要確定的堆分配地址, 它不能繞過地址空間布局隨機(jī)化.
5.2污點(diǎn)分析
污點(diǎn)分析技術(shù)是用于分析程序數(shù)據(jù)流的一種重要方法, 可以直接判斷輸入源和目標(biāo)點(diǎn)之間是否存在關(guān)聯(lián)性, EoLeak執(zhí)行輕量級(jí)動(dòng)態(tài)污點(diǎn)分析來研究用戶輸入與庫函數(shù)調(diào)用參數(shù)之間的關(guān)系. 靜態(tài)污點(diǎn)分析很難保證結(jié)果的正確性, 現(xiàn)行的污點(diǎn)分析系統(tǒng)往往采用動(dòng)態(tài)分析的方法, 并與動(dòng)態(tài)符號(hào)執(zhí)行和模糊測試等方法相結(jié)合.
Dytan[33]給出了一個(gè)通用的污點(diǎn)分析框架, 并采用動(dòng)態(tài)插樁的方法進(jìn)行污點(diǎn)分析, 但它在污點(diǎn)標(biāo)記和插樁效率上存在很大的局限性. Libdft[34]使用影子內(nèi)存(shadow memory)方法, 提高了動(dòng)態(tài)數(shù)據(jù)流追蹤的效率, 加強(qiáng)了動(dòng)態(tài)污點(diǎn)分析技術(shù)的實(shí)用性. 現(xiàn)行的動(dòng)態(tài)污點(diǎn)分析方法都不可避免地存在過污染(over-taint, 污點(diǎn)標(biāo)記過多, 污點(diǎn)變量大量擴(kuò)散)或欠污染(under-taint, 污點(diǎn)傳播分析不當(dāng), 本應(yīng)被標(biāo)記的變量沒有被標(biāo)記)的問題[35]. 并且, 由于污點(diǎn)分析需要對(duì)每一條指令指定污點(diǎn)傳播規(guī)則, 它們對(duì)目標(biāo)程序的運(yùn)行平臺(tái)有著很強(qiáng)的依賴, 遷移到不同的平臺(tái)需要付出很大的工程代價(jià). 迄今為止, 沒有一個(gè)動(dòng)態(tài)污點(diǎn)分析系統(tǒng)可以同時(shí)在x86和x86-64平臺(tái)上分別對(duì)32位和64位程序進(jìn)行分析. 為了緩解過污染和欠污染問題, 從而加強(qiáng)動(dòng)態(tài)污點(diǎn)分析的可靠性和完備性, TaintInduce[36]可以只利用對(duì)應(yīng)架構(gòu)最少的語義信息來自動(dòng)分析得到傳播規(guī)則, 具有較好的跨平臺(tái)遷移能力. 另外, 還有一些結(jié)合二進(jìn)制分析的動(dòng)態(tài)污點(diǎn)分析工具, 比如TEMU[37]和Triton[38].
傳統(tǒng)的污點(diǎn)分析方法工程量大, 運(yùn)行效率低, 因此一些前沿的研究嘗試使用機(jī)器學(xué)習(xí)的手段, 用神經(jīng)網(wǎng)絡(luò)模擬指令的輸入和輸出, 嘗試為指令自動(dòng)建立傳播規(guī)則, 從而達(dá)到降低工程量和跨平臺(tái)的目的. 如Neutaint[39]利用神經(jīng)網(wǎng)絡(luò)來直接估計(jì)輸入源和目標(biāo)點(diǎn)之間的關(guān)聯(lián)性.
6 總結(jié)
對(duì)于自動(dòng)生成漏洞利用樣本解決方案來說, 將部署在目標(biāo)系統(tǒng)中的緩解策略涵蓋進(jìn)考慮范圍是一個(gè)現(xiàn)實(shí)的挑戰(zhàn). 我們提出了一種有效的自動(dòng)解決方案EoLeak, 用于通過堆漏洞同時(shí)繞過地址空間布局隨機(jī)化和數(shù)據(jù)執(zhí)行保護(hù). 通過使用漏洞觸發(fā)樣本對(duì)程序執(zhí)行跡進(jìn)行動(dòng)態(tài)分析, EoLeak方案利用對(duì)內(nèi)存?zhèn)鬏數(shù)妮p量級(jí)污點(diǎn)分析和簡單的堆利用模型來推斷可能的庫函數(shù)指針和漏洞利用目標(biāo). 我們?cè)?7個(gè)奪旗賽堆漏洞二進(jìn)制程序上測試了EoLeak, 其中15個(gè)可以自動(dòng)構(gòu)建泄漏, 14個(gè)可以生成最終利用樣本. EoLeak還可以成功分析真實(shí)世界程序中的敏感信息和內(nèi)存可控性.
審核編輯:湯梓紅
-
信息
+關(guān)注
關(guān)注
0文章
407瀏覽量
35566 -
PoC
+關(guān)注
關(guān)注
1文章
70瀏覽量
20550 -
AEG
+關(guān)注
關(guān)注
0文章
4瀏覽量
1902
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論