999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于懸空指針追蹤的UAF 漏洞檢測方法研究

2024-08-23 00:00:00許敏胡勇李新建

摘要: 隨著UAF 漏洞的關(guān)注度上升,其利用方式更加多樣,對計算機系統(tǒng)造成的威脅愈發(fā)嚴(yán)重. 因此,本文提出一個輕量級的UAF 漏洞檢測方案. 該方案在LLVM IR 的基礎(chǔ)上收集被測試程序中所有可能的懸空指針;然后,對它們進行精準(zhǔn)的數(shù)據(jù)流分析和控制流分析后,可以排除再次定義的指針,得到所有懸空指針;最后,對懸空指針進行可達性分析和數(shù)據(jù)流分析即可得到UAF 漏洞的操作序列. 該方案還通過2 種方式減少系統(tǒng)開銷:將過程間分析簡化為過程內(nèi)分析和結(jié)合數(shù)據(jù)流分析的別名分析算法. 在開源的測試用例和真實程序上測試的實驗結(jié)果表明,該方案可以快速、準(zhǔn)確地識別出代碼中的UAF 漏洞,并報告危險的操作序列.

關(guān)鍵詞: 懸空指針; LLVM; UAF; 漏洞檢測

中圖分類號: TP391. 1 文獻標(biāo)志碼: A DOI: 10. 19907/j. 0490-6756. 2024. 043001

1 引言

根據(jù)NIST 的統(tǒng)計數(shù)據(jù)[1]顯示,2021 年公布的新增漏洞數(shù)量再創(chuàng)新高,達到20 158 個. 如圖1 所示,釋放后重用(Use-After-Free,UAF)漏洞自2015 年開始逐漸增多. 這主要是由于開發(fā)人員的安全意識提高和眾多堆棧保護機制的廣泛應(yīng)用,使得溢出漏洞發(fā)現(xiàn)和利用的難度加大,研究人員逐漸轉(zhuǎn)向發(fā)現(xiàn)和利用堆運行機制漏洞. Yan 等[2]的研究表明,NVD 數(shù)據(jù)庫中有80. 14% 的UAF 漏洞被評為高?;驀?yán)重等級. 相比之下,大約只有50%的堆緩沖區(qū)溢出漏洞被視為高危等級的漏洞[3].UAF 漏洞作為堆內(nèi)存分配機制的基本漏洞,可以通過它對計算機系統(tǒng)進行更復(fù)雜且危害性更大的攻擊. 如HeapFengShui[4]等,可能導(dǎo)致拒絕服務(wù),信息泄漏,甚至是任意代碼執(zhí)行攻擊.

UAF 漏洞由2 個條件組成:(1) 產(chǎn)生懸空指針;(2) 使用懸空指針. 其中懸空指針是指指向的內(nèi)存對象被釋放后沒有被正確處理的指針. 因此若要檢測UAF 漏洞或緩解UAF 漏洞帶來的危害,檢測懸空指針就顯得尤為重要.

目前針對懸空指針的檢測也有一些成熟的技術(shù). DangSan[5]以LLVM[6]編譯框架插件的形式工作,通過指針追蹤器和內(nèi)存對象追蹤器分別追蹤內(nèi)存對象指針和內(nèi)存對象,并使用映射器將其關(guān)聯(lián). 最后在內(nèi)存對象被釋放時得到相應(yīng)的懸空指針,并使其失效,從而達到防止UAF 漏洞的目的.不過由于指針追蹤的復(fù)雜性導(dǎo)致存在誤報,并且指針追蹤器追蹤所有指針導(dǎo)致開銷較大. 為了解決開銷問題,HeapExpo[7]在DangSan 的基礎(chǔ)上進行改進,對每個函數(shù)的局部指針和指針參數(shù)進行活躍分析,配合LLVM 的mem2reg 優(yōu)化,從而減少需要跟蹤的指針變量數(shù)量,減小了系統(tǒng)開銷. DangNULL[8]和FreeSentry[9]也是追蹤指針傳播,并記錄指針與對象之間的關(guān)系. 不過二者用于記錄的數(shù)據(jù)結(jié)構(gòu)不同,前者采用紅黑樹進行元數(shù)據(jù)存儲,其中每個節(jié)點對應(yīng)1 個內(nèi)存對象和所有指向該內(nèi)存對象的指針,而后者使用2 個查找表作為其元數(shù)據(jù)存儲:一個表記錄從指針到其引用的內(nèi)存對象的所有映射,另一個表記錄從內(nèi)存對象到引用它的指針的所有映射. 在跟蹤指針傳播方面,Dang?Null 只跟蹤數(shù)據(jù)段和堆中的指針,不跟蹤堆?;蚣拇嫫髦械闹羔? 而FreeSentry 跟蹤堆棧上的指針,但不跟蹤寄存器中的指針. 因此,這會導(dǎo)致UAF漏洞漏報.

此外,也有一些專門針對UAF 漏洞的自動檢測技術(shù),根據(jù)是否需要運行程序分為2 類:靜態(tài)檢測和動態(tài)檢測. 靜態(tài)檢測,如CBMC[10]、Coccinelle[11]、Clang 靜態(tài)分析器[12]和TscanCode[13]等,通過在不執(zhí)行程序的情況下分析源代碼或機器代碼來發(fā)現(xiàn)程序中潛在的UAF 漏洞;而動態(tài)檢測,如Valgrind[14]和Dr. Memory[15]等,在程序執(zhí)行期間報告潛在的UAF 漏洞.

