







摘要:針對同內(nèi)存空間操作的多指針變量關(guān)系和跨函數(shù)調(diào)用的指針特征,文章提出一種基于執(zhí)行域敏感屬性圖的指針類漏洞檢測方法。文章采用語法、控制流、指針關(guān)系和函數(shù)調(diào)用來刻畫程序及其指針變量的執(zhí)行過程并構(gòu)建執(zhí)行域敏感屬性圖,聚焦于指針行為特征及與內(nèi)存域的聯(lián)系,通過圖遍歷得到與指針類漏洞相關(guān)的節(jié)點(diǎn)與邊,并基于漏洞特征實(shí)現(xiàn)指針類漏洞的檢測。實(shí)驗(yàn)結(jié)果表明,提出的方法在漏洞發(fā)現(xiàn)的準(zhǔn)確率、誤報(bào)率和漏報(bào)率上均有較好表現(xiàn),為執(zhí)行域敏感屬性應(yīng)用于軟件漏洞檢測提供了新的可靠途徑。
關(guān)鍵詞: 指針漏洞;指針依賴;函數(shù)調(diào)用;敏感屬性圖;漏洞檢測
中圖分類號:TP393.08 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號:1009-3044(2024)27-0004-04
0 引言
由錯(cuò)誤使用內(nèi)存所引發(fā)的安全漏洞是軟件開發(fā)的安全隱患之一,主要涉及對內(nèi)存管理的錯(cuò)誤或不當(dāng)使用。常見的內(nèi)存相關(guān)漏洞包括緩沖區(qū)溢出、已釋放內(nèi)存重用、內(nèi)存泄漏等,通常發(fā)生在程序未正確驗(yàn)證輸入數(shù)據(jù)的長度或類型,導(dǎo)致數(shù)據(jù)超過分配的內(nèi)存空間或者內(nèi)存數(shù)據(jù)被篡改,并可能被攻擊者利用來執(zhí)行任意代碼、繞過安全檢查、拒絕服務(wù)等。典型的如微軟披露的涉及25個(gè)嚴(yán)重內(nèi)存分配漏洞的家族“BadAl?loc”,源于易受攻擊的內(nèi)存功能相關(guān)的指針使用,攻擊者可以利用這些漏洞繞過安全控制,以執(zhí)行惡意代碼或?qū)е孪到y(tǒng)崩潰。深信服科技《2022漏洞威脅分析報(bào)告》指出[1],漏洞數(shù)量持續(xù)增長,由漏洞引發(fā)的主要威脅有未授權(quán)的信息泄露和管理訪問權(quán)限獲取,網(wǎng)絡(luò)攻擊趨于破壞性攻擊。Fortinet《2023上半年全球威脅態(tài)勢報(bào)告(1H 2023 Global Threat Landscape report) 》指出[2],過去五年間檢測到特定漏洞被利用次數(shù)增加了68%,潛在威脅者往往使用轉(zhuǎn)入捕獲技術(shù)攔截用戶輸入以非法竊取憑據(jù)信息或通過在內(nèi)存中查找憑據(jù)并收集數(shù)據(jù)。在眾多漏洞類型中,與內(nèi)存相關(guān)漏洞的危害性不容小覷,其中,“釋放后重用”(Use-After-Free) 更是成為2023年CWE TOP 5之一。
鑒于軟件開發(fā)中的安全左移原則,靜態(tài)分析在檢測指針類漏洞方面已取得一定成果,其判定依據(jù)主要包括數(shù)據(jù)流分析中指針的位置與精度以及內(nèi)存數(shù)據(jù)的變化情況。然而,當(dāng)前方法仍面臨諸多挑戰(zhàn)。一方面,由于與內(nèi)存相關(guān)聯(lián)的多指針變量之間的復(fù)雜關(guān)系由內(nèi)存區(qū)域決定,若多個(gè)指針對同一內(nèi)存空間進(jìn)行操作,簡單的別名分析方法難以準(zhǔn)確判定指針間的實(shí)際關(guān)系,從而可能導(dǎo)致漏洞的誤報(bào)或漏報(bào)[3]。另一方面,靜態(tài)分析指針類漏洞的過程需跨越函數(shù)或過程的界限,全面考慮函數(shù)調(diào)用時(shí)參數(shù)與其他變量的相互影響、內(nèi)存共享以及指針運(yùn)算時(shí)的內(nèi)存指向信息,否則將忽略過程間行為或上下文信息,降低漏洞檢測的準(zhǔn)確性。
1 基于執(zhí)行域敏感屬性圖的漏洞檢測模型
基于代碼屬性圖(CPG) 的生成[4],通過指針關(guān)系依賴和函數(shù)調(diào)用等子圖構(gòu)建執(zhí)行域敏感屬性圖并用于指針類漏洞檢測的模型(EDSPG) ,如圖1所示。首先,構(gòu)建源代碼的執(zhí)行域敏感屬性圖,包含多個(gè)角度檢測漏洞所需的語義信息,其關(guān)鍵在于通過定義指針與內(nèi)存區(qū)域之間的抽象關(guān)系和函數(shù)調(diào)用的規(guī)則[5],旨在獲取指針變量之間基于內(nèi)存區(qū)域的精確聯(lián)系,并用于構(gòu)建屬性圖的指針關(guān)系子圖和函數(shù)調(diào)用子圖。其中,前者通過指針變量所分配的內(nèi)存域體現(xiàn)它們之間的關(guān)系,并用于刻畫程序的執(zhí)行過程,尤其是涉及指針變量的部分。其次,建立基于特定標(biāo)簽或?qū)傩缘谋闅v規(guī)則,用于指導(dǎo)沿圖的邊和節(jié)點(diǎn)的移動(dòng)策略,目的在于獲得與指針類漏洞相關(guān)的部分,該過程涉及識(shí)別和跟蹤關(guān)鍵的節(jié)點(diǎn)和邊,用于漏洞的準(zhǔn)確定位。第三,基于漏洞特征建立漏洞判定規(guī)則,基于漏洞的特征形式化描述,針對執(zhí)行域敏感屬性圖實(shí)現(xiàn)指針類漏洞的檢測。
執(zhí)行域敏感屬性圖展示了程序相關(guān)語義和執(zhí)行流程,包括運(yùn)行時(shí)為指針分配的動(dòng)態(tài)內(nèi)存域以及指針指向的內(nèi)存域變化。圖的結(jié)構(gòu)由源代碼抽象語法樹、程序控制流圖、指針關(guān)系依賴圖和函數(shù)調(diào)用圖聚合而成,聚焦于指針的行為特征及與內(nèi)存聯(lián)系,并用于檢測指針類漏洞。
2 指針關(guān)系依賴圖
指針描述內(nèi)存單元的地址,指針變量間的關(guān)系體現(xiàn)指針?biāo)赶騼?nèi)存的關(guān)聯(lián)性。采用基本變量的數(shù)據(jù)流分析方法不能有效檢測出由內(nèi)存狀態(tài)引發(fā)的漏洞。因此,建立面向指針變量的抽象內(nèi)存模型,通過記錄程序路徑中各個(gè)程序點(diǎn)的指針變量并形成相應(yīng)的抽象內(nèi)存模型記錄,以獲得指針變量與內(nèi)存的關(guān)聯(lián),進(jìn)而通過分析抽象內(nèi)存模型獲得指針之間的依賴關(guān)系,構(gòu)建指針關(guān)系依賴圖。
定義1 指針抽象內(nèi)存模型可描述為Mp=。其中,Var表示指針變量名稱;Type表示指針變量定義的類型;Region表示指針變量關(guān)聯(lián)的抽象內(nèi)存區(qū)域?qū)傩?,描述為(typex,byte,offset),這里typex為指針指向抽象內(nèi)存區(qū)域的唯一編號,byte表示指針變量指向內(nèi)存區(qū)域占用的字節(jié)數(shù);offset表示指針的偏移量;Scope表示指針變量的作用域;State代表指針變量的狀態(tài);LineN為代碼行號。
定義2 指針運(yùn)算是包含指針和地址的操作,用于對表達(dá)式左值的指針賦值,可描述為pointer opera?tion ::= p+offset| array+offset| array[j]+ offset。
指針運(yùn)算的形式包括指針變量對于分配基本變量類、數(shù)組類、數(shù)組元素類等內(nèi)存后的偏移量運(yùn)算等。每種運(yùn)算形式可能會(huì)改變左值變量指針指向的內(nèi)存域,從而導(dǎo)致左值指針變量的指針抽象內(nèi)存模型發(fā)生變化。
通過定義指針抽象內(nèi)存模型以及指針運(yùn)算,可得到程序中具體指針變量的六元組及指針變量指向內(nèi)存的狀態(tài)變化。圖2為一段能引發(fā)Use-After-Free漏洞的代碼實(shí)例,可用定義第2行指針變量q,用 表示第3行狀態(tài)更新后的指針變量q,用定義第7行指針變量p,使用公式np=p+offset計(jì)算第8行的op()操作,形如(np:p) = (p:q)+(offset:0),可將指針變量p的指針抽象內(nèi)存模型更新為,計(jì)算出指針變量p 和q 指向同一塊內(nèi)存區(qū)域int1,為指針變量p 和q之間依賴關(guān)系的定義提供條件。
為了捕獲指針變量基于內(nèi)存域的聯(lián)系,通過抽象內(nèi)存模型獲取指針變量分配的內(nèi)存域信息,并基于指針運(yùn)算規(guī)則更新抽象內(nèi)存模型六元組以更新指針變量指向內(nèi)存域的變化信息。通過抽象內(nèi)存模型六元組描述指針變量的依賴關(guān)系,基于指針變量的依賴關(guān)系建立指針關(guān)系依賴圖。
3 函數(shù)調(diào)用圖
通過函數(shù)調(diào)用圖獲得本體函數(shù)到被調(diào)用函數(shù)的可達(dá)路徑,實(shí)現(xiàn)跨函數(shù)的路徑分析。當(dāng)變量的值取決于其他函數(shù)的輸出時(shí),通過追蹤這些依賴關(guān)系,可準(zhǔn)確地獲取這些變量的信息,提高代碼分析的精度。在源代碼抽象語法樹中,一個(gè)函數(shù)體內(nèi)調(diào)用的其他函數(shù)方法被表示為這個(gè)函數(shù)體形成的源代碼抽象語法樹中的一個(gè)節(jié)點(diǎn),它對應(yīng)于被調(diào)用函數(shù)的源代碼抽象語法樹的根節(jié)點(diǎn)。因此,基于源代碼抽象語法樹,合并同名方法的函數(shù)調(diào)用節(jié)點(diǎn)和函數(shù)定義節(jié)點(diǎn),形成函數(shù)調(diào)用邊并最終得到函數(shù)調(diào)用圖。
圖2漏洞代碼實(shí)例的函數(shù)調(diào)用圖構(gòu)建過程如圖3 所示。首先遍歷函數(shù)體內(nèi)調(diào)用函數(shù)類型的節(jié)點(diǎn),主函數(shù)中調(diào)用了名為op的函數(shù),表現(xiàn)為主函數(shù)的源代碼抽象語法樹中有一個(gè)類型為“FunctionExpression”的名為op的節(jié)點(diǎn),再遍歷找到根節(jié)點(diǎn)與其同名的源代碼抽象語法樹,添加一條函數(shù)調(diào)用邊將主函數(shù)調(diào)用語句節(jié)點(diǎn)與被調(diào)用函數(shù)根節(jié)點(diǎn)連接。
4 執(zhí)行域敏感屬性圖及其遍歷
執(zhí)行域敏感屬性圖由源代碼抽象語法樹、程序控制流圖、指針關(guān)系依賴圖和函數(shù)調(diào)用圖取并集建立,Computer Knowledge and Technology 電腦知識(shí)與技術(shù)第20 卷第27 期 (2024 年9 月)不同子圖表示不同的代碼語義信息。對執(zhí)行域敏感屬性圖遍歷,是按一定的規(guī)則檢索圖中節(jié)點(diǎn)和邊,即從任一節(jié)點(diǎn)或邊開始,匹配屬性和邊的類型,沿邊正向或者逆向搜索到與之相鄰的下一組節(jié)點(diǎn)或邊,終止于符合條件的節(jié)點(diǎn)或邊。
圖2 代碼實(shí)例在執(zhí)行printf 函數(shù)時(shí)引發(fā)Use-After-Free 漏洞,其中,指針變量q和p、malloc 函數(shù)、free函數(shù)等構(gòu)成漏洞的詞法特征。實(shí)際上,與指針類漏洞相關(guān)的詞法特征包括指針變量與指針運(yùn)算符、內(nèi)存分配函數(shù)(如malloc、calloc、realloc、new等)、內(nèi)存釋放函數(shù)(如free、delete等)、內(nèi)存區(qū)域操作行為運(yùn)算符等。將漏洞的詞法特征定義為敏感因子s,它是漏洞出現(xiàn)的必要條件。由于屬性圖節(jié)點(diǎn)由源代碼抽象語法樹節(jié)點(diǎn)構(gòu)成,因此屬性圖包含源代碼抽象語法樹的全部信息,這些信息可以描述程序的詞法和語法結(jié)構(gòu)信息,通過語法結(jié)構(gòu)找到漏洞敏感因子。
圖2代碼實(shí)例漏洞的出現(xiàn)依賴于對指針變量分配內(nèi)存的操作、對指針指向的內(nèi)存區(qū)域進(jìn)行操作以及釋放指針?biāo)赶騼?nèi)存的操作等3個(gè)關(guān)鍵語法特征。因此,與指針類漏洞相關(guān)的語法特征包括為指針變量分配內(nèi)存的語句、釋放所分配內(nèi)存的語句、內(nèi)存區(qū)域操作的語句等。顯然,漏洞的語法特征包含了漏洞敏感因子。將包含敏感因子的語句定義為漏洞敏感點(diǎn)Ns。
除了漏洞敏感點(diǎn),還需分析其語義特征才能判定是否存在漏洞。在圖2代碼實(shí)例中,因?yàn)閛p函數(shù)為指針變量q分配內(nèi)存后進(jìn)行了釋放內(nèi)存的操作,之后又通過指針p訪問了該內(nèi)存域,表現(xiàn)為程序中存在漏洞敏感點(diǎn),且漏洞敏感點(diǎn)按一定順序執(zhí)行。這一特征構(gòu)成了Use-After-Free漏洞的語義特征,稱為漏洞約束,記為R。
定義3 漏洞特征C 可描述為C(VType)={Ns, R}。其中:VType為漏洞類型;Ns為漏洞敏感點(diǎn);R為漏洞約束。
定義3 具有性質(zhì){Prog}CVType{VulVTypeProg},即對于程序Prog,若滿足漏洞類型VType的漏洞特征CVType,則Pro47e50379a2c962015116d6ddba14844fdd3255a9cd178e1706c29192168fd77fg存在狀態(tài)為VulVTypeProg,類型為VType的漏洞。
5 實(shí)驗(yàn)結(jié)果與分析
實(shí)驗(yàn)選取C/CPP 的Juliet Test Suite for C/C++ 1.3 作為測試數(shù)據(jù)集,選取CWE-401(Memory Leak) 、CWE-415(Double-Free) 、CWE-416(Use-After-Free) 和CWE-762(Mismatched Memory Management Rou?tines) 4種指針類漏洞用于測試。使用Cloc工具獲得數(shù)據(jù)集信息如表1所示。
將本文方法EDSPG 與Cppcheck[6]、Flawfinder[7]、Splint[8]、MRVDAVE[9]、CPG等模型進(jìn)行對比,采用誤報(bào)率FPR、漏報(bào)率FNR和準(zhǔn)確率Acc作為評估指標(biāo)。
用不同檢測方法對數(shù)據(jù)集開展漏洞檢測實(shí)驗(yàn),其中與CWE-416漏洞有關(guān)的檢測情況如表2所示,表中,DVN為相應(yīng)方法或模型檢測出的漏洞數(shù)量,DVT 為檢測出的正確漏洞數(shù)量,DVF為誤報(bào)漏洞數(shù)量。針對CWE-416 漏洞,Cppcheck 和Flawfinder 出現(xiàn)100% 誤報(bào)率,主要因?yàn)镃ppcheck專注語法和代碼質(zhì)量檢查,不能深入分析內(nèi)存使用的狀態(tài)變化,而Flawfinder 基于文本搜索和模式匹配,無法理解內(nèi)存生命周期。相比之下,MRVDAF和EDSPG方法通過內(nèi)存分配、使用及釋放等語義規(guī)則,能更準(zhǔn)確地追蹤和理解內(nèi)存周期,均提高了正確漏洞識(shí)別的數(shù)量。
誤報(bào)率情況如圖4所示。由于Cppcheck和Flaw?finder不進(jìn)行數(shù)據(jù)流深度分析,檢測存在較高誤報(bào)率。Splint雖然增加了語義分析,但誤報(bào)率也較高。而具有數(shù)據(jù)流分析能力的MRVDAF和聚合了多種層次語義的聯(lián)合圖結(jié)構(gòu)的CPG,誤報(bào)率均較低。EDSPG構(gòu)建了指針變量之間的關(guān)系依賴邊,表達(dá)了更為精確的指針變量關(guān)系語義,同時(shí)基于執(zhí)行域敏感屬性圖對這4 種漏洞類型進(jìn)行形式化描述,在指針類漏洞檢測上具有更低的誤報(bào)率。
漏報(bào)率情況如圖5所示。Cppcheck和Flawfinder 由于沒有涉及語義分析,對于含較復(fù)雜語義程序的漏報(bào)率很高。Splint只匹配了基本程序語義,對于深層程序行為無法分析,導(dǎo)致漏報(bào)率也較高。MRVDAF因?yàn)槎x了漏洞的形式化信息并用于程序分析,較低了漏報(bào)率。CPG由于結(jié)構(gòu)是單一函數(shù)且缺少過程間分析,導(dǎo)致漏報(bào)率偏高。EDSPG通過關(guān)系依賴邊獲得指針變量的精確語義,并具備程序過程間分析,實(shí)現(xiàn)了更低的指針類漏洞漏報(bào)率。
準(zhǔn)確率情況如圖6所示。在需要語義分析的漏洞中,Cppcheck和Flawfinder均無法準(zhǔn)確檢測出漏洞,僅依賴數(shù)據(jù)流分析的Splint和依賴各層圖語義的CPG在漏洞檢測準(zhǔn)確性上表現(xiàn)不佳。MRVDAF在數(shù)據(jù)流分析的基礎(chǔ)上增加了漏洞的形式化信息,提升了漏洞檢測準(zhǔn)確率。EDSPG方法包含了與指針有關(guān)的行為信息,通過定義圖的遍歷與指針的行為描述,實(shí)現(xiàn)了較為全面的基于模型的漏洞分析,進(jìn)一步提升了漏洞檢測準(zhǔn)確率。
6 結(jié)束語
不同漏洞類型蘊(yùn)含不同的特征,本文提出基于執(zhí)行域敏感屬性圖的指針類漏洞檢測方法,通過分析指針與內(nèi)存關(guān)系,定義模型的子圖并使方法具備過程間分析的能力。實(shí)驗(yàn)表明,EDSPG在Juliet數(shù)據(jù)集上對于4種指針類漏洞的檢測能力更好,漏洞檢測的準(zhǔn)確率上升,誤報(bào)率與漏報(bào)率降低。由于本文未考慮指向函數(shù)的指針變量情況,某些特殊的調(diào)用過程是通過函數(shù)指針調(diào)用并引發(fā)漏洞問題,且本文提出模型未考慮程序路徑的可達(dá)性問題。下一工作,將進(jìn)一步完善指針規(guī)則描述和可達(dá)性判斷,提升方法的有效性。
參考文獻(xiàn):
[1] Sangfor. 2022 漏洞威脅分析報(bào)告[EB/OL]. [2023-11-16]https://www.sangfor.com.cn/document/.
[2] FORTINET. FortiGuard Labs 1H 2023 Global Threat Land?scape Report[EB/OL]. [2023-09-28] https://www.fortinet.com/demand/gated/threat-report-1h-2023.
[3] JIN W H,ULLAH S,YOO D,et al.NPDHunter:efficient null pointer dereference vulnerability detection in binary[J]. IEEE Access,2021,9:90153-90169.
[4] YAMAGUCHI F,GOLDE N,ARP D,et al.Modeling and discov?ering vulnerabilities with code property graphs[C]//2014 IEEE Symposium on Security and Privacy.May 18-21,2014,Berkeley,CA,USA.IEEE,2014:590-604.
[5] 陳濤清,范廣生,尹幫虎,等.基于抽象解釋的函數(shù)內(nèi)聯(lián)過程間分析優(yōu)化方法[J].軟件學(xué)報(bào),2022,33(8):2964-2979.
[6] Cppcheck-2.12[CP/OL]. [2023-09-10] http://cppcheck.source?forge.net.
[7] Flawfinder-2.0.19[CP/OL].[2023-09-06]https://www.dwheeler.com/flawfinder.
[8] Splint-3.1.2[CP/OL]. [2023-9-6] https://www.splint.org.[9] HU J C,CHEN J F,ZHANG L,et al.A memory-related vulner?ability detection approach based on vulnerability features[J].Ts?inghua Science and Technology,2020,25(5):604-613.
【通聯(lián)編輯:代影】
基金項(xiàng)目:國家自然科學(xué)基金(項(xiàng)目編號:62062028) ;廣西可信軟件重點(diǎn)實(shí)驗(yàn)室基金(項(xiàng)目編號:202320) ;廣西研究生教育創(chuàng)新計(jì)劃項(xiàng)目(項(xiàng)目編號:YCSW2023295)