亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

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

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

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

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

        利用漏洞發(fā)起網(wǎng)絡(luò)攻擊仍是當(dāng)前網(wǎng)絡(luò)攻擊中的主要方式.漏洞攻擊能夠使目標(biāo)設(shè)備癱瘓、實(shí)現(xiàn)對目標(biāo)設(shè)備的突破控制,或者對重要文件的竊取.在利用漏洞發(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í)候缺少對長度的檢查,或者對特殊的字節(jié)進(jìn)行轉(zhuǎn)換時(shí)發(fā)生長度的變化,都會導(dǎo)致對內(nèi)存的越界寫或者越界讀[5].因此內(nèi)存拷貝類函數(shù)(下文簡稱拷貝類函數(shù))的識別對內(nèi)存錯(cuò)誤漏洞的發(fā)現(xiàn)和修補(bǔ)具有重大意義和價(jià)值.

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

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

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

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

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

        1 相關(guān)工作

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

        此外,當(dāng)前的研究中還存在一個(gè)被忽視的問題:開發(fā)者在開發(fā)程序時(shí)會自定義實(shí)現(xiàn)類似于內(nèi)存拷貝功能的函數(shù),進(jìn)而會引入內(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]考慮到了對拷貝類函數(shù)的識別,但是它們的識別方法依據(jù)簡單的代碼特征:1)從內(nèi)存中加載數(shù)據(jù);2)存儲數(shù)據(jù)到內(nèi)存中;3)增加1 個(gè)單元(字節(jié)byte、字word 等)的偏移值.然而滿足上述3 個(gè)特征的函數(shù)并不一定具有拷貝數(shù)據(jù)的功能,而且會遺漏用戶自定義實(shí)現(xiàn)的拷貝類函數(shù),因此具有較高的誤報(bào)率和漏報(bào)率.

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

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

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

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

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

        2.1 相關(guān)概念

        1)內(nèi)存拷貝類函數(shù)(memory copy function)[8].將數(shù)據(jù)從內(nèi)存中的一段區(qū)域(源地址)直接或者經(jīng)過處理(例如對字節(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í)行流的圖,是對函數(shù)的執(zhí)行流程進(jìn)行簡化而得到,是為了突出函數(shù)的控制結(jié)構(gòu).本文以Gc表示程序的控制流圖,以V表示節(jié)點(diǎn)的集合,以E表示邊的集合.其中Gc=(V,E),V={v1,v2,…,vn},E={e1,e2,…,em}.需要注意的是CFG 圖是一個(gè)有向圖.通過對CFG 的遍歷來判斷其是否包含循環(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)的路徑.對于CFG 來說,循環(huán)路徑更多關(guān)注的是其路徑上的節(jié)點(diǎn),即基本塊和基本塊內(nèi)的指令,該指令序列組成了函數(shù)的執(zhí)行流.

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

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

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

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

        如圖1 所示,函數(shù)alps_lib_toupper在拷貝的時(shí)候?qū)⑺械男懽帜皋D(zhuǎn)換為大寫字母,開發(fā)者調(diào)用此函數(shù)時(shí)缺乏對長度的檢查,導(dǎo)致了漏洞CVE-2017-6736[25]的產(chǎn)生;另一個(gè)例子是MIPS 架構(gòu)下TP-Link WR940N 無線路由器中的一個(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)存中,由于缺少對長度嚴(yán)格的檢查導(dǎo)致了漏洞的產(chǎn)生.

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

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

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

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

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

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

        Fig.3 Implementation of strcpy function in C library圖3 C 語言庫中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ù)的功能,借助此指令來完成內(nèi)存的拷貝.但由于其他指令集下,如ARM,MIPS,PPC 不存在這種特殊的指令,則需要借助循環(huán)來實(shí)現(xiàn)內(nèi)存的拷貝.此外,由于rep 只能實(shí)現(xiàn)無變化的數(shù)據(jù)拷貝,因此x86 指令下二進(jìn)制同樣存在基于循環(huán)實(shí)現(xiàn)的內(nèi)存拷貝類函數(shù).因此CFG 中存在循環(huán)路徑仍是拷貝類函數(shù)最大的特點(diǎn).內(nèi)存拷貝類函數(shù)一定存在對內(nèi)存的訪問,即對內(nèi)存進(jìn)行讀寫,因此在循環(huán)路徑中一定要存在對內(nèi)存的讀取和寫入指令,在反匯編代碼中即表現(xiàn)為存在內(nèi)存的加載和存儲的操作碼,例如在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)存中,此過程未對數(shù)據(jù)進(jìn)行修改.

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

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

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

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

        隨著靜態(tài)污點(diǎn)分析技術(shù)和物聯(lián)網(wǎng)技術(shù)的發(fā)展,研究者開始將靜態(tài)污點(diǎn)分析應(yīng)用到對固件的脆弱性檢測中,如Redini 等人先后在2017 年和2020 年分別提出BootStomp[8]和Karonte[9],使用靜態(tài)污點(diǎn)分析來檢測安卓手機(jī)中bootloader 的脆弱性和嵌入式設(shè)備系統(tǒng)中,如路由器、網(wǎng)絡(luò)攝像頭等由于多二進(jìn)制交互而產(chǎn)生的漏洞.如圖6 所示,Karonte 仍需要借助函數(shù)名的信息.2021 年,Chen 等人[14]提出使用靜態(tài)污點(diǎn)分析檢測嵌入式設(shè)備中與前端關(guān)鍵字關(guān)聯(lián)的漏洞技術(shù)SaTC,如圖7 所示,借助函數(shù)名信息對嵌入式設(shè)備的固件進(jìn)行靜態(tài)分析依賴于對拷貝類函數(shù)的識別.然而當(dāng)前的方法依賴于函數(shù)名等信息,并且僅僅通過簡單的特征匹配模式進(jìn)行檢測,存在較高的漏報(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ù).因此本文在CFG 分析和模式匹配的基礎(chǔ)上,增加對函數(shù)的DFG的分析,通過對DFG 的分析來提高拷貝類函數(shù)識別的準(zhǔn)確率,降低誤報(bào)率和漏報(bào)率,并且為了支持多指令集架構(gòu),將不同指令的二進(jìn)制代碼轉(zhuǎn)換為VEX IR代碼進(jìn)行分析,使得該方法具有較高的適用性.

        2.5 VEX IR 中間語言

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

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

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

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

        拷貝類函數(shù)識別是給定一個(gè)二進(jìn)制函數(shù)(匯編代碼或二進(jìn)制代碼),在不借助符號表的情況下,通過靜態(tài)分析技術(shù)或者動(dòng)態(tài)分析技術(shù)來判斷該函數(shù)是否具有內(nèi)存拷貝的功能.二進(jìn)制程序中拷貝函數(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為基本塊編號,LP為循環(huán)的路徑,由CFG 遍歷算法獲得保存著參與循環(huán)的基本塊的編號.因此當(dāng)LP=? 時(shí),函數(shù)不為拷貝類函數(shù)(x86 指令集除外).對二進(jìn)制程序中每個(gè)函數(shù)進(jìn)行識別,判斷是否為拷貝類函數(shù),輸出該二進(jìn)制程序中對所有函數(shù)的識別結(jié)果.

        本文對具備拷貝類功能的函數(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ù)量,可以通過對函數(shù)的復(fù)雜程度進(jìn)行過濾,例如以基本塊的數(shù)量進(jìn)行過濾,通常情況下細(xì)粒度的拷貝類函數(shù)的基本塊數(shù)量小于50(這里閾值的設(shè)置根據(jù)對當(dāng)前的拷貝類函數(shù)分析所得,實(shí)際應(yīng)用中可以根據(jù)具體的后續(xù)任務(wù)需求設(shè)置閾值進(jìn)行過濾).

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

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

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

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

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

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

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

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

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

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

        在獲得了函數(shù)的CFG 后,為進(jìn)一步判斷是否為拷貝類函數(shù),需要判斷CFG 是否包含循環(huán).由于判斷圖結(jié)構(gòu)中是否包含環(huán),以及對算法的效率的分析是圖論中研究的內(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ù)的識別;當(dāng)CFG 中無循環(huán)路徑,并且該二進(jìn)制程序非x86 指令集,認(rèn)為此函數(shù)為非拷貝類函數(shù)(對于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 指令,然后對VEX IR 指令進(jìn)行過濾分析,構(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á)式對指令的變量進(jìn)行提取,將指令中的變量分為目的和源,即(dst,src),其中由于存在指令對多個(gè)變量進(jìn)行操作,例如Add 操作,因此,源操作數(shù)src又記錄為(src1,src2),然后根據(jù)指令的類型和特點(diǎn)對源變量和目的變量構(gòu)建數(shù)據(jù)流關(guān)系.在整個(gè)變量關(guān)系記錄過程中,只記錄變量之間的關(guān)系,不記錄常量.以圖9 的行4 為例說明,數(shù)據(jù)流動(dòng)方向?yàn)閺膔1 到t18(VEX IR 的臨時(shí)變量以t開頭),行5 數(shù)據(jù)流動(dòng)方向?yàn)閺膖18 流向了t17,不記錄常量0x00000001流向了t17,依次構(gòu)建所有的變量之間的關(guān)系.由于pc,eip等特殊的寄存器與拷貝類函數(shù)的判斷無關(guān),因此在進(jìn)行變量關(guān)系生成時(shí)會將此類的寄存器過濾掉,不做處理,圖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 代碼

        在對所有的VEX IR 代碼遍歷的同時(shí)記錄直接參與內(nèi)存訪問(加載指令點(diǎn)記錄為LD點(diǎn),存儲指令點(diǎn)記錄為ST點(diǎn))和參與算術(shù)運(yùn)算的變量,例如圖9 中的行5 和行6,其中行5 為加運(yùn)算操作,行6 為從t17指向的內(nèi)存單元中加載數(shù)據(jù).在對所有的VEX IR 指令遍歷后,生成了所有變量之間的關(guān)系、內(nèi)存加載變量集合、內(nèi)存存儲變量集合、算術(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)存存儲集合為 ?、算術(shù)運(yùn)算變量集合為[t17].由于圖9 中VEX IR 指令中無ST指令,因此內(nèi)存存儲集合為空.

        在獲取上述數(shù)據(jù)后,將所有變量之間的關(guān)系輸入到函數(shù)DiGraph()中構(gòu)建DFG.經(jīng)過大量的分析發(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è)特征,對函數(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)行具體識別過程的描述.使用networkx的路徑通過函數(shù)all_simple_paths()來判斷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 對特殊拷貝類函數(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)用會導(dǎo)致數(shù)據(jù)流的中斷,因此需要對變量間的數(shù)據(jù)流進(jìn)行連接,即在函數(shù)的參數(shù)與函數(shù)的返回寄存器之間建立數(shù)據(jù)流關(guān)系.當(dāng)發(fā)現(xiàn)循環(huán)中存在函數(shù)調(diào)用時(shí),對被調(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ù),返回值寄存器的值會指向目的寄存器).對于不同的指令集,其參數(shù)的傳遞方式和結(jié)果返回的方式(返回值寄存器)均不同,因此需要對各個(gè)指令集根據(jù)其參數(shù)傳遞方式的約定進(jìn)行數(shù)據(jù)流的連接,對于x86 指令集則根據(jù)其利用棧進(jìn)行參數(shù)傳遞的方式,追溯壓入棧的指令和變量,與返回值寄存器進(jìn)行連接;對于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)致對特殊拷貝類函數(shù)的遺漏.

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

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

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

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

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

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

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

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

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

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

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

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

        5.2.1 對C 語言庫中拷貝類函數(shù)的識別效果

        為了驗(yàn)證對C 語言庫中拷貝類函數(shù)的識別效果,本文編寫C 代碼,調(diào)用string.h 和wchar.h 庫中的函數(shù)來編譯成不同的二進(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)化等級為O0,此外由于5.0 以上版本的GCC 使用的libc 庫在拷貝類函數(shù)的實(shí)現(xiàn),不同的拷貝類函數(shù)會調(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è)方法的識別效果如表5 所示,從表5 中可以看出,CPYFinder 的效果優(yōu)于其他3 種方法,即BootStomp,SaTC 和SaTC+.盡管BootStomp 具有較高的精準(zhǔn)率P,但是召回率R卻不高于0.5,盡管SaTC+識別效果好于SaTC(后續(xù)實(shí)驗(yàn)只與SaTC+進(jìn)行對比),但是仍低于BootStomp 和CPYFinder,而在實(shí)際分析中,為避免遺漏關(guān)鍵函數(shù),應(yīng)該在保證召回率的情況下提高精準(zhǔn)率.分析發(fā)現(xiàn),誤報(bào)的函數(shù)來源于編譯器的靜態(tài)編譯會引入其他的函數(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 上的識別效果最好,精準(zhǔn)率到達(dá)了0.81,召回率為1.0.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        為了測試CPYFinder 在實(shí)際固件中拷貝類函數(shù)識別的效果,本文收集了近5 年來公開分析的路由器設(shè)備固件中的漏洞,其中多數(shù)與函數(shù)strcpy相關(guān),由于函數(shù)strcpy作為導(dǎo)入函數(shù)調(diào)用,無法對其進(jìn)行識別,不符合實(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)存拷貝中由于對長度未進(jìn)行校驗(yàn)導(dǎo)致的棧溢出漏洞,并且循環(huán)路徑中包含多個(gè)基本塊.對這5 個(gè)導(dǎo)致棧溢出漏洞的函數(shù)進(jìn)行識別測試,判斷BootStomp,SaTC+,CPYFinder 是否能夠識別出這5 個(gè)函數(shù)為拷貝類函數(shù),即是否存在內(nèi)存拷貝的代碼片段.

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

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

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

        5.2.6 效率分析

        本節(jié)對BootStomp,SaTC,SaTC+,CPYFinder 在拷貝類函數(shù)識別中的效率進(jìn)行分析,選取的程序?yàn)?.2.1 節(jié)中測試的程序,各個(gè)方法時(shí)耗的對比結(jié)果如表12 所示,CPYFinder 的效率遠(yuǎn)遠(yuǎn)高于BootStomp 和SaTC.由于不再對函數(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 對數(shù)據(jù)流進(jìn)行了分析,然而由于SaTC 是基于angr 開發(fā)的,angr在分析二進(jìn)制程序時(shí)的效率較低,因此CPYFinder 借助于IDA Pro 盡管增加了數(shù)據(jù)流分析但整個(gè)耗時(shí)卻幾乎未增加,而BootStomp 借助了IDA Pro 的反編譯引擎,由于反編譯分析耗時(shí)較久,因此BootStomp 的耗時(shí)較高.

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

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

        6 CPYFinder 與IDAPro 集成

        為方便對工具的使用,本文將CPYFinder 以IDA插件的形式與IDA Pro 進(jìn)行了集成,并實(shí)現(xiàn)可視化的結(jié)果輸出;支持對單個(gè)函數(shù)的識別和整個(gè)二進(jìn)制程序中所有函數(shù)的識別,將識別分為single 和all 這2種識別模式,其中single 模式識別當(dāng)前光標(biāo)指向的地址所在的函數(shù)是否為拷貝類函數(shù),如圖11 所示.single 模式的輸出如圖12 所示.對整個(gè)二進(jìn)制程序的識別結(jié)果可視化界面如圖13 所示,該界面共分為5 個(gè)部分,其中Line 為檢測時(shí)的序號、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ù)手工分析對結(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ù)CPYFinder 通過將二進(jìn)制函數(shù)轉(zhuǎn)換成中間語言VEX IR 進(jìn)行數(shù)據(jù)流的分析,支持對多指令集架構(gòu)(x86,ARM,MIPS,PPC)的二進(jìn)制程序中拷貝類函數(shù)的識別,不依賴于符號表等信息,并且受編譯器版本、優(yōu)化等級的影響較小.此外,CPYFinder 不僅能夠識別庫函數(shù)中的內(nèi)存拷貝類函數(shù),還能識別用戶自定義的內(nèi)存拷貝類函數(shù),具有較高的適用性.雖然基于靜態(tài)分析的識別方法具有快速、高效的特點(diǎn),但是由于靜態(tài)數(shù)據(jù)流分析很難做到十分精確,并且由于用戶自定義實(shí)現(xiàn)的拷貝類函數(shù)多樣以及受編譯器和優(yōu)化等級的影響,無可避免地會存在一定的誤報(bào)和漏報(bào),所以在識別的準(zhǔn)確率上具有一定局限性.在后續(xù)的研究中,嘗試將動(dòng)態(tài)執(zhí)行以及動(dòng)靜態(tài)分析結(jié)合的方式應(yīng)用到拷貝類函數(shù)的識別中,提高對拷貝類函數(shù)識別的準(zhǔn)確率.

        8 結(jié)束語

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

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

        猜你喜歡
        指令集拷貝二進(jìn)制
        用二進(jìn)制解一道高中數(shù)學(xué)聯(lián)賽數(shù)論題
        3DNow指令集被Linux淘汰
        有趣的進(jìn)度
        二進(jìn)制在競賽題中的應(yīng)用
        中國生殖健康(2018年1期)2018-11-06 07:14:38
        實(shí)時(shí)微測量系統(tǒng)指令集及解析算法
        什么是AMD64
        基于覆蓋率驅(qū)動(dòng)的高性能DSP指令集驗(yàn)證方法
        一個(gè)生成組合的新算法
        文件拷貝誰最“給力”
        午夜一级成人| 国产精品成人无码久久久久久| 色偷偷亚洲第一成人综合网址 | 日韩a毛片免费观看| 亚洲网站免费看| 国产一级黄色片一区二区| 亚洲人成人无码www| 无码精品人妻一区二区三区影院 | 99久久久精品国产性黑人| 亚洲国产综合人成综合网站| 欧美最猛黑人xxxx黑人猛交 | 亚洲av中文字字幕乱码软件| 浓毛老太交欧美老妇热爱乱| 老师脱了内裤让我进去| 999精品免费视频观看| 蜜桃码一区二区三区在线观看| 人人妻人人添人人爽欧美一区 | 欧美黄色免费看| 色婷婷精品国产一区二区三区| 国产av剧情一区二区三区| 水蜜桃精品一二三| 亚洲欧洲日产国码无码AV一| 55夜色66夜色国产精品视频| 亚洲成人777| 午夜av福利亚洲写真集| 东北女人啪啪对白| 国产亚洲av综合人人澡精品| 偷拍网日本一区二区三区| aa日韩免费精品视频一| 久久精品aⅴ无码中文字字幕| 国产免费一区二区三区在线观看| 国产美女自拍国语对白| av影院手机在线观看| 国产在视频线精品视频| 国产精品一区2区三区| 免费在线亚洲视频观看| 老师露出两个奶球让我吃奶头| 91视频88av| 日本一区中文字幕在线播放| 护士的小嫩嫩好紧好爽| 亚洲另类激情综合偷自拍图|