在眾多靜態(tài)檢測技術(shù)中,UAFChecker[16]通過構(gòu)建有限狀態(tài)機來檢測程序中的所有指針或其別名在釋放其內(nèi)存對象后是否再次被使用,作為可能的UAF 漏洞. 然后使用符號執(zhí)行檢查可能的UAF 漏洞的路徑約束的可滿足性來減少誤報率.但是由于約束求解的局限性以及使用函數(shù)內(nèi)聯(lián)技術(shù)和函數(shù)摘要技術(shù)進行過程間分析帶來的巨大開銷,導(dǎo)致它僅適用于較小的程序. CRed[2]首先對C程序進行基于需求驅(qū)動的指針分析獲取可能的UAF 漏洞,然后通過函數(shù)調(diào)用上下文敏感縮減技術(shù)和路徑敏感縮減技術(shù)逐步減少誤報率. 為了減少分析時間,CRed 通過設(shè)置函數(shù)調(diào)用上下文的深度來減少需要分析的程序路徑的數(shù)量. 因此CRed會遺漏一些UAF 漏洞. 此外,由于CRed 對數(shù)組訪問別名的建模不完善,并且缺乏對鏈接列表的處理,即使沒有減少函數(shù)調(diào)用上下文深度,它也可能會遺漏真正的UAF 漏洞.

與上述對指針進行詳細分析不同,CBMC 是將模型檢查[17]與可滿足性求解相結(jié)合的有界模型檢查工具. CBMC 首先將每個循環(huán)展開到固定邊界,然后再將程序轉(zhuǎn)換為使用UAF 斷言注釋的程序. 然后,它將所有可能的程序路徑視為約束,并使用SMT 求解器對其進行求解,以確定程序是否包含UAF 約束違規(guī). 盡管精度很高,但由于約束求解的局限性,CBMC 只能擴展到小型程序.

Coccinelle 和TscanCode 都是采用給定的模式來分析和驗證C 程序中的漏洞. 因此二者具有很高的擴展性,但給定模式也降低了漏洞檢測的精度. 此外,由于指針分析不佳和模式匹配的性質(zhì),前者容易產(chǎn)生大量誤報;后者由于缺乏指針分析,所以在真實程序中難以檢測UAF 漏洞. Clang 靜態(tài)分析器通過在軟件編譯過程中執(zhí)行控制流分析、路徑敏感分析和過程間分析進行漏洞檢測. 為了平衡有效性和可擴展性,它通過函數(shù)內(nèi)聯(lián)技術(shù)執(zhí)行有限的過程間分析,并且只進行簡單的指針分析和保守的循環(huán)分析. 因此,在減少誤報率的同時,也會漏報一些程序間和程序內(nèi)的UAF 漏洞.

除以上主要針對源代碼的UAF 檢測技術(shù),對于應(yīng)用場景更多的二進制程序,也有一些UAF 檢測技術(shù). 由于二進制程序相比源碼缺失更多的信息,所以一般都是在二進制程序的基礎(chǔ)上提取出抽象信息用于指導(dǎo)檢測. 如GUEB[18]先構(gòu)建出抽象內(nèi)存模型作為其中間表示;然后通過值分析和指針別名分析來跟蹤堆的操作和指針傳播;最后為檢測到的每個UAF 漏洞提取1 個子圖,以描述指針的創(chuàng)建、釋放和使用位置. GUEB 可以在沒有源代碼的情況下檢測UAF 漏洞,并且比嚴(yán)重依賴于測試用例的動態(tài)檢測器提供更好的覆蓋率. 然而,由于反匯編技術(shù)的誤差和不完善的指針分析,GUEB 的檢測結(jié)果既不精確也不可靠. 此外,GUEB 在分析真正的大型程序時存在一定難度,因為它使用函數(shù)內(nèi)聯(lián)技術(shù)進行過程間分析,導(dǎo)致多次調(diào)用的函數(shù)被重復(fù)處理[19]. 而UAFDetector[20]提出釋放后使用特征模型為檢測提供指導(dǎo),再將目標(biāo)程序的二進制代碼轉(zhuǎn)換為中間表示并構(gòu)建控制流圖,最后執(zhí)行指針跟蹤以識別UAF 漏洞. 其方案與前者類似,它使用函數(shù)摘要技術(shù)而不是函數(shù)內(nèi)聯(lián)技術(shù)進行過程間分析,實現(xiàn)了更好的可擴展性,并減少了不必要的分析開銷.

