• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      基于控制流和數(shù)據(jù)流分析的內(nèi)存拷貝類函數(shù)識(shí)別技術(shù)

      2023-03-02 10:09:14尹小康蘆斌蔡瑞杰朱肖雅楊啟超劉勝利
      關(guān)鍵詞:指令集拷貝二進(jìn)制

      尹小康 蘆斌 蔡瑞杰 朱肖雅 楊啟超 劉勝利

      (數(shù)學(xué)工程與先進(jìn)計(jì)算國(guó)家重點(diǎn)實(shí)驗(yàn)室(信息工程大學(xué))鄭州 450001)

      利用漏洞發(fā)起網(wǎng)絡(luò)攻擊仍是當(dāng)前網(wǎng)絡(luò)攻擊中的主要方式.漏洞攻擊能夠使目標(biāo)設(shè)備癱瘓、實(shí)現(xiàn)對(duì)目標(biāo)設(shè)備的突破控制,或者對(duì)重要文件的竊取.在利用漏洞發(fā)起的攻擊中,危害性最高的漏洞之一為內(nèi)存錯(cuò)誤漏洞.內(nèi)存錯(cuò)誤漏洞包括內(nèi)存溢出漏洞、內(nèi)存泄漏漏洞和內(nèi)存釋放后重用漏洞等,這些漏洞能夠?qū)崿F(xiàn)任意代碼執(zhí)行,造成密鑰、口令等信息的泄露.在通用漏 洞披露組織(Common Vulnerabilities and Exposures,CVE)發(fā) 布的2021 年最危險(xiǎn)的25 種軟件脆弱性分析[1]中,CWE-787[2]即越界寫(out-of-bounds write,OOBW)排在了 第1 位,CWE-125[3]即越界 讀(out-of-bounds read,OOBR)排在第3 位以及CWE-119[4]即不當(dāng)?shù)膬?nèi)存緩沖區(qū)范圍內(nèi)的操作限制排在第17 位.內(nèi)存溢出漏洞和內(nèi)存泄漏漏洞的發(fā)生常常跟內(nèi)存的拷貝相關(guān),在進(jìn)行內(nèi)存拷貝的時(shí)候缺少對(duì)長(zhǎng)度的檢查,或者對(duì)特殊的字節(jié)進(jìn)行轉(zhuǎn)換時(shí)發(fā)生長(zhǎng)度的變化,都會(huì)導(dǎo)致對(duì)內(nèi)存的越界寫或者越界讀[5].因此內(nèi)存拷貝類函數(shù)(下文簡(jiǎn)稱拷貝類函數(shù))的識(shí)別對(duì)內(nèi)存錯(cuò)誤漏洞的發(fā)現(xiàn)和修補(bǔ)具有重大意義和價(jià)值.

      本文提出了一種拷貝類函數(shù)識(shí)別技術(shù)CPYFinder(copy function finder).該技術(shù)在不依賴函數(shù)名、符號(hào)表等信息的情況下,對(duì)函數(shù)的控制流進(jìn)行分析,并將二進(jìn)制代碼轉(zhuǎn)換成中間語(yǔ)言代碼進(jìn)行數(shù)據(jù)流的分析,識(shí)別二進(jìn)制程序中的拷貝類函數(shù).本文的主要貢獻(xiàn)包括4 個(gè)方面:

      1)分析了不同架構(gòu)下拷貝類函數(shù)的特點(diǎn),構(gòu)建了基于靜態(tài)的分析方法的拷貝類函數(shù)識(shí)別模型.

      2)提出并實(shí)現(xiàn)了二進(jìn)制程序中拷貝類函數(shù)識(shí)別技術(shù)CPYFinder,該方法不依賴函數(shù)名、符號(hào)表等信息,能夠識(shí)別無(wú)論是C 語(yǔ)言庫(kù)中還是用戶自定義實(shí)現(xiàn)的拷貝類函數(shù).

      3)提出的CPYFinder 具有良好的適用性和擴(kuò)展性,通過(guò)將二進(jìn)制代碼轉(zhuǎn)換成中間語(yǔ)言代碼進(jìn)行數(shù)據(jù)流的分析,使得支持x86,ARM,MIPS,PowerPC 指令集架構(gòu)的二進(jìn)制程序.

      4)從GitHub 上收集了拷貝類函數(shù),構(gòu)建了測(cè)試數(shù)據(jù)集進(jìn)行測(cè)試,并選取了真實(shí)的CVE 漏洞函數(shù)進(jìn)行了測(cè)試.實(shí)驗(yàn)結(jié)果表明CPYFinder 具有更好的表現(xiàn),在精準(zhǔn)率和召回率上得到更好的平衡,并且具有較低的運(yùn)行時(shí)耗.CPYFinder 對(duì)提高下游分析任務(wù)具有重大價(jià)值.

      1 相關(guān)工作

      拷貝類函數(shù)的識(shí)別對(duì)二進(jìn)制程序中內(nèi)存錯(cuò)誤漏洞的發(fā)現(xiàn)和修補(bǔ)具有重大意義和價(jià)值.由于版權(quán)或者安全的需要,軟件供應(yīng)商在程序發(fā)布的時(shí)候往往是以二進(jìn)制的形式進(jìn)行發(fā)行,甚至?xí)兂绦蛑械暮瘮?shù)名、符號(hào)表等信息.因此安全研究員只能在缺少源碼的情況下對(duì)二進(jìn)制程序進(jìn)行分析,進(jìn)而發(fā)現(xiàn)程序中的脆弱點(diǎn)并提供給供應(yīng)商進(jìn)行漏洞的修補(bǔ).相比于對(duì)源代碼的分析[6],由于二進(jìn)制代碼中丟失了高級(jí)語(yǔ)言具有的信息,例如C/C++中的函數(shù)原型、變量名、數(shù)據(jù)結(jié)構(gòu)等信息,因此對(duì)二進(jìn)制程序進(jìn)行分析具有更大的挑戰(zhàn).針對(duì)二進(jìn)制程序的分析技術(shù)主要有二進(jìn)制代碼審計(jì)[7]、污點(diǎn)分析[8-9]、符號(hào)執(zhí)行[10-11]等,這些技術(shù)在漏洞發(fā)現(xiàn)和分析中具有較好的效果.然而這些技術(shù)在一定程度上依賴函數(shù)名、符號(hào)表等信息,例如Mouzarani 等人[12]在提出的基于混合符號(hào)執(zhí)行的模糊測(cè)試技術(shù)中仍需要借助符號(hào)表對(duì)memcpy,strcpy等函數(shù)的識(shí)別.DTaint[13]和SaTC[14]等在進(jìn)行靜態(tài)污點(diǎn)分析中需要借助函數(shù)名,例如memcpy,strncpy等函數(shù),來(lái)定位關(guān)鍵函數(shù),進(jìn)而進(jìn)行后續(xù)的污點(diǎn)記錄和傳播等操作.當(dāng)二進(jìn)制程序剝除了函數(shù)名等信息時(shí),上述技術(shù)的效果將會(huì)受到嚴(yán)重影響.

      此外,當(dāng)前的研究中還存在一個(gè)被忽視的問(wèn)題:開(kāi)發(fā)者在開(kāi)發(fā)程序時(shí)會(huì)自定義實(shí)現(xiàn)類似于內(nèi)存拷貝功能的函數(shù),進(jìn)而會(huì)引入內(nèi)存錯(cuò)誤漏洞.例如,漏洞CVE-2020-8 423[15]發(fā)生在一個(gè)TP-Link TL-WR841N V10 路由器設(shè)備中,由函數(shù)intstringModify(char*dst,size_tsize,char*src)引發(fā)的 棧溢出漏洞.盡 管BootStomp[8],Karonte[9],SaTC[14]考慮到了對(duì)拷貝類函數(shù)的識(shí)別,但是它們的識(shí)別方法依據(jù)簡(jiǎn)單的代碼特征:1)從內(nèi)存中加載數(shù)據(jù);2)存儲(chǔ)數(shù)據(jù)到內(nèi)存中;3)增加1 個(gè)單元(字節(jié)byte、字word 等)的偏移值.然而滿足上述3 個(gè)特征的函數(shù)并不一定具有拷貝數(shù)據(jù)的功能,而且會(huì)遺漏用戶自定義實(shí)現(xiàn)的拷貝類函數(shù),因此具有較高的誤報(bào)率和漏報(bào)率.

      當(dāng)前針對(duì)剝除函數(shù)名等信息的二進(jìn)制程序中的函數(shù)識(shí)別技術(shù),主要是以靜態(tài)簽名的方法為主,例如IDA Pro 中使用 庫(kù)函數(shù) 快速識(shí) 別技術(shù)(fast library identification and recognition technology,FLIRT)[16],工具Radare2[17]使用Zsignature 技術(shù)對(duì)程序中的函數(shù)名進(jìn)行識(shí)別,此類方法能夠識(shí)別出簽名庫(kù)中包含已經(jīng)簽名的函數(shù),例如strcpy,memcpy等函數(shù).然而基于簽名的函數(shù)識(shí)別技術(shù)容易受編譯器類型(GCC,ICC,Clang 等)、編譯器版本(v5.4.0,v9.2.0 等)、優(yōu)化等級(jí)(O0~O3)以及目標(biāo)程序的架構(gòu)(x86,ARM,MIPS 等)的影響.而且,每種優(yōu)化等級(jí)又可以分為數(shù)十種優(yōu)化選項(xiàng)[18](在GCC v7.5.0 中O0 開(kāi) 啟了58 種優(yōu)化 選項(xiàng),O1 開(kāi)啟了92 種優(yōu)化選項(xiàng),O2 開(kāi)啟了130 種優(yōu)化選項(xiàng),O3 開(kāi)啟了142 種優(yōu)化選項(xiàng)),這些優(yōu)化選項(xiàng)可以通過(guò)配置進(jìn)行手動(dòng)地開(kāi)啟和關(guān)閉.因此,這些選項(xiàng)組合起來(lái)將產(chǎn)生成千上萬(wàn)種編譯方案,即同一份源碼經(jīng)過(guò)不同的編譯配置編譯后會(huì)產(chǎn)生成千上萬(wàn)個(gè)函數(shù),但這些函數(shù)的靜態(tài)簽名存在一定的差異,給基于簽名的函數(shù)識(shí)別造成了阻礙.因此,為準(zhǔn)確地識(shí)別函數(shù)需要構(gòu)建各種各樣的函數(shù)簽名,這些工作顯得尤為繁重.此外,基于簽名的函數(shù)識(shí)別只能識(shí)別已知的函數(shù),對(duì)于未知的拷貝類函數(shù)(簽名庫(kù)中不包含該函數(shù)的簽名)則無(wú)法識(shí)別,這仍是一個(gè)亟待解決的問(wèn)題.

      因此,為解決當(dāng)前研究中存在的依賴函數(shù)名等信息、無(wú)法識(shí)別未知的拷貝類函數(shù)以及識(shí)別的誤報(bào)率較高等問(wèn)題,本文提出了一種新穎的拷貝類函數(shù)識(shí)別技術(shù)CPYFinder,用于對(duì)剝除函數(shù)名等信息的二進(jìn)制程序中拷貝類函數(shù)的識(shí)別.該方法基于拷貝類函數(shù)的代碼結(jié)構(gòu)特征和數(shù)據(jù)流特征,通過(guò)對(duì)函數(shù)的控制流[19]和數(shù)據(jù)流[20]進(jìn)行分析,識(shí)別二進(jìn)制程序中具有內(nèi)存拷貝功能的函數(shù).CPYFinder 一定程度上避免了編譯器和優(yōu)化等級(jí)的影響,不依賴于函數(shù)名的信息,并且能夠識(shí)別開(kāi)發(fā)者自定義實(shí)現(xiàn)的內(nèi)存拷貝類函數(shù),通過(guò)將二進(jìn)制代碼轉(zhuǎn)換成中間語(yǔ)言表示(intermediate representation,IR)代碼進(jìn)行數(shù)據(jù)流的分析,使得CPYFinder 適用于x86,ARM,MIPS,PowerPC(PowerPC與PPC 等同)等指令集的二進(jìn)制程序,具有良好的適用性和擴(kuò)展性,以及較高的準(zhǔn)確率.

      經(jīng)過(guò)實(shí)驗(yàn)評(píng)估表明,CPYFinder 相比于最新的工作BootStomp 和SaTC,在對(duì)無(wú)論C 語(yǔ)言庫(kù)中的拷貝類函數(shù)還是對(duì)用戶自定義實(shí)現(xiàn)的拷貝類函數(shù)的識(shí)別上都具有更好的表現(xiàn);在精準(zhǔn)率和召回率上得到更好的平衡.在實(shí)際的路由器固件的5 個(gè)CVE 漏洞函數(shù)測(cè)試中,BootStomp 和SaTC 均未發(fā)現(xiàn)導(dǎo)致漏洞的拷貝類函數(shù),而CPYFinder 發(fā)現(xiàn)4 個(gè)漏洞函數(shù).在識(shí)別效率測(cè)試中發(fā)現(xiàn),CPYFinder 具有更高的識(shí)別效率;在增加數(shù)據(jù)流分析的情況下與SaTC 耗時(shí)幾乎相同,耗時(shí)僅相當(dāng)于BootStomp 的19%.CPYFinder 能夠?yàn)橄掠蔚姆治鋈蝿?wù),例如污點(diǎn)分析[21]、符號(hào)執(zhí)行[12]、模糊測(cè)試[22]等提供支持,在對(duì)內(nèi)存錯(cuò)誤漏洞的發(fā)現(xiàn)和檢測(cè)上具有較高的價(jià)值.

      2 問(wèn)題描述及相關(guān)技術(shù)

      本節(jié)主要介紹相關(guān)的定義、結(jié)合具體的實(shí)例對(duì)拷貝類函數(shù)識(shí)別的重要性進(jìn)行介紹、對(duì)現(xiàn)有方法存在的問(wèn)題進(jìn)行分析以及對(duì)VEX IR 中間語(yǔ)言進(jìn)行簡(jiǎn)要介紹.

      2.1 相關(guān)概念

      1)內(nèi)存拷貝類函數(shù)(memory copy function)[8].將數(shù)據(jù)從內(nèi)存中的一段區(qū)域(源地址)直接或者經(jīng)過(guò)處理(例如對(duì)字節(jié)進(jìn)行轉(zhuǎn)換)轉(zhuǎn)移到另一段內(nèi)存區(qū)域(目的地址)中的函數(shù),或者部分代碼片段實(shí)現(xiàn)了內(nèi)存拷貝功能的函數(shù).

      2)函數(shù)控制流圖(control flow graph,CFG).函數(shù)方法內(nèi)的程序執(zhí)行流的圖,是對(duì)函數(shù)的執(zhí)行流程進(jìn)行簡(jiǎn)化而得到,是為了突出函數(shù)的控制結(jié)構(gòu).本文以Gc表示程序的控制流圖,以V表示節(jié)點(diǎn)的集合,以E表示邊的集合.其中Gc=(V,E),V={v1,v2,…,vn},E={e1,e2,…,em}.需要注意的是CFG 圖是一個(gè)有向圖.通過(guò)對(duì)CFG 的遍歷來(lái)判斷其是否包含循環(huán)結(jié)構(gòu).

      3)循環(huán)路徑(loop path,LP).從圖中的一個(gè)節(jié)點(diǎn)出發(fā),沿著其相連接的邊進(jìn)行遍歷,若還能回到這個(gè)節(jié)點(diǎn),則該圖包含循環(huán)結(jié)構(gòu),其中從該節(jié)點(diǎn)出發(fā)又回到該節(jié)點(diǎn)的所有節(jié)點(diǎn)及其邊構(gòu)成了循環(huán)的路徑.對(duì)于CFG 來(lái)說(shuō),循環(huán)路徑更多關(guān)注的是其路徑上的節(jié)點(diǎn),即基本塊和基本塊內(nèi)的指令,該指令序列組成了函數(shù)的執(zhí)行流.

      4)數(shù)據(jù)流圖(data flow graph,DFG).是記錄程序中的數(shù)據(jù)在內(nèi)存或者寄存器間的傳播和轉(zhuǎn)移變化情況的圖.通過(guò)對(duì)變量或者內(nèi)存的數(shù)據(jù)流進(jìn)行跟蹤分析能夠判斷函數(shù)的行為.

      對(duì)二進(jìn)制程序中拷貝類函數(shù)識(shí)別的第1 步是二進(jìn)制函數(shù)邊界的識(shí)別,二進(jìn)制函數(shù)邊界識(shí)別的技術(shù)[23-24]已經(jīng)相對(duì)成熟,以及現(xiàn)有的IDA Pro 工具已經(jīng)滿足需要,這里不再贅述.

      2.2 拷貝類函數(shù)識(shí)別的重要性

      據(jù)本文研究發(fā)現(xiàn),C 語(yǔ)言庫(kù)中封裝的拷貝類函數(shù)并不能滿足所有開(kāi)發(fā)的需求,例如需要在內(nèi)存拷貝時(shí)對(duì)字節(jié)進(jìn)行處理或者轉(zhuǎn)換時(shí)無(wú)法再使用C 語(yǔ)言庫(kù)中的拷貝類函數(shù),開(kāi)發(fā)者只能自己開(kāi)發(fā)相應(yīng)功能的函數(shù)來(lái)滿足需求.此類拷貝類函數(shù)仍是安全研究需要關(guān)注的重點(diǎn),對(duì)此類函數(shù)的不正確使用仍會(huì)造成內(nèi)存錯(cuò)誤漏洞的產(chǎn)生.

      如圖1 所示,函數(shù)alps_lib_toupper在拷貝的時(shí)候?qū)⑺械男懽帜皋D(zhuǎn)換為大寫字母,開(kāi)發(fā)者調(diào)用此函數(shù)時(shí)缺乏對(duì)長(zhǎng)度的檢查,導(dǎo)致了漏洞CVE-2017-6736[25]的產(chǎn)生;另一個(gè)例子是MIPS 架構(gòu)下TP-Link WR940N 無(wú)線路由器中的一個(gè)棧溢出漏洞CVE-2017-13772[26],如 圖2 所 示,導(dǎo)致該 漏洞的 是函數(shù)ipAddrDispose中的一段負(fù)責(zé)內(nèi)存拷貝(地址轉(zhuǎn)換)的代碼,導(dǎo)致該漏洞產(chǎn)生的基本塊路徑是loc_478568,loc_478550,loc_478560,該循環(huán)在一定條件下從寄存器$a1 指向的內(nèi)存中取出1B 的數(shù)據(jù)存放到寄存器$v0 中,當(dāng)$v0 的值與$t0 的值不相等時(shí),將寄存器$v0 中的數(shù)據(jù)存放到0x1C($a2)指向的內(nèi)存中,由于缺少對(duì)長(zhǎng)度嚴(yán)格的檢查導(dǎo)致了漏洞的產(chǎn)生.

      Fig.1 Memory copy function implemented by developer圖1 開(kāi)發(fā)者實(shí)現(xiàn)的內(nèi)存拷貝類函數(shù)

      由此可見(jiàn),不僅對(duì)C 語(yǔ)言庫(kù)中拷貝類函數(shù)的錯(cuò)誤調(diào)用會(huì)導(dǎo)致內(nèi)存錯(cuò)誤漏洞,對(duì)開(kāi)發(fā)者自定義實(shí)現(xiàn)的拷貝類函數(shù)調(diào)用也存在產(chǎn)生內(nèi)存錯(cuò)誤漏洞的風(fēng)險(xiǎn).因此本文提出通過(guò)識(shí)別二進(jìn)制程序中的拷貝類函數(shù)對(duì)具備內(nèi)存拷貝功能的代碼片段進(jìn)行檢測(cè),以便為下游的分析任務(wù),例如污點(diǎn)分析、模糊測(cè)試等提供更多的支持,提高分析的準(zhǔn)確率和發(fā)現(xiàn)內(nèi)存錯(cuò)誤漏洞的可能性.

      2.3 拷貝類函數(shù)的特點(diǎn)

      本節(jié)將對(duì)拷貝類函數(shù)的特點(diǎn)、不同指令集下的變化以及檢測(cè)的難點(diǎn)進(jìn)行分析.

      Fig.2 Function for IP address conversion in the httpd service圖2 httpd 服務(wù)中IP 地址轉(zhuǎn)換的函數(shù)

      在C 程序開(kāi)發(fā)時(shí),一般情況下開(kāi)發(fā)者會(huì)直接調(diào)用庫(kù)中封裝好的內(nèi)存拷貝類函數(shù),如strcpy,memcpy等函數(shù).圖3 展示了C 語(yǔ)言下函數(shù)strcpy的源碼經(jīng)過(guò)編譯后的二進(jìn)制代碼.圖4 展示了MIPS 指令集下的函數(shù)strncpy.從源碼中可以看出,對(duì)于內(nèi)存中數(shù)據(jù)的轉(zhuǎn)移或者修改往往借助于while 或者for 循環(huán)進(jìn)行實(shí)現(xiàn),經(jīng)過(guò)編譯器編譯后在二進(jìn)制函數(shù)CFG 中的表現(xiàn)即為存在循環(huán)路徑.

      Fig.3 Implementation of strcpy function in C library圖3 C 語(yǔ)言庫(kù)中strcpy 函數(shù)的實(shí)現(xiàn)

      Fig.4 The strncpy function under the MIPS instruction set圖4 MIPS 指令集下的strncpy 函數(shù)

      然而并不是所有的內(nèi)存拷貝函數(shù)都存在循環(huán)路徑,如圖5 所示為x86 指令集下的函數(shù)memcpy,從圖中可以看出該函數(shù)不存在循環(huán)路徑,原因是x86 指令集下存在特殊的指令可以直接實(shí)現(xiàn)字節(jié)的連續(xù)轉(zhuǎn)移,如rep movsb,rep movsd 指令等,即由于x86 指令集下存在rep 指令可以完成重復(fù)的功能,借助此指令來(lái)完成內(nèi)存的拷貝.但由于其他指令集下,如ARM,MIPS,PPC 不存在這種特殊的指令,則需要借助循環(huán)來(lái)實(shí)現(xiàn)內(nèi)存的拷貝.此外,由于rep 只能實(shí)現(xiàn)無(wú)變化的數(shù)據(jù)拷貝,因此x86 指令下二進(jìn)制同樣存在基于循環(huán)實(shí)現(xiàn)的內(nèi)存拷貝類函數(shù).因此CFG 中存在循環(huán)路徑仍是拷貝類函數(shù)最大的特點(diǎn).內(nèi)存拷貝類函數(shù)一定存在對(duì)內(nèi)存的訪問(wèn),即對(duì)內(nèi)存進(jìn)行讀寫,因此在循環(huán)路徑中一定要存在對(duì)內(nèi)存的讀取和寫入指令,在反匯編代碼中即表現(xiàn)為存在內(nèi)存的加載和存儲(chǔ)的操作碼,例如在MIPS 指令下為lbu 和sb(如圖4 所示,在基本塊loc_415EC0 和基本塊loc_415EAC 中);在數(shù)據(jù)流的層面表現(xiàn)為,字節(jié)從內(nèi)存的一個(gè)區(qū)域流向了另一段內(nèi)存區(qū)域.以MIPS 下的函數(shù)strncpy為例,如圖4 所示,即字節(jié)從寄存器$a1 指向的內(nèi)存流向了寄存器$v1 指向的內(nèi)存中,此過(guò)程未對(duì)數(shù)據(jù)進(jìn)行修改.

      Fig.5 The memcpy function under the x86 instruction set圖5 x86 指令集下的memcpy 函數(shù)

      拷貝類函數(shù)的另一個(gè)特點(diǎn)就是存在偏移的更新,即需要對(duì)內(nèi)存地址進(jìn)行更新,以便將數(shù)據(jù)儲(chǔ)存到連續(xù)的內(nèi)存單元.以簡(jiǎn)單的拷貝類函數(shù)為例,如圖4 所示,即存在對(duì)寄存器$v1(addiu $v1,1)的更新.然而,自定義實(shí)現(xiàn)的拷貝類函數(shù)可能包含更多的復(fù)雜操作以及分支判斷,導(dǎo)致循環(huán)路徑上可能包含多個(gè)基本塊,并不是如圖4 中所示的那樣只有兩個(gè)基本塊,并且編譯器的優(yōu)化也對(duì)函數(shù)造成一定的影響,數(shù)據(jù)流會(huì)經(jīng)過(guò)多次的轉(zhuǎn)移變化,因此拷貝類函數(shù)并不是像BootStomp 以及SaTC 中所提的特征那么簡(jiǎn)單,對(duì)其的檢測(cè)需要更準(zhǔn)確的數(shù)據(jù)流特征.

      2.4 現(xiàn)有相關(guān)方法及其不足

      基于循環(huán)路徑的溢出漏洞檢測(cè)在二進(jìn)制程序分析中和源碼分析中都存在諸多的應(yīng)用,例如2012 年,Rawat 等人[27]提出檢測(cè)二進(jìn)制程序中由循環(huán)路徑導(dǎo)致的溢出漏洞(buffer overflow inducing loops,BOILs),實(shí)現(xiàn)了一個(gè)輕量級(jí)的靜態(tài)分析工具來(lái)檢測(cè)BOILs.然而此方法未對(duì)數(shù)據(jù)流進(jìn)行分析,僅依靠BOILs 的特征進(jìn)行檢測(cè),并且只支持x86 的二進(jìn)制程序.2020 年,Luo 等人[28]提出在源碼層面檢測(cè)由循環(huán)路徑導(dǎo)致的溢出漏洞,由于該方法針對(duì)的是源代碼,而二進(jìn)制程序丟失了源碼中較多的語(yǔ)義、變量類型、結(jié)構(gòu)體等信息,難度更大,該方法不適用于對(duì)二進(jìn)制程序的分析.

      隨著靜態(tài)污點(diǎn)分析技術(shù)和物聯(lián)網(wǎng)技術(shù)的發(fā)展,研究者開(kāi)始將靜態(tài)污點(diǎn)分析應(yīng)用到對(duì)固件的脆弱性檢測(cè)中,如Redini 等人先后在2017 年和2020 年分別提出BootStomp[8]和Karonte[9],使用靜態(tài)污點(diǎn)分析來(lái)檢測(cè)安卓手機(jī)中bootloader 的脆弱性和嵌入式設(shè)備系統(tǒng)中,如路由器、網(wǎng)絡(luò)攝像頭等由于多二進(jìn)制交互而產(chǎn)生的漏洞.如圖6 所示,Karonte 仍需要借助函數(shù)名的信息.2021 年,Chen 等人[14]提出使用靜態(tài)污點(diǎn)分析檢測(cè)嵌入式設(shè)備中與前端關(guān)鍵字關(guān)聯(lián)的漏洞技術(shù)SaTC,如圖7 所示,借助函數(shù)名信息對(duì)嵌入式設(shè)備的固件進(jìn)行靜態(tài)分析依賴于對(duì)拷貝類函數(shù)的識(shí)別.然而當(dāng)前的方法依賴于函數(shù)名等信息,并且僅僅通過(guò)簡(jiǎn)單的特征匹配模式進(jìn)行檢測(cè),存在較高的漏報(bào)率和誤報(bào)率.

      Fig.6 Static taint analysis in Karonte relies on function name information圖6 Karonte 中靜態(tài)污點(diǎn)分析依賴于函數(shù)名信息

      Fig.7 Static taint analysis in SaTC relies on function name information圖7 SaTC 中靜態(tài)污點(diǎn)分析依賴于函數(shù)名信息

      本文研究發(fā)現(xiàn),由于拷貝類函數(shù)多種多樣,僅僅依靠模式匹配很難識(shí)別出拷貝類函數(shù).因此本文在CFG 分析和模式匹配的基礎(chǔ)上,增加對(duì)函數(shù)的DFG的分析,通過(guò)對(duì)DFG 的分析來(lái)提高拷貝類函數(shù)識(shí)別的準(zhǔn)確率,降低誤報(bào)率和漏報(bào)率,并且為了支持多指令集架構(gòu),將不同指令的二進(jìn)制代碼轉(zhuǎn)換為VEX IR代碼進(jìn)行分析,使得該方法具有較高的適用性.

      2.5 VEX IR 中間語(yǔ)言

      由于IR 能夠保留指令的語(yǔ)義信息,具有出色的可拓展性,可以將不同指令集的代碼進(jìn)行歸一化,被廣泛應(yīng)用于跨指令集的程序分析[29-30].其中較為著名的是VEX IR,由于其支持的指令集架構(gòu)相對(duì)齊全,并且提供了Python 的API[31],被較多的二進(jìn)制分析工具angr[32],MockingBird[33],Binmatch[34]使用.為了能夠支持對(duì)多指令集架構(gòu)的二進(jìn)制程序進(jìn)行分析,本文選用VEX IR 作為中間語(yǔ)言對(duì)函數(shù)的數(shù)據(jù)流進(jìn)行分析.

      本節(jié)對(duì)VEX IR 的指令類型進(jìn)行了梳理,并給出了對(duì)應(yīng)的操作碼和示例,結(jié)果如表1 所示.將VEX IR指令分為8 種類型,分別為寄存器訪問(wèn)、內(nèi)存訪問(wèn)、算術(shù)運(yùn)算、邏輯運(yùn)算、移位運(yùn)算、轉(zhuǎn)換、函數(shù)調(diào)用以及其他指令.其中,寄存器訪問(wèn)指令是對(duì)寄存器的讀取和寫入,內(nèi)存訪問(wèn)指令是從內(nèi)存中加載數(shù)據(jù)和將數(shù)據(jù)存儲(chǔ)到內(nèi)存中;函數(shù)調(diào)用指令會(huì)修改pc寄存器的值,并給出一個(gè)關(guān)鍵字Ijk_Call;其他指令包括比較指令以及其他不常見(jiàn)的指令,如ITE(if-then-else).通過(guò)對(duì)VEX IR 指令的分析獲取變量間的數(shù)據(jù)流動(dòng).

      Table 1 Instruction Types and Examples of VEX IR表1 VEX IR 的指令類型及示例

      3 拷貝類函數(shù)識(shí)別

      拷貝類函數(shù)識(shí)別是給定一個(gè)二進(jìn)制函數(shù)(匯編代碼或二進(jìn)制代碼),在不借助符號(hào)表的情況下,通過(guò)靜態(tài)分析技術(shù)或者動(dòng)態(tài)分析技術(shù)來(lái)判斷該函數(shù)是否具有內(nèi)存拷貝的功能.二進(jìn)制程序中拷貝函數(shù)識(shí)別是給定一個(gè)含有n個(gè)函數(shù)的二進(jìn)制程序B(剝離或者保留函數(shù)名等信息),即B={f1,f2,…,fi,…,fn},其中fi為包含m個(gè)基本塊的二進(jìn)制函數(shù)(通常以函數(shù)的起始地址命名),fi={b1,b2,…,bj,…,bm},bi為函數(shù)fi的基本塊.用L={bk|bk∈fi∧k∈LP}表示參與循環(huán)的基本塊,其中k為基本塊編號(hào),LP為循環(huán)的路徑,由CFG 遍歷算法獲得保存著參與循環(huán)的基本塊的編號(hào).因此當(dāng)LP=? 時(shí),函數(shù)不為拷貝類函數(shù)(x86 指令集除外).對(duì)二進(jìn)制程序中每個(gè)函數(shù)進(jìn)行識(shí)別,判斷是否為拷貝類函數(shù),輸出該二進(jìn)制程序中對(duì)所有函數(shù)的識(shí)別結(jié)果.

      本文對(duì)具備拷貝類功能的函數(shù)研究發(fā)現(xiàn),具備拷貝功能的函數(shù)可能不單單完成一項(xiàng)任務(wù),即將數(shù)據(jù)從一段內(nèi)存區(qū)域轉(zhuǎn)移到另一段內(nèi)存區(qū)域,它可能具備更多其他的功能,例如數(shù)據(jù)轉(zhuǎn)移后的處理.因此可以將拷貝類函數(shù)分為粗粒度的拷貝類函數(shù)和細(xì)粒度的拷貝類函數(shù).細(xì)粒度的拷貝類函數(shù)只完成內(nèi)存拷貝的功能;粗粒度的拷貝類函數(shù)除了做內(nèi)存拷貝的功能外,還存在更多的功能.因此為減少待分析函數(shù)的數(shù)量,可以通過(guò)對(duì)函數(shù)的復(fù)雜程度進(jìn)行過(guò)濾,例如以基本塊的數(shù)量進(jìn)行過(guò)濾,通常情況下細(xì)粒度的拷貝類函數(shù)的基本塊數(shù)量小于50(這里閾值的設(shè)置根據(jù)對(duì)當(dāng)前的拷貝類函數(shù)分析所得,實(shí)際應(yīng)用中可以根據(jù)具體的后續(xù)任務(wù)需求設(shè)置閾值進(jìn)行過(guò)濾).

      4 拷貝類函數(shù)識(shí)別技術(shù)

      本節(jié)對(duì)二進(jìn)制程序中拷貝類函數(shù)識(shí)別技術(shù)進(jìn)行詳細(xì)介紹.二進(jìn)制程序中拷貝類函數(shù)識(shí)別技術(shù)CPYFinder 的流程如圖8 所示:

      Fig.8 Workflow of memory copy function identification圖8 內(nèi)存拷貝類函數(shù)識(shí)別的流程

      CPYFinder 總共分為6 個(gè)模塊:CFG 提取和循環(huán)檢測(cè)模塊、循環(huán)指令提取模塊、VEX IR 指令生成模塊、數(shù)據(jù)流構(gòu)建模塊、數(shù)據(jù)流分析模塊和拷貝類函數(shù)識(shí)別模塊.其中:CFG 提取和循環(huán)檢測(cè)模塊主要分析二進(jìn)制程序中是否包含循環(huán)路徑;循環(huán)指令提取模塊借助于IDA Pro 等逆向分析工具從二進(jìn)制程序中提取循環(huán)路徑上的指令;VEX IR 指令生成模塊借助于pyvex 工具將指令轉(zhuǎn)換為中間語(yǔ)言指令,方便系統(tǒng)支持對(duì)多種指令集架構(gòu)的程序進(jìn)行分析;數(shù)據(jù)流構(gòu)建和數(shù)據(jù)流分析模塊從VEX IR 指令提取變量間的數(shù)據(jù)關(guān)系,并對(duì)其進(jìn)行分析;拷貝類函數(shù)識(shí)別模塊依據(jù)拷貝類函數(shù)數(shù)據(jù)流的特點(diǎn)對(duì)函數(shù)循環(huán)路徑上的數(shù)據(jù)流進(jìn)行判斷.具體的拷貝類函數(shù)識(shí)別算法如算法1 所示.

      算法1.拷貝類函數(shù)識(shí)別算法.

      輸入:函數(shù)起始地址;

      輸出:函數(shù)是否為拷貝類函數(shù)(值為0 或1).

      4.1 函數(shù)控制流的生成及循環(huán)識(shí)別

      在第2 節(jié)中,本文對(duì)拷貝類函數(shù)的特點(diǎn)進(jìn)行了分析,除了x86 指令集下存在使用rep movsb 等實(shí)現(xiàn)內(nèi)存拷貝的特殊指令(x86 下需要添加對(duì)rep movsb 指令進(jìn)行檢測(cè)),在ARM,MIPS,PowerPC 指令集下拷貝類函數(shù)均需借助循環(huán)進(jìn)行內(nèi)存數(shù)據(jù)的轉(zhuǎn)移.因此,對(duì)循環(huán)的檢測(cè)是拷貝類函數(shù)識(shí)別的基礎(chǔ).CPYFinder首先對(duì)二進(jìn)制函數(shù)的CFG 進(jìn)行提取,以判斷函數(shù)執(zhí)行流中是否存在循環(huán),在非x86 指令集下,CFG 不包含循環(huán)則直接視為非拷貝類函數(shù).

      CFG 中保存著函數(shù)內(nèi)基本塊間的關(guān)系,通過(guò)對(duì)匯編指令的解析可以獲取基本塊之間的關(guān)系,IDA Pro提供了API 即函數(shù)FlowChart()來(lái)獲取二進(jìn)制函數(shù)的基本塊以及基本塊間的關(guān)系,因此本文直接借助IDA Pro 獲取基本塊間的關(guān)系.為了快速地生成圖以及對(duì)后續(xù)的處理,選擇使用networkx 庫(kù)[35](用于創(chuàng)建、操作和處理復(fù)雜網(wǎng)絡(luò)的Python 庫(kù)).通過(guò)將基本塊間的關(guān)系輸出到networkx 的創(chuàng)建圖的API 函數(shù)DiGraph()中,生成函數(shù)的CFG(算法1 行②和③).

      在獲得了函數(shù)的CFG 后,為進(jìn)一步判斷是否為拷貝類函數(shù),需要判斷CFG 是否包含循環(huán).由于判斷圖結(jié)構(gòu)中是否包含環(huán),以及對(duì)算法的效率的分析是圖論中研究的內(nèi)容,這里不再做探討.此外,判斷圖結(jié)構(gòu)中是否包含環(huán)的算法已經(jīng)十分成熟,這里將利用networkx 提供的函數(shù)simple_cycles()判斷CFG 是否包含循環(huán)路徑以及生成循環(huán)路徑,用于后續(xù)循環(huán)內(nèi)數(shù)據(jù)流的生成(算法1 行④).當(dāng)CFG 包含循環(huán)路徑時(shí),進(jìn)行后續(xù)的拷貝類函數(shù)的識(shí)別;當(dāng)CFG 中無(wú)循環(huán)路徑,并且該二進(jìn)制程序非x86 指令集,認(rèn)為此函數(shù)為非拷貝類函數(shù)(對(duì)于x86 指令集的函數(shù),如果指令中存在rep movsb 等指令,認(rèn)為是拷貝類函數(shù)).

      4.2 基于VEX IR 的數(shù)據(jù)流生成與分析

      L={bk|bk∈fi∧k∈LP}

      在獲取了循環(huán)路徑后,為了支持多指令集架構(gòu)并方便后續(xù)的處理,將基本塊的指令全部轉(zhuǎn)換為VEX IR 指令,然后對(duì)VEX IR 指令進(jìn)行過(guò)濾分析,構(gòu)建變量之間的數(shù)據(jù)關(guān)系(算法1 行⑥和⑦).如圖9 所示,為ARM 指令集下二進(jìn)制字節(jié)碼E5 F1 E0 01 生成的匯編代碼(圖9 行1)和VEX IR代碼(圖9 行3~10).CPYFinder 依據(jù)表1 中指令的類型,使用正則表達(dá)式對(duì)指令的變量進(jìn)行提取,將指令中的變量分為目的和源,即(dst,src),其中由于存在指令對(duì)多個(gè)變量進(jìn)行操作,例如Add 操作,因此,源操作數(shù)src又記錄為(src1,src2),然后根據(jù)指令的類型和特點(diǎn)對(duì)源變量和目的變量構(gòu)建數(shù)據(jù)流關(guān)系.在整個(gè)變量關(guān)系記錄過(guò)程中,只記錄變量之間的關(guān)系,不記錄常量.以圖9 的行4 為例說(shuō)明,數(shù)據(jù)流動(dòng)方向?yàn)閺膔1 到t18(VEX IR 的臨時(shí)變量以t開(kāi)頭),行5 數(shù)據(jù)流動(dòng)方向?yàn)閺膖18 流向了t17,不記錄常量0x00000001流向了t17,依次構(gòu)建所有的變量之間的關(guān)系.由于pc,eip等特殊的寄存器與拷貝類函數(shù)的判斷無(wú)關(guān),因此在進(jìn)行變量關(guān)系生成時(shí)會(huì)將此類的寄存器過(guò)濾掉,不做處理,圖9 中變量的關(guān)系記錄為{(t18,r1),(t17,t18),(t20,t17),(t38,t20),(lr,t38),(r1,t17)}.

      Fig.9 Assembly code and VEX IR code圖9 匯編代碼和VEX IR 代碼

      在對(duì)所有的VEX IR 代碼遍歷的同時(shí)記錄直接參與內(nèi)存訪問(wèn)(加載指令點(diǎn)記錄為L(zhǎng)D點(diǎn),存儲(chǔ)指令點(diǎn)記錄為ST點(diǎn))和參與算術(shù)運(yùn)算的變量,例如圖9 中的行5 和行6,其中行5 為加運(yùn)算操作,行6 為從t17指向的內(nèi)存單元中加載數(shù)據(jù).在對(duì)所有的VEX IR 指令遍歷后,生成了所有變量之間的關(guān)系、內(nèi)存加載變量集合、內(nèi)存存儲(chǔ)變量集合、算術(shù)運(yùn)算變量集合.圖9中的所 有數(shù)據(jù) 為變量關(guān)系{(t18,r1),(t17,t18),(t20,t17),(t38,t20),(lr,t38),(r1,t17)}、內(nèi)存加 載集合 為[t20]、內(nèi)存存儲(chǔ)集合為 ?、算術(shù)運(yùn)算變量集合為[t17].由于圖9 中VEX IR 指令中無(wú)ST指令,因此內(nèi)存存儲(chǔ)集合為空.

      在獲取上述數(shù)據(jù)后,將所有變量之間的關(guān)系輸入到函數(shù)DiGraph()中構(gòu)建DFG.經(jīng)過(guò)大量的分析發(fā)現(xiàn),拷貝類函數(shù)的DFG 具有5 個(gè)特征:

      特征1.數(shù)據(jù)流圖上存在LD點(diǎn);

      特征2.數(shù)據(jù)流圖中存在ST點(diǎn);

      特征3.存在從LD點(diǎn)到ST點(diǎn)的路徑,并且LD點(diǎn)先于ST點(diǎn)出現(xiàn);

      特征4.數(shù)據(jù)流圖上存在環(huán)結(jié)構(gòu),并且環(huán)上存在算術(shù)運(yùn)算;

      特征5.環(huán)上的點(diǎn)能夠到達(dá)特征3 上的ST點(diǎn).

      基于5 個(gè)特征,對(duì)函數(shù)的循環(huán)內(nèi)的數(shù)據(jù)流進(jìn)行分析,數(shù)據(jù)流滿足5 個(gè)特征的函數(shù)被認(rèn)為是拷貝類函數(shù).這里以存在LD點(diǎn)和ST點(diǎn)(特征1 和特征2)的數(shù)據(jù)流圖為例進(jìn)行具體識(shí)別過(guò)程的描述.使用networkx的路徑通過(guò)函數(shù)all_simple_paths()來(lái)判斷DFG 中是否存在LD點(diǎn)到ST點(diǎn)的路徑(特征3),如果不存在該路徑,則認(rèn)為不滿足拷貝類函數(shù)數(shù)據(jù)流的特征.當(dāng)從LD點(diǎn)到ST點(diǎn)存在路徑時(shí),則進(jìn)一步判斷DFG 中是否存在環(huán)結(jié)構(gòu),并且環(huán)上節(jié)點(diǎn)的關(guān)系是否存在算術(shù)運(yùn)算(特征4),如果滿足特征4,就繼續(xù)判定環(huán)上的點(diǎn)能否到達(dá)滿足特征5 的ST點(diǎn),如果滿足上述所有特征,認(rèn)為此函數(shù)為拷貝類函數(shù).由于函數(shù)內(nèi)可能存在多條循環(huán)路徑,因此只要存在1 條循環(huán)路徑的DFG滿足5 個(gè)特征,則認(rèn)為此函數(shù)為拷貝類函數(shù).

      4.3 對(duì)特殊拷貝類函數(shù)的處理

      正如第2 節(jié)中的函數(shù)alps_lib_toupper存在函數(shù)在循環(huán)塊內(nèi)調(diào)用其他函數(shù)的情況,因此,本文認(rèn)為在內(nèi)存拷貝中調(diào)用了其他函數(shù)的函數(shù)為特殊拷貝類函數(shù).此類函數(shù)由于函數(shù)的調(diào)用會(huì)導(dǎo)致數(shù)據(jù)流的中斷,因此需要對(duì)變量間的數(shù)據(jù)流進(jìn)行連接,即在函數(shù)的參數(shù)與函數(shù)的返回寄存器之間建立數(shù)據(jù)流關(guān)系.當(dāng)發(fā)現(xiàn)循環(huán)中存在函數(shù)調(diào)用時(shí),對(duì)被調(diào)用函數(shù)的參數(shù)傳遞情況及返回值寄存器使用情況進(jìn)行分析;當(dāng)函數(shù)調(diào)用后存在返回值寄存器被使用的情況,則將被調(diào)用函數(shù)參數(shù)與返回值寄存器之間構(gòu)建數(shù)據(jù)流,當(dāng)前方法中是將函數(shù)的第2 個(gè)參數(shù)與函數(shù)返回值寄存器建立數(shù)據(jù)流.如果返回值寄存器未被使用,則直接在第2 個(gè)參數(shù)和第1 個(gè)參數(shù)間建立數(shù)據(jù)流關(guān)系(一般情況下,目的寄存器是第1 個(gè)參數(shù),源地址寄存器是第2 個(gè)參數(shù),返回值寄存器的值會(huì)指向目的寄存器).對(duì)于不同的指令集,其參數(shù)的傳遞方式和結(jié)果返回的方式(返回值寄存器)均不同,因此需要對(duì)各個(gè)指令集根據(jù)其參數(shù)傳遞方式的約定進(jìn)行數(shù)據(jù)流的連接,對(duì)于x86 指令集則根據(jù)其利用棧進(jìn)行參數(shù)傳遞的方式,追溯壓入棧的指令和變量,與返回值寄存器進(jìn)行連接;對(duì)于ARM,MIPS,PPC,由于都是首先使用寄存器進(jìn)行參數(shù)的傳遞,參數(shù)寄存器不足時(shí)采用棧進(jìn)行參數(shù)傳遞.研究發(fā)現(xiàn),通常情況下參數(shù)寄存器即可滿足此類拷貝類函數(shù)中的參數(shù)傳遞,因此,直接在參數(shù)寄存器之間和返回值寄存器之間或者參數(shù)寄存器之間建立數(shù)據(jù)流關(guān)系,以避免數(shù)據(jù)流的中斷,導(dǎo)致對(duì)特殊拷貝類函數(shù)的遺漏.

      5 實(shí)驗(yàn)評(píng)估

      本節(jié)從不同的角度利用CPYFinder 對(duì)拷貝類函數(shù)識(shí)別的效果進(jìn)行評(píng)估,并與現(xiàn)有方法BootStomp,Karonte,SaTC 進(jìn)行對(duì)比,包括對(duì)庫(kù)函數(shù)識(shí)別效果、自定義函數(shù)識(shí)別效果、多架構(gòu)的支持、受編譯器的影響和編譯優(yōu)化等級(jí)的影響、在實(shí)際的漏洞函數(shù)檢測(cè)中的效果以及識(shí)別的運(yùn)行效率等進(jìn)行評(píng)估.

      5.1 實(shí)驗(yàn)設(shè)置和數(shù)據(jù)集

      1)實(shí)驗(yàn)環(huán)境.實(shí)驗(yàn)所使用計(jì)算機(jī)的配置為Intel?CoreTM6-core、3.7 GHz i7-8700K CPU 和32 GB RAM.軟件為Python(版本為3.7.9)、pyvex(版本為9.0.6136)、networkx(版本為2.5)、IDA Pro(版本7.5)以及基 于buildroot 構(gòu)建的交叉編譯環(huán)境用于生成不同架構(gòu)的二進(jìn)制程序.

      2)對(duì)比方 法.BootStomp(Usenix17),Karonte(S&P20),SaTC(Usenix21)(由于Karonte 與SaTC 對(duì)拷貝類函數(shù)實(shí)現(xiàn)完全相同,本文只與SaTC 進(jìn)行對(duì)比),經(jīng)過(guò)分析發(fā)現(xiàn)由于SaTC 借助于工具angr 來(lái)識(shí)別函數(shù)的參數(shù)個(gè)數(shù),在識(shí)別過(guò)程中限制了參數(shù)的個(gè)數(shù)n即2≤n≤ 3,由于angr 對(duì)參數(shù)個(gè)數(shù)錯(cuò)誤的識(shí)別,導(dǎo)致很多拷貝類函數(shù)被過(guò)濾掉,例如函數(shù)strcpy實(shí)際上存在2 個(gè)參數(shù),而angr 識(shí)別出來(lái)的參數(shù)個(gè)數(shù)為4,因此,本文對(duì)SaTC進(jìn)行修改后,取消其對(duì)參數(shù)個(gè)數(shù)限制的方法為SaTC+.

      3)工具實(shí)現(xiàn).CPYFinder 基于IDAPython 和pyvex進(jìn)行實(shí)現(xiàn),并借助于network 對(duì)CFG 和DFG 進(jìn)行處理.表2 展示各個(gè)方法實(shí)現(xiàn)主要依賴的工具和支持的指令集.

      Table 2 Comparison of Existing Methods and CPYFinder表2 現(xiàn)有方法與CPYFinder 對(duì)比

      4)數(shù)據(jù)集.本文首先對(duì)C 語(yǔ)言庫(kù)中的拷貝類函數(shù)進(jìn)行分析,根據(jù)其應(yīng)用程序編程接口(application programming interface,API)編寫一個(gè)主程序來(lái)調(diào)用所有string.h 和wchar.h 中的函數(shù)拷貝類函數(shù),如表3 所示,列出了C 語(yǔ)言庫(kù)中的拷貝類函數(shù),其中string.h 為普通拷貝類函數(shù),wchar.h 為寬字符拷貝類函數(shù),用于測(cè)試不同工具的效果.此外為驗(yàn)證對(duì)用戶自定義實(shí)現(xiàn)(非C 語(yǔ)言庫(kù)中)的拷貝類函數(shù)的識(shí)別效果,本文從Github(Netgear R7000 路由器代碼[36]以 及Mirai 代 碼[37])上搜集了22 個(gè)此類的函數(shù),整合到一個(gè)C 程序中進(jìn)行編譯測(cè)試.

      Table 3 Memory Copy Functions Used in the Experiment表3 實(shí)驗(yàn)中使用的內(nèi)存拷貝類函數(shù)

      5)評(píng)估標(biāo)準(zhǔn).本文使用精準(zhǔn)率(precision,P),以及召回率(recall,R)來(lái)評(píng)估本文所提方法的效果,精準(zhǔn)率和召回率越高效果越好.

      TP為將拷貝類函數(shù)識(shí)別為拷貝類函數(shù)的數(shù)量 ;FP為將非拷貝類函數(shù)識(shí)別為拷貝類函數(shù)的數(shù)量 ;FN為將拷貝類函數(shù)識(shí)別為非拷貝類函數(shù)的數(shù)量.

      6)編譯器以及優(yōu)化等級(jí).如表4 所示為實(shí)驗(yàn)評(píng)估中使用的編譯器、編譯器類型及優(yōu)化選項(xiàng),使用GCC 和Clang 這2 個(gè)編譯 器進(jìn)行測(cè)試,并使用buildroot 構(gòu)建了不同指令集的交叉工具鏈,用于生成不同目標(biāo)架構(gòu)的程序(在當(dāng)前的Clang 編譯器中,O3優(yōu)化等級(jí)與O4 優(yōu)化等級(jí)仍相同).

      Table 4 Compilers Used in the Evaluation Experiments表4 評(píng)估實(shí)驗(yàn)中所使用的編譯器

      5.2 實(shí)驗(yàn)結(jié)果

      5.2.1 對(duì)C 語(yǔ)言庫(kù)中拷貝類函數(shù)的識(shí)別效果

      為了驗(yàn)證對(duì)C 語(yǔ)言庫(kù)中拷貝類函數(shù)的識(shí)別效果,本文編寫C 代碼,調(diào)用string.h 和wchar.h 庫(kù)中的函數(shù)來(lái)編譯成不同的二進(jìn)制程序(由于BootStomp 只支持ARM 指令),這里使用靜態(tài)方法將源代碼編譯成ARM 架構(gòu)的二進(jìn)制程序,使用的編譯器版本為4.5.4,4.6.4,4.7.4,4.8.5,優(yōu)化等級(jí)為O0,此外由于5.0 以上版本的GCC 使用的libc 庫(kù)在拷貝類函數(shù)的實(shí)現(xiàn),不同的拷貝類函數(shù)會(huì)調(diào)用同一個(gè)函數(shù),導(dǎo)致拷貝類函數(shù)的種類下降,例如strcpy,strncpy的拷貝功能的實(shí)現(xiàn)是直接調(diào)用函數(shù)memcpy進(jìn)行的,這些函數(shù)本身不存在拷貝類函數(shù)的特點(diǎn),只是函數(shù)memcpy的封裝,因此這里未使用高版本的編譯器.各個(gè)方法的識(shí)別效果如表5 所示,從表5 中可以看出,CPYFinder 的效果優(yōu)于其他3 種方法,即BootStomp,SaTC 和SaTC+.盡管BootStomp 具有較高的精準(zhǔn)率P,但是召回率R卻不高于0.5,盡管SaTC+識(shí)別效果好于SaTC(后續(xù)實(shí)驗(yàn)只與SaTC+進(jìn)行對(duì)比),但是仍低于BootStomp 和CPYFinder,而在實(shí)際分析中,為避免遺漏關(guān)鍵函數(shù),應(yīng)該在保證召回率的情況下提高精準(zhǔn)率.分析發(fā)現(xiàn),誤報(bào)的函數(shù)來(lái)源于編譯器的靜態(tài)編譯會(huì)引入其他的函數(shù),例如__do_global_dtors_aux,__getdents函數(shù),由于靜態(tài)分析數(shù)據(jù)流的準(zhǔn)確性有限,導(dǎo)致誤報(bào)的產(chǎn)生.此外,CPYFinder 在gcc-4.7.4-0 上的識(shí)別效果最好,精準(zhǔn)率到達(dá)了0.81,召回率為1.0.

      從表5 中可以看出編譯器版本對(duì)拷貝類函數(shù)識(shí)別存在一定的影響.總的來(lái)說(shuō),對(duì)C 語(yǔ)言庫(kù)中拷貝類函數(shù)的識(shí)別,CPYFinder 優(yōu)于BootStomp,SaTC 和SaTC+.

      Table 5 Comparison of Methods for Identifying Memory Copy Functions in C Libraries表5 各方法對(duì)C 語(yǔ)言庫(kù)中內(nèi)存拷貝函數(shù)識(shí)別對(duì)比

      5.2.2 用戶自定義的拷貝類函數(shù)的識(shí)別效果

      為了測(cè)試用戶自定義實(shí)現(xiàn)的拷貝類函數(shù)的識(shí)別效果,正如5.1 節(jié)中介紹,本文從開(kāi)源庫(kù)中收集了相關(guān)的用戶自定義實(shí)現(xiàn)的拷貝類函數(shù),使用不同的編譯器編譯成ARM 程序進(jìn)行測(cè)試,測(cè)試結(jié)果如表6 所示.從表6 中可以看出,BootStomp 雖然對(duì)庫(kù)函數(shù)中拷貝類函數(shù)識(shí)別效果好于SaTC+,但是對(duì)自定義實(shí)現(xiàn)的拷貝類函數(shù)識(shí)別效果較差,雖然其準(zhǔn)確率幾乎為1,但是召回率幾乎為0.從表6 中準(zhǔn)確率和召回率得出結(jié)論:CPYFinder 對(duì)自定義拷貝類函數(shù)識(shí)別的效果好于BootStomp 和SaTC+,并且隨著編譯器版本的升級(jí),識(shí)別效果越好.

      Table 6 Comparison of Methods on the Identification of Custom Memory Copy Functions表6 各方法對(duì)自定義內(nèi)存拷貝類函數(shù)識(shí)別對(duì)比

      5.2.3 不同指令集及優(yōu)化等級(jí)下的識(shí)別效果

      為了展示CPYFinder 對(duì)不同架構(gòu)的拷貝類函數(shù)識(shí)別效果以及受優(yōu)化等級(jí)的影響,本文將源碼使用GCC 編譯器版本5.4.0 編譯成4 種架構(gòu)的程序(x86,ARM,MIPS,PPC)以及不同的優(yōu)化等級(jí)(O0~O3).由于BootStomp 和SaTC 不完全支持上述指令集架構(gòu),因此不再測(cè)試BootStomp 和SaTC 受指令集架構(gòu)的影響,首先測(cè)試CPYFinder 受指令集架構(gòu)和優(yōu)化等級(jí)的影響,然后在ARM 架構(gòu)的程序上測(cè)試BootStomp,SaTC 和CPYFinder 受優(yōu)化等級(jí)的影響.從表7 中可以看出,CPYFinder 支持x86,ARM,MIPS,PPC 指令集架構(gòu)的二進(jìn)制程序,并且識(shí)別的精準(zhǔn)率和召回率幾乎相同.此外,CPYFinder 會(huì)受編譯優(yōu)化等級(jí)的影響,在無(wú)優(yōu)化(O0 等級(jí))下識(shí)別的效果最好,隨著編譯優(yōu)化等級(jí)的提升,召回率和精準(zhǔn)率均會(huì)略微下降.從表8中可以看出,除了BootStomp 在O1 優(yōu)化下表現(xiàn)較好,SaTC 和CPYFinder 均是在O0 下表現(xiàn)較好.

      5.2.4 不同編譯器下拷貝類函數(shù)的識(shí)別效果

      為了展示不同方法受編譯器種類以及優(yōu)化等級(jí)的影響,本文將使用不同源碼版本的GCC 和Clang編譯器以O(shè)1 優(yōu)化等級(jí)將源碼編譯成ARM 架構(gòu)的二進(jìn)制程序,各個(gè)方法識(shí)別的效果如表9 所示.

      從識(shí)別的結(jié)果來(lái)看,BootStomp 識(shí)別的精準(zhǔn)率為1,但是召回率卻極低;而SaTC+識(shí)別的精準(zhǔn)率和召回率均低于CPYFinder.此外,3 種方法識(shí)別的效果均顯示對(duì)Clang 編譯的程序識(shí)別效果更好.因此,從表9 數(shù)據(jù)可得出結(jié)論:CPYFinder 識(shí)別效果好于BootStomp和SaTC+,并且對(duì)Clang 編譯的程序的識(shí)別效果優(yōu)于由GCC 編譯生成的程序.

      Table 7 Effect of Different Instruction Sets and Optimization Levels on the Identification表7 不同指令集及優(yōu)化等級(jí)對(duì)識(shí)別的影響

      Table 8 Effect of Optimization Level on the Identification of Each Method表8 優(yōu)化等級(jí)對(duì)各個(gè)方法識(shí)別的影響

      Table 9 Comparison of the Identification Effect of Each Method Under Different Compilers表9 不同編譯器下各方法的識(shí)別效果對(duì)比

      此外,本文還測(cè)試了Clang 編譯下,不同版本(3.9.1,6.0.1)以及不同優(yōu)化等級(jí)(O0~O4)對(duì)拷貝類函數(shù)識(shí)別效果的影響,對(duì)比結(jié)果如表10 所示.從表10中可以看出,BootStomp 和CPYFinder 受Clang 優(yōu)化等級(jí)的影響均較少,并且在版本較高(6.0.1 版本)的編譯器下,識(shí)別效果更好;而SaTC+受編譯優(yōu)化等級(jí)的影響較大,隨著編譯優(yōu)化等級(jí)的升高,其識(shí)別效果逐漸下降.此外,BootStomp 和SaTC+存在精準(zhǔn)率P和召回率R均為0 的情況.在Clang 編譯的ARM 程序下,CPYFinder識(shí)別的效果好于BootStomp 和SaTC+的識(shí)別效果.

      Table 10 Effect of Clang Compiler on the Identification of Memory Copy Function表10 Clang 編譯器對(duì)內(nèi)存拷貝類函數(shù)識(shí)別的影響

      5.2.5 固件中已知漏洞函數(shù)的檢測(cè)

      為了測(cè)試CPYFinder 在實(shí)際固件中拷貝類函數(shù)識(shí)別的效果,本文收集了近5 年來(lái)公開(kāi)分析的路由器設(shè)備固件中的漏洞,其中多數(shù)與函數(shù)strcpy相關(guān),由于函數(shù)strcpy作為導(dǎo)入函數(shù)調(diào)用,無(wú)法對(duì)其進(jìn)行識(shí)別,不符合實(shí)驗(yàn)的要求,因此,最終篩選出由循環(huán)拷貝導(dǎo)致的溢出漏洞,共獲得了5 個(gè)CVE,如表11 所示.這5 個(gè)漏洞分別發(fā)現(xiàn)于TP-Link 和D-Link 的路由器設(shè)備固件中,總共4 個(gè)固件(其中CVE-2018-3950和CVE-2018-3951 由同一個(gè)程序中的不同函數(shù)導(dǎo)致),這4 個(gè)固件均是MIPS 指令集架構(gòu)的二進(jìn)制程序,并且均是在由循環(huán)實(shí)現(xiàn)的內(nèi)存拷貝中由于對(duì)長(zhǎng)度未進(jìn)行校驗(yàn)導(dǎo)致的棧溢出漏洞,并且循環(huán)路徑中包含多個(gè)基本塊.對(duì)這5 個(gè)導(dǎo)致棧溢出漏洞的函數(shù)進(jìn)行識(shí)別測(cè)試,判斷BootStomp,SaTC+,CPYFinder 是否能夠識(shí)別出這5 個(gè)函數(shù)為拷貝類函數(shù),即是否存在內(nèi)存拷貝的代碼片段.

      Table 11 Identification Results for Overflow Vulnerabilities Caused by Loop Copy表11 對(duì)由循環(huán)拷貝導(dǎo)致的溢出漏洞的識(shí)別結(jié)果

      測(cè)試結(jié)果如表11 所示,BootStomp 由于不支持MIPS 架構(gòu)的二進(jìn)制程序的識(shí)別,給出的結(jié)果全為*,SaTC+未識(shí)別出這5 個(gè)函數(shù),其中在包含CVE-2018-3950 和CVE-2018-3951 的程序中運(yùn)行時(shí)直接崩潰,未給出結(jié)果.而CPYFinder 識(shí)別出4 個(gè)溢出漏洞,其中導(dǎo)致CVE-2018-11013 的漏洞函數(shù)未檢測(cè)出,導(dǎo)致CVE-2018-11013 的函數(shù)未檢測(cè)出的原因如圖10 所示.經(jīng)過(guò)分析發(fā)現(xiàn),由于該循環(huán)內(nèi)首先對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ)(基本塊loc_41EB04 中第1 條指令sb v1,0x40(v1,0x40(v0)),然后進(jìn)行數(shù)據(jù)的加載(基本塊loc_41EB04中第3 條指令lbu v1,0(v1,0(a0)),這與4.2 節(jié)設(shè)定的數(shù)據(jù)流的特征3 沖突,導(dǎo)致對(duì)函數(shù)websRedirect識(shí)別為非拷貝類函數(shù),在關(guān)閉特征3 的限制后,CPYFinder能夠識(shí)別出該CVE,但是隨之CPYFinder 的識(shí)別精準(zhǔn)率會(huì)下降,誤報(bào)率會(huì)增加,在實(shí)際的固件程序分析中,可以根據(jù)需要來(lái)決定是否開(kāi)啟特征3 的限制.

      綜上所述,基于控制流和數(shù)據(jù)流的CPYFinder 在實(shí)際的漏洞函數(shù)發(fā)現(xiàn)上,效果遠(yuǎn)遠(yuǎn)好于基于特征匹配的BootStomp 和SaTC+.

      5.2.6 效率分析

      本節(jié)對(duì)BootStomp,SaTC,SaTC+,CPYFinder 在拷貝類函數(shù)識(shí)別中的效率進(jìn)行分析,選取的程序?yàn)?.2.1 節(jié)中測(cè)試的程序,各個(gè)方法時(shí)耗的對(duì)比結(jié)果如表12 所示,CPYFinder 的效率遠(yuǎn)遠(yuǎn)高于BootStomp 和SaTC.由于不再對(duì)函數(shù)參數(shù)個(gè)數(shù)進(jìn)行分析,SaTC+的時(shí)耗低于SaTC.因此,CPYFinder 在較高的精準(zhǔn)率P和較高的召回率R情況下仍具有較低的時(shí)耗.其中CPYFinder 只用了相當(dāng)于BootStomp 19%的時(shí)間,與SaTC 和SaTC+的耗時(shí)相當(dāng).盡管CPYFinder 對(duì)數(shù)據(jù)流進(jìn)行了分析,然而由于SaTC 是基于angr 開(kāi)發(fā)的,angr在分析二進(jìn)制程序時(shí)的效率較低,因此CPYFinder 借助于IDA Pro 盡管增加了數(shù)據(jù)流分析但整個(gè)耗時(shí)卻幾乎未增加,而B(niǎo)ootStomp 借助了IDA Pro 的反編譯引擎,由于反編譯分析耗時(shí)較久,因此BootStomp 的耗時(shí)較高.

      Fig.10 Vulnerable functions not identified by CPYFinder圖10 CPYFinder 未識(shí)別出的漏洞函數(shù)

      Table 12 Comparison of Time Consumption for Memory Copy Functions Identification表12 對(duì)內(nèi)存拷貝類函數(shù)識(shí)別時(shí)耗對(duì)比

      6 CPYFinder 與IDAPro 集成

      為方便對(duì)工具的使用,本文將CPYFinder 以IDA插件的形式與IDA Pro 進(jìn)行了集成,并實(shí)現(xiàn)可視化的結(jié)果輸出;支持對(duì)單個(gè)函數(shù)的識(shí)別和整個(gè)二進(jìn)制程序中所有函數(shù)的識(shí)別,將識(shí)別分為single 和all 這2種識(shí)別模式,其中single 模式識(shí)別當(dāng)前光標(biāo)指向的地址所在的函數(shù)是否為拷貝類函數(shù),如圖11 所示.single 模式的輸出如圖12 所示.對(duì)整個(gè)二進(jìn)制程序的識(shí)別結(jié)果可視化界面如圖13 所示,該界面共分為5 個(gè)部分,其中Line 為檢測(cè)時(shí)的序號(hào)、Local Address展示函數(shù)的地址、Local Name 展示函數(shù)名、Loop Address 展示發(fā)現(xiàn)的拷貝函數(shù)的循環(huán)地址入口以及Is Copy Function 展示該函數(shù)是否為拷貝類函數(shù)(是為1,不是為0).借助于IDA Pro 的跳轉(zhuǎn)功能,能夠方便后續(xù)手工分析對(duì)結(jié)果的確認(rèn).

      Fig.11 The interface that CPYFinder provides to the user for mode selection.圖11 CPYFinder 提供給用戶模式選擇的界面

      Fig.12 Output of CPYFinder in single function mode圖12 CPYFinder 的單函數(shù)模式single 下的輸出

      Fig.13 Visualization results of CPYFinder’s all-mode in IDA Pro圖13 CPYFinder 的all 模式在IDA Pro 中的可視化結(jié)果

      7 討論

      本文提出的拷貝類函數(shù)識(shí)別技術(shù)CPYFinder 通過(guò)將二進(jìn)制函數(shù)轉(zhuǎn)換成中間語(yǔ)言VEX IR 進(jìn)行數(shù)據(jù)流的分析,支持對(duì)多指令集架構(gòu)(x86,ARM,MIPS,PPC)的二進(jìn)制程序中拷貝類函數(shù)的識(shí)別,不依賴于符號(hào)表等信息,并且受編譯器版本、優(yōu)化等級(jí)的影響較小.此外,CPYFinder 不僅能夠識(shí)別庫(kù)函數(shù)中的內(nèi)存拷貝類函數(shù),還能識(shí)別用戶自定義的內(nèi)存拷貝類函數(shù),具有較高的適用性.雖然基于靜態(tài)分析的識(shí)別方法具有快速、高效的特點(diǎn),但是由于靜態(tài)數(shù)據(jù)流分析很難做到十分精確,并且由于用戶自定義實(shí)現(xiàn)的拷貝類函數(shù)多樣以及受編譯器和優(yōu)化等級(jí)的影響,無(wú)可避免地會(huì)存在一定的誤報(bào)和漏報(bào),所以在識(shí)別的準(zhǔn)確率上具有一定局限性.在后續(xù)的研究中,嘗試將動(dòng)態(tài)執(zhí)行以及動(dòng)靜態(tài)分析結(jié)合的方式應(yīng)用到拷貝類函數(shù)的識(shí)別中,提高對(duì)拷貝類函數(shù)識(shí)別的準(zhǔn)確率.

      8 結(jié)束語(yǔ)

      拷貝類函數(shù)的識(shí)別對(duì)內(nèi)存錯(cuò)誤漏洞的檢測(cè)具有重大價(jià)值,能夠提升下游分析任務(wù)的能力,如污點(diǎn)分析、符號(hào)執(zhí)行等.本文提出了一種基于控制流和數(shù)據(jù)流分析的拷貝類函數(shù)識(shí)別技術(shù)CPYFinder,通過(guò)將二進(jìn)制程序轉(zhuǎn)換為中間語(yǔ)言VEX IR,進(jìn)行后續(xù)的數(shù)據(jù)流分析,提高了對(duì)拷貝類函數(shù)識(shí)別的精準(zhǔn)率和召回率,使得CPYFinder 具有較高的適用性,并且具有較低的運(yùn)行耗時(shí),支持多種指令集架構(gòu)(x86,ARM,MIPS,PPC).實(shí)驗(yàn)結(jié)果表明,CPYFinder 不僅能夠有效地識(shí)別出C 語(yǔ)言庫(kù)中的拷貝類函數(shù),還能夠識(shí)別用戶自定義實(shí)現(xiàn)的拷貝類函數(shù),并且受編譯器版本、編譯優(yōu)化等級(jí)的影響較小,能夠發(fā)現(xiàn)路由器固件中由此類函數(shù)導(dǎo)致的溢出漏洞,這對(duì)內(nèi)存錯(cuò)誤類漏洞的發(fā)現(xiàn)和分析具有重要作用.

      作者貢獻(xiàn)聲明:尹小康負(fù)責(zé)算法和對(duì)比實(shí)驗(yàn)的設(shè)計(jì)、算法的實(shí)現(xiàn)、初稿撰寫和修改;蘆斌完成算法和對(duì)比實(shí)驗(yàn)可行性分析、論文的審閱;蔡瑞杰負(fù)責(zé)實(shí)驗(yàn)結(jié)果分析、論文的修改;朱肖雅協(xié)助實(shí)驗(yàn)數(shù)據(jù)收集、論文的修改;楊啟超負(fù)責(zé)論文的審閱、修改和完善;劉勝利提出研究問(wèn)題、負(fù)責(zé)算法和實(shí)驗(yàn)的可行性分析、論文的審閱和修改.

      猜你喜歡
      指令集拷貝二進(jìn)制
      用二進(jìn)制解一道高中數(shù)學(xué)聯(lián)賽數(shù)論題
      3DNow指令集被Linux淘汰
      有趣的進(jìn)度
      二進(jìn)制在競(jìng)賽題中的應(yīng)用
      中國(guó)生殖健康(2018年1期)2018-11-06 07:14:38
      實(shí)時(shí)微測(cè)量系統(tǒng)指令集及解析算法
      什么是AMD64
      基于覆蓋率驅(qū)動(dòng)的高性能DSP指令集驗(yàn)證方法
      一個(gè)生成組合的新算法
      文件拷貝誰(shuí)最“給力”
      基隆市| 富民县| 托里县| 台中县| 正定县| 罗城| 阜康市| 小金县| 沾化县| 鄂托克前旗| 濮阳县| 竹山县| 肥东县| 盈江县| 阳谷县| 广德县| 启东市| 漯河市| 河东区| 乡宁县| 青浦区| 尼玛县| 茶陵县| 朝阳市| 普兰店市| 尚义县| 南通市| 玉林市| 东城区| 张家口市| 阳新县| 上栗县| 阿巴嘎旗| 邻水| 新疆| 镇沅| 尼勒克县| 惠州市| 准格尔旗| 九寨沟县| 故城县|