由于部分靜態(tài)分析技術(shù)的局限性導(dǎo)致靜態(tài)檢測存在一定的誤報率,所以部分研究采用動態(tài)檢測. Mudflap[21]在C/C++程序編譯時添加內(nèi)存檢查. Mudflap 在指針的使用位置處靜態(tài)插入合法性驗證斷言. 斷言取決于指針是否訪問有效內(nèi)存,這由Mudflap 維護的有效內(nèi)存對象列表決定. 實際環(huán)境中,對于復(fù)雜的C/C++ 程序,Mudflap 會出現(xiàn)較高的誤報率. UAFL[3]利用SVF[22]對中間語言進行過程間分析,依次尋找觸發(fā)UAF 漏洞的特定序列的3 個結(jié)點:內(nèi)存申請、內(nèi)存釋放和內(nèi)存使用,給出可能存在的UAF 漏洞,然后利用模糊測試技術(shù)驗證UAF 漏洞是否存在. DoubleTake[23]對共享庫函數(shù)進行修改,使得每個被釋放的內(nèi)存對象的前128 字節(jié)都被填充指定數(shù)據(jù),下一次申請內(nèi)存對象時通過檢查其中的值是否為指定數(shù)據(jù)來判斷是否存在UAF 漏洞,并立即觸發(fā)重新執(zhí)行以識別此錯誤的原因. 由于它的判斷依據(jù)是內(nèi)存對象中的指定數(shù)據(jù)是否被修改,所以對于通過UAF 漏洞泄露信息的漏洞無法檢測.

Valgrind 使用反匯編技術(shù)首先將機器代碼翻譯成中間表達(Intermediate Representation,IR)形式,再在關(guān)鍵位置插入額外的IR 以啟用內(nèi)存檢查,最后將這些IR 翻譯回機器代碼. 最后在運行時,插入的代碼就可以實時檢測軟件是否有UAF 漏洞觸發(fā). Dr. Memory 與Valgrind 的不同之處在于Dr. Memory 是基于DynamoRIO[24]執(zhí)行內(nèi)存檢查優(yōu)化. DynamoRIO 復(fù)制每條指令并且對每條指令都添加相應(yīng)的注釋,以解釋這條指令的效果. 二者相同之處在于都將影子內(nèi)存拆分成類似的多級結(jié)構(gòu),即多級影子映射,以減少內(nèi)存開銷并加速查詢. Valgrind 和Dr. Memory 的缺點就是由于增加了檢測代碼,導(dǎo)致新的程序?qū)ο到y(tǒng)開銷增大很多.

簡而言之,動態(tài)分析一般先將程序轉(zhuǎn)換成IR或者直接在二進制文件上進行插樁,然后在程序運行時檢測是否存在UAF 漏洞. 這種方式雖然具有較低的誤報率,但也存在低覆蓋率和高性能開銷問題.

本文的主要貢獻如下:(1) 基于導(dǎo)致UAF 漏洞的2 個條件,本文提出了輕量級的UAF 漏洞靜態(tài)檢測方案;(2) 采用調(diào)用圖的逆拓撲序列的方式遍歷并處理程序,將過程間分析簡化為過程內(nèi)分析,減小了系統(tǒng)開銷;(3) 結(jié)合基于指令間關(guān)系的別名分析和Andersen 別名分析算法的別名分析快速且準(zhǔn)確地得到所有懸空指針;(4) 將設(shè)計的檢測方案實現(xiàn)并與其他靜態(tài)分析工具進行比較,證明了該方案的有效性,且在UAF 漏洞檢測方面優(yōu)于它們.

2 LLVM

LLVM(Low Level Virtual Machine)是用途廣泛的編譯器基礎(chǔ)架構(gòu). 它將編譯器的功能進行模塊化劃分與封裝,使得用戶可以根據(jù)自身需求定制編譯器. 如圖2 所示,其主要分為3 部分:編譯器前端、優(yōu)化器、編譯器后端. 其前端對程序源代碼依次進行詞法分析,語法分析和語義分析,最后生成IR. 優(yōu)化器使用Pass 對IR 進行優(yōu)化,既可以優(yōu)化代碼也可以進行靜態(tài)分析. 編譯器后端則根據(jù)優(yōu)化后的IR 生成在目標(biāo)機器上運行的機器碼,即目標(biāo)程序.

IR 是屬于低級語言,有如下特點:采用靜態(tài)單一賦值(Static Single Assignment,SSA),即每個值只有1 個定義它的賦值操作;代碼被組織為三地址指令(Three-Address Instructions);寄存器的數(shù)量不受限制.

模塊是LLVM IR 的頂層數(shù)據(jù)結(jié)構(gòu),包含目標(biāo)機器信息、函數(shù)的聲明定義、符號表和全局變量.函數(shù)包含函數(shù)的返回類型、函數(shù)名、參數(shù)類型和函數(shù)體. 其中,函數(shù)體由一系列基本塊構(gòu)成,基本塊由一系列各種指令構(gòu)成,如訪問內(nèi)存指令、操作內(nèi)存指令、類型轉(zhuǎn)換指令、算術(shù)運算指令及跳轉(zhuǎn)指令等,特殊的是最后1 條指令一般都是終止指令. 常見指令及其作用如表1 所示. 其中,getelementptr指令常用于獲取聚合數(shù)據(jù)結(jié)構(gòu)的子元素的地址,如結(jié)構(gòu)體成員變量的地址.

優(yōu)化器的功能由1 個或者多個Pass 實現(xiàn),以LLVM IR 作為輸入輸出. 多個Pass 可以協(xié)同工作,并且Pass 支持用戶自定義. 為了實現(xiàn)不同級別的優(yōu)化和分析,需要通過繼承Pass 類的子類MoudlePass、FunctionPass 和BasicBlockPass 實現(xiàn). 它們分別代表模塊級、函數(shù)級和基本塊級. 示例如圖3,該自定義Pass 使用LLVM 的CallGraph?WrapperPass 打印出程序中所有函數(shù)的函數(shù)名.

LLVM 中的Value 類和User 類是2 個非常重要的基類,其中繼承于Value 的子類表示它的結(jié)果可以在其他地方使用,而繼承于User 的子類表示它會使用1 個或多個Value 對象. LLVM 在SSA 的基礎(chǔ)上根據(jù)Value 與User 之間的關(guān)系得出use-def鏈和def-use 鏈. use-def 鏈?zhǔn)侵副荒硞€User 使用的Value 列表,def-use 鏈?zhǔn)鞘褂媚硞€Value 的User 列表. 它們極大地提升了LLVM 的數(shù)據(jù)流分析能力.

3 UAF 漏洞檢測方案

本節(jié)首先概述整個UAF 漏洞檢測流程,然后再詳細描述UAF 漏洞檢測方案的具體細節(jié).

3. 1 整體設(shè)計

UAF 漏洞檢測流程圖如圖4 所示. 通過Clang編譯器編譯源代碼可獲得LLVM IR,但微軟提供的開源工具llvm-mctoll[25]實現(xiàn)將常見架構(gòu)的二進制程序轉(zhuǎn)換成LLVM IR,可擴大本方案的適用范圍.

UAF漏洞靜態(tài)分析流程如下:( 1) 通過Clang編譯器或者 llvm-mctoll工具獲取 LLVM IR;( 2)進行調(diào)用圖分析,獲得程序的調(diào)用圖的逆拓撲序列;( 3) 進行控制流分析和數(shù)據(jù)流分析,獲得被釋放內(nèi)存對象的指針;( 4) 使用別名分析,收集所有懸空指針;( 5) 進行控制流分析,過濾不存在UAF漏洞的懸空指針;( 6) 利用函數(shù)的支配樹細化UAF漏洞操作序列;( 7) 以操作序列的形式報告UAF 漏洞.

通過數(shù)據(jù)流分析追蹤懸空指針的傳播,UAF漏洞檢測報告的查全率取決于數(shù)據(jù)流分析的精確性,是否可以查出所有懸空指針及其別名的傳播.UAF 漏洞誤報是將不存在UAF 漏洞的程序視為存在UAF 漏洞的程序. 由于數(shù)據(jù)流分析可以精確地獲得懸空指針及其使用指令,所以根據(jù)產(chǎn)生UAF 漏洞的2 個條件可知,誤報主要是在分析懸空指針能否被使用的階段產(chǎn)生的,即可達性分析.所以UAF 漏洞檢測報告的查準(zhǔn)率受到控制流分析的影響.

3. 2 基于靜態(tài)分析的UAF 漏洞檢測方案

UAF 漏洞檢測分為2 部分:檢測程序中可能存在的懸空指針;懸空指針是否被使用.

根據(jù)懸空指針的定義可知,若要檢測程序中存在的懸空指針,必須先獲得懸空指針可能產(chǎn)生的位置,即內(nèi)存釋放函數(shù)的調(diào)用位置,還需要確保在內(nèi)存對象被釋放后,相關(guān)指針沒有再次被定義.本文中,內(nèi)存釋放函數(shù)分為庫函數(shù)和對庫函數(shù)封裝的用戶自定義函數(shù)2 類,其參數(shù)列表中都一定存在被釋放內(nèi)存對象的指針. 具體檢測方法如算法1所示.

算法1 首先讀取配置文件獲取被測試程序中可能存在的常見內(nèi)存釋放函數(shù)的函數(shù)名,如free等,和代表內(nèi)存對象的指針參數(shù)序號. 同時使用LLVM 提供的Pass 構(gòu)建被測試程序的調(diào)用圖,再通過深度優(yōu)先遍歷調(diào)用圖可以得到所有用戶自定義函數(shù)的逆拓撲排序. 根據(jù)逆拓撲序列開始依次分析每個用戶自定義函數(shù)時,如果發(fā)現(xiàn)用戶自定義函數(shù)中存在內(nèi)存釋放函數(shù)調(diào)用,需要對該用戶自定義函數(shù)進行深入分析.

分析過程從對內(nèi)存釋放函數(shù)調(diào)用指令的處理開始,首先根據(jù)參數(shù)序號取出被釋放內(nèi)存對象的指針,然后通過別名分析獲取其別名,得到可能的懸空指針集合. 該別名分析算法在worklist 算法的基礎(chǔ)上結(jié)合了基于指令關(guān)系的別名分析和Andersen算法[26].

其中基于指令關(guān)系的別名分析主要側(cè)重于分析指針變量之間通過賦值運算符進行的賦值操作. 其中,將IR 中的store 指令視為變量的定義操作. load 指令視為使用操作. 基于指令關(guān)系的別名分析首先根據(jù)內(nèi)存對象指針變量確定對應(yīng)的寄存器,然后收集與該寄存器相關(guān)的load 和store 指令并對其進行處理. 如圖5 所示,對于函數(shù)func1,根據(jù)內(nèi)存釋放函數(shù)free 得到被釋放內(nèi)存對象指針a,遍歷func1 的指令發(fā)現(xiàn)在釋放內(nèi)存之前指針a 賦值給指針b,在IR 中主要表現(xiàn)形式為先使用load 指令獲取指針a,然后使用store 指令將其存儲到指針b中,所以追蹤變量a 的賦值操作時需要獲取load 和store 指令. 函數(shù)func2 同理,不過由于已知的內(nèi)存對象指針是被賦值,所以只需要獲取相關(guān)的store指令即可.

除了上述直接利用賦值操作符進行指針復(fù)制外,還有利用函數(shù)進行指針復(fù)制的特殊情況. 上述直接利用數(shù)據(jù)流分析進行獲取別名的方式對此并不適用,因此考慮使用Andersen 算法. 該算法只是收集與利用上述數(shù)據(jù)流分析得到的候選懸空指針集合相關(guān)的call 指令涉及的指針,然后利用Andersen算法計算其與已知的被釋放內(nèi)存對象指針是否存在別名關(guān)系. 如果存在,則將其視為別名,反之,則舍棄.

通過上述方法獲得程序中所有可能的懸空指針之后,查找其使用位置前,還需要進行驗證,確保其屬于懸空指針,即沒有再次被定義. 本文根據(jù)可能的懸空指針是否是全局變量選擇執(zhí)行不同的檢測方案.

考慮循環(huán)結(jié)構(gòu)的影響,對于局部變量類型的候選懸空指針,本文在GetNotRedefined 函數(shù)中通過前向分析來確定在某個內(nèi)存釋放函數(shù)之后,哪些指針仍然保持活性. 具體來說,算法首先為函數(shù)中的每個指令設(shè)置一個in 和out 映射,分別表示函數(shù)中的指令執(zhí)行前后是否可以到達相關(guān)的store 指令,然后通過遍歷每個基本塊并按照順序遍歷基本塊中的指令(主要是store,call 和終止指令這3類)來對所有指令進行前向分析. 對于每個指令,代碼檢查其入口和出口,并在此基礎(chǔ)上更新in 和out 映射. 具體而言,當(dāng)檢測到指令I(lǐng) 的in 與out 映射不同時,算法檢查該指令是否為定義指針變量AI 的store 指令. 如果不是,代碼將修改對應(yīng)的out映射,以將所有能夠到達I 的指令設(shè)置為活性. 接下來,算法按照基本塊終止指令的類型(分支、轉(zhuǎn)換、間接分支、返回或不可達)更新in 和out 映射.最后,算法根據(jù)in 和out 映射中的結(jié)果確定哪些store 指令在某個內(nèi)存釋放函數(shù)之后定義了指針.

為了減少過程間分析帶來的性能開銷,本文通過從內(nèi)存釋放函數(shù)調(diào)用處開始順序遍歷指令的方式處理全局指針變量,嘗試得到與其相關(guān)的store 指令. 如果存在該store 指令,則在檢測懸空指針的使用時,還需要對懸空指針再定義與懸空指針使用之間進行可達性分析. 如果store 指令在load 指令之前執(zhí)行,則說明該指針在利用之前已經(jīng)被再次定義,故放棄對該指針的后續(xù)處理.

通過上述步驟,最終可以得到程序中的所有的懸空指針及其產(chǎn)生的位置,其中局部懸空指針以alloca 指令形式存儲. 特殊的是,由于僅使用 alloca指令表示局部聚合數(shù)據(jù)的成員可能導(dǎo)致很高的誤報率,所以為了精準(zhǔn)定位聚合數(shù)據(jù)中的懸空指針,還需要記錄對應(yīng)的getelementptr 指令的偏移下標(biāo).

獲取程序中所有懸空指針后,通過LLVM 的def-use 鏈逐個獲取每個懸空指針的使用者. 如果使用者是訪問內(nèi)存指令或操作內(nèi)存指令,且內(nèi)存釋放函數(shù)調(diào)用指令與該指令存在通路,則視為存在UAF 漏洞. 需要注意的是,對于局部聚合數(shù)據(jù)中的懸空指針,通過alloca 指令的def-use 鏈獲取它的使用者之后,還需要確定每個使用者是否是getelementptr指令,如果是該類型指令,還要檢查getelementptr指令的偏移下標(biāo)是否與收集懸空指針階段保存的偏移下標(biāo)一致. 只有偏移下標(biāo)一致,才表明是聚合數(shù)據(jù)中的懸空指針被使用.

通過上述方法可以檢測出程序中是否存在UAF 漏洞,并以lt;內(nèi)存釋放位置,內(nèi)存使用位置gt;映射的形式表示UAF 漏洞. 為了保證內(nèi)存釋放函數(shù)調(diào)用指令不會被忽略,還需要實時更新內(nèi)存釋放函數(shù)信息. 更新機制首先會檢查當(dāng)前集合中的懸空指針是否會導(dǎo)致UAF 漏洞,即是否有對應(yīng)的lt; 內(nèi)存釋放位置,內(nèi)存使用位置gt; 映射. 如果存在,則將對應(yīng)的lt;內(nèi)存釋放位置,內(nèi)存使用位置gt;映射存放到集合中;如果不存在,則對該懸空指針進行數(shù)據(jù)流分析,檢查其是否屬于當(dāng)前函數(shù)的參數(shù),或存在別名關(guān)系. 如果該懸空指針屬于當(dāng)前函數(shù)的參數(shù)或存在別名關(guān)系,則將當(dāng)前函數(shù)視為用戶自定義的內(nèi)存釋放函數(shù),并更新內(nèi)存釋放函數(shù)信息.

在獲取程序中所有的UAF 漏洞之后,為了后續(xù)更好地分析UAF 漏洞,需要根據(jù)lt;內(nèi)存釋放位置,內(nèi)存使用位置gt;映射獲取對應(yīng)的UAF 操作序列. 具體來說,首先對集合中的每個映射進行分析:獲取內(nèi)存釋放位置所在函數(shù)的支配樹,然后獲取內(nèi)存釋放位置和內(nèi)存使用位置2 個結(jié)點的公共祖先結(jié)點,然后從下向上遍歷支配樹,得到從內(nèi)存釋放位置到內(nèi)存使用位置必經(jīng)的所有基本塊,即UAF 漏洞操作序列. 最后,以操作序列的形式報告UAF 漏洞.

4 實驗結(jié)果與分析

本文實驗均在Ubuntu 20. 04 64 bit 上進行,處理器為AMD 銳龍5 4600 G,內(nèi)存分配4 GB. 本文代碼基于C++編寫.

4. 1 實驗對象

為了評估該方案的有效性,本文使用了軟件保障參考數(shù)據(jù)庫公開的測試樣本集Juliet C/C++ 1. 3[27]對檢測方案進行驗證. 該測試用例集由一組具有已知漏洞的合成C 程序,且涵蓋了軟件中常見的118 種漏洞. 這些程序可以用于測試靜態(tài)分析器在各種系統(tǒng)環(huán)境下的有效性. 本文僅利用與UAF 漏洞(CWE-416)相關(guān)的C 語言測試用例子集,它的測試用例提供了數(shù)據(jù)結(jié)構(gòu)的不同變體以及不同的控制流和數(shù)據(jù)流模式中的漏洞示例. 每個測試文件都包含1 個有漏洞的函數(shù)和相應(yīng)的無漏洞函數(shù). 將每個測試用例都分成對應(yīng)的有漏洞測試用例和無漏洞測試用例,構(gòu)成了本文使用的包含276 個測試用例的集合. 其中包含138個存在UAF 漏洞的測試樣例和138 個不存在UAF 漏洞的測試樣例. 為了說明該方案在真實環(huán)境中的有效性,本文還利用了數(shù)個公開漏洞進行驗證,其基本信息如表2 所示.

4. 2 有效性驗證

4. 2. 1 開源測試用例集驗證

將本文提出的UAF 漏洞檢測方案與CBMC、TscanCode、Coccinelle和Clang 靜態(tài)分析器這4 個目前主流的靜態(tài)分析器進行比較. 實驗結(jié)果如表3 所示.

本文方案相比于其他4 個主流的靜態(tài)分析器效果更好. 其中,138 個存在UAF 漏洞的樣本都成功地被本文方案檢測出來,并且沒有錯誤地認為138 個正常樣本中存在UAF 漏洞. 其余4 個主流的靜態(tài)分析器雖然也沒有產(chǎn)生誤報,但是檢測出來的UAF 漏洞數(shù)量都沒有達到全部漏洞的50%,甚至更少. 圖6 直觀地展示了本文方案與其他靜態(tài)分析器的有效性分析.

通過開源測試用例集的驗證,說明本文方案對于常見的UAF 漏洞形式都能夠精確且迅速的檢測出來.

4. 2. 2 公開漏洞驗證

公開漏洞驗證結(jié)果如表4所示. 對于這5 個真實應(yīng)用程序,本文提出的方案表現(xiàn)良好,都成功地將其中的UAF 漏洞檢測出來. 對于結(jié)構(gòu)較簡單的bzip2recover 程序甚至做到了零誤報率. 但是對于復(fù)雜的程序,為了提高檢測效率,本方案采用了較簡單且保守的控制流分析,因此會導(dǎo)致檢測結(jié)果出現(xiàn)一定的誤報率. 由于靜態(tài)分析技術(shù)的局限性仍然存在一定的誤報率.Clang 靜態(tài)分析器只是成功地檢測出了gifsicle 程序中的UAF 漏洞,同時伴隨著誤報. 這主要是由于其對于結(jié)構(gòu)體內(nèi)部指針的分析具有一定缺陷.由于TscanCode 和Coccinelle 通過模式匹配的方式進行檢測,所以對于結(jié)構(gòu)復(fù)雜多變的真實程序,它們表現(xiàn)得也不盡人意,只是檢測出readelf 程序中的UAF 漏洞,并且后者伴隨著大量誤報.

4. 3 性能分析

為了比較5 個檢測工具之間的性能優(yōu)劣,本文統(tǒng)計了5 種檢測工具對6 個實驗對象進行檢測時的消耗時長,具體數(shù)據(jù)如表5 所示. 根據(jù)圖7 的直觀展示可知,本文提出的方案檢測耗時并不比主流的靜態(tài)分析器耗時更多,甚至大多數(shù)情況下能夠更快地給出檢測結(jié)果. 對于結(jié)構(gòu)越簡單的程序,本文提出的方案表現(xiàn)得越好. 此外,由于CBMC利用約束求解器進行漏洞檢測,導(dǎo)致其所消耗的時間通常是最多的,甚至是本方案所需時間的數(shù)十倍以上.

5 結(jié)論

因為由懸空指針引起的UAF 漏洞對計算機系統(tǒng)的危害性越來越嚴(yán)重,所以本文提出了輕量級的UAF 漏洞檢測方案. 該方案使用調(diào)用圖的逆拓撲序列遍歷函數(shù),不斷更新內(nèi)存釋放函數(shù)信息,從而避免過程間分析帶來的系統(tǒng)性能消耗. 此外,該方案還通過結(jié)合基于指令關(guān)系的別名分析和Andersen別名分析算法,使得別名分析在精確性和性能之間取得平衡. 最后該方案還利用基本塊之間的支配關(guān)系豐富每個UAF 漏洞操作序列,使得UAF 漏洞報告更詳細,為后續(xù)研究帶來便利. 通過LLVM Pass 實現(xiàn)該方案后,本文從開源測試用例和真實程序2 個角度驗證了該方案的可行性和高效性.

實驗結(jié)果表明,方案能夠有效地發(fā)現(xiàn)UAF 漏洞. 對于測試樣本集Juliet 中的276 個測試用例,本文提出的工具與其他4 種主流工具相比實現(xiàn)了零漏報率和零誤報率,初步證明了該方案的可行性.此外,本文還用數(shù)個公開漏洞進行測試,都成功地檢測出其中的UAF 漏洞. 通過比較不同工具檢測不同程序的消耗時長可以說明,該方案對于小型程序中的UAF 漏洞檢測具有較大優(yōu)勢. 并且對于結(jié)構(gòu)復(fù)雜的程序,也能展示出不錯的效果. 不過,由于可達性分析和數(shù)據(jù)流分析的難度隨著程序規(guī)模的不斷變大而增加,所以對于較復(fù)雜的程序,依舊存在一定的誤報率.

目前,該方案也存在一些不足之處. 對于異步程序,由于其控制流圖和調(diào)用圖需要考慮回調(diào)函數(shù)和事件循環(huán),且有可能導(dǎo)致多線程執(zhí)行,因此通過靜態(tài)分析檢測其中的UAF 漏洞可能存在較大的誤報率和漏報率. 此外,本方案雖然可以通過采用llvm-mctoll 工具將二進制程序轉(zhuǎn)化為LLVM IR,擴大了本方案的適用范圍,但是該工具并不能支持所有架構(gòu)的二進制程序,且轉(zhuǎn)換后可能導(dǎo)致程序結(jié)構(gòu)更加復(fù)雜.

參考文獻:

[1] Booth H, Rike D, Witte G A. The national vulnerabilitydatabase( NVD): Overview[ EB/OL].[2023-02-05]. https://csrc. nist. gov/pubs/itlb/2013/12/thenational-vulnerability-database-nvd-overview/fi-nal.

[2] Yan H, Sui Y, Chen S, et al. Spatio-temporal contextreduction: A pointer-analysis-based static approachfor detecting use-after-free vulnerabilities[ C]//Proceedings of the 2018 IEEE/ACM 40th InternationalConference on Software Engineering( ICSE).New York: IEEE, 2018: 327.

[3] Wang H, Xie X, Li Y, et al. Typestate-guidedfuzzer for discovering use-after-free vulnerabilities[ C]//Proceedings of the 2020 IEEE/ACM 42nd InternationalConference on Software Engineering( ICSE).New York: IEEE, 2020: 999.

[4] Sotirov A. Heap feng shui in JavaScript[ R]. Amsterdam:Black Hat Europe, 2007: 11.

[5] Van Der Kouwe E, Nigade V, Giuffrida C. Dangsan:Scalable use-after-free detection [C]//Proceedingsof the Twelfth European Conference on Com ?puter Systems. New York: Association for Comput?ing Machinery, 2017: 405.

[6] Lattner C, Adve V. LLVM: A compilation frameworkfor lifelong program analysis amp; transformation[C]//Proceedings of the International Symposiumon Code Generation and Optimization. SanJose: IEEE, 2004: 75.

[7] Shen Z, Dolan-Gavitt B. Heapexpo: Pinpointing promotedpointers to prevent use-after-free vulnerabilities[ C]//Proceedings of the Annual Computer SecurityApplications Conference. New York: Associationfor Computing Machinery, 2020: 454.

[8] Lee B, Song C, Jang Y, et al. Preventing use-afterfreewith dangling pointers 1ification [C]// Proceedingsof the 2015 International Conference onCloud and Autonomic Computing. San Diego: TheInternet Society, 2015.

[9] Younan Y. FreeSentry: protecting against use-afterfreevulnerabilities due to dangling Pointers [C]//Proceedings of the 2015 International Conference onCloud and Autonomic Computing. San Diego: TheInternet Society, 2015.

[10] Kroening D, Tautschnig M. CBMC-C boundedmodel checker: (Competition contribution) [C]//Proceedings of the 20th International ConferenceTools and Algorithms for the Construction andAnalysis of Systems. Berlin: Springer Berlin Heidelberg,2014: 389.

[11] Olesen M C, Hansen R R, Lawall J L, et al. Coccinelle:Tool support for automated CERT C securecoding standard certification [J]. ScI Comput Program,2014, 91: 141.

[12] Clang. Clang static analyzer [DB/OL]. [2023-03-23]. http://clang-analyzer. llvm. org/.

[13] Tencent. TscanCode [DB/OL]. [2023-03-23].https://github. com/Tencent/TscanCode/.

[14] Nethercote N, Seward J. Valgrind: A framework forheavyweight dynamic binary instrumentation [J].ACM Sigplan Notices, 2007, 42: 89.

[15] Bruening D, Zhao Q. Practical memory checkingwith Dr. Memory [C]//International Symposium onCode Generation and Optimization (CGO 2011).New York: IEEE, 2011: 213.

[16] Ye J, Zhang C, Han X. POSTER: UAFChecker:Scalable static detection of use-after-free vulnerabilities[C]//Proceedings of the 2014 ACM SIGSACConference on Computer and Communications Security.New York: Association for Computing Machinery,2014: 1529.

[17] Biere A, Cimatti A, Clarke E M, et al. Boundedmodel checking [J]. Handbook of Satisfiability,2009, 185: 457.

[18] Feist J, Mounier L, Potet M L. Statically detectinguse after free on binary code [J]. Journal of ComputerVirology and Hacking Techniques, 2014,10: 211.

[19] Gui B, Song W, Xiong H, et al. Automated useafter-free detection and exploit mitigation: how farhave we gone [J]. IEEE T Software Eng,2021, 48:4569.

[20] Zhu K, Lu Y, Huang H. Scalable static detection ofuse-after-free vulnerabilities in binary code [J]. IEEEAccess, 2020, 8: 78713.

[21] Eigler F C. Mudflap: Pointer use checking for C/C++ [C]//Proceedings of the 2003 GCC Summit.[S. l. :s. n.],2003: 57.

[22] Sui Y, Xue J. SVF: Interprocedural static valueflowanalysis in LLVM [C]//Proceedings of the25th international conference on compiler construction.New York: Association for Computing Machinery,2016: 265.

[23] Liu T, Curtsinger C, Berger E D. Doubletake: Fastand precise error detection via evidence-based dynamicanalysis [C]// Proceedings of the 38th InternationalConference on Software Engineering. NewYork: Association for Computing Machinery,2016: 911.

[24] Bruening D. Efficient, transparent, and comprehensiveruntime code manipulation [D]. Cambridge,Boston, MA: Massachusetts Institute of Technology,2004.

[25] Yadavalli S B, Smith A. Raising binaries to LLVMIR with MCTOLL( WIP paper)[ C]// Proceedingsof the 20th ACM SIGPLAN/SIGBED InternationalConference on Languages. New York: Associationfor Computing Machinery, 2019: 213.

[26] Andersen L. Program analysis and specialization forthe C programming language[ D]. Copenhagen: Universityof Copenhagen, 1994.

[27] NIST. Juliet test suite 1. 3. test suites [DB/OL].(2017-10-01)[2023-03-23]. https://samate. nist.gov/SRD/testsuite. php/.

(責(zé)任編輯: 伍少梅)

基金項目: 國家重點研發(fā)計劃項目(2021YGB3101800)

主站蜘蛛池模板: 欧美另类一区| 国产一区二区三区精品久久呦| 亚洲精品大秀视频| 1级黄色毛片| 人妻免费无码不卡视频| 亚洲一区二区成人| 亚洲中文字幕23页在线| 中国国产高清免费AV片| 成人福利视频网| 在线播放真实国产乱子伦| 亚洲欧洲日韩综合| 亚洲精品国产精品乱码不卞| 中文国产成人久久精品小说| 囯产av无码片毛片一级| 色综合久久久久8天国| 无码国产伊人| 久久久四虎成人永久免费网站| 亚洲日韩国产精品综合在线观看| 国产三级毛片| 久久6免费视频| 欧美色视频在线| 国产精品手机视频一区二区| 国产精品视频观看裸模| 一本大道东京热无码av| 久久国产亚洲欧美日韩精品| 久久久黄色片| 国产香蕉国产精品偷在线观看 | 亚洲国产欧洲精品路线久久| 久久黄色小视频| 91高清在线视频| 国产xx在线观看| 国产精品白浆在线播放| 91福利在线观看视频| 午夜性刺激在线观看免费| 成人毛片在线播放| 国产精品无码影视久久久久久久| 一级毛片免费不卡在线视频| 欧美激情福利| 狠狠综合久久久久综| 18禁影院亚洲专区| 中文字幕免费视频| 久久免费视频6| 亚洲天堂网在线观看视频| 亚洲男人的天堂在线观看| 高h视频在线| 亚洲中文久久精品无玛| 国产小视频a在线观看| 国产精品污视频| 国产成人综合亚洲欧美在| 无码一区二区三区视频在线播放| 色综合狠狠操| 一级毛片不卡片免费观看| 亚洲婷婷在线视频| 成·人免费午夜无码视频在线观看| 无码中文AⅤ在线观看| 精品国产aⅴ一区二区三区| 538国产视频| 成人夜夜嗨| 美女被操91视频| 中文字幕亚洲精品2页| 亚洲国产亚洲综合在线尤物| 国内精品视频| 青青草原国产| 波多野结衣第一页| 久久国产精品波多野结衣| 国产va在线观看免费| 99草精品视频| 91区国产福利在线观看午夜| 国产美女一级毛片| 国产美女丝袜高潮| 欧美福利在线观看| 一本色道久久88| 九九精品在线观看| 亚洲无码免费黄色网址| 国产成人精品18| 午夜影院a级片| 亚洲成A人V欧美综合天堂| 亚洲资源站av无码网址| 日韩欧美国产另类| 精品国产免费观看| 在线观看免费人成视频色快速| 国内精品久久久久鸭|