• 
    

    
    

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

      ?

      基于數(shù)據(jù)結(jié)構(gòu)特征發(fā)現(xiàn)的腳本引擎內(nèi)置對(duì)象別名關(guān)系識(shí)別

      2022-08-16 09:34:08張羿偉萬(wàn)欣宇郭蘇越
      信息安全學(xué)報(bào) 2022年4期
      關(guān)鍵詞:腳本數(shù)據(jù)結(jié)構(gòu)內(nèi)置

      張羿偉,游 偉,梁 彬,萬(wàn)欣宇,郭蘇越

      中國(guó)人民大學(xué)信息學(xué)院 北京 中國(guó) 100872

      1 引言

      腳本語(yǔ)言具有簡(jiǎn)單易用的特性,越來(lái)越多的軟件支持通過(guò)腳本語(yǔ)言可編程式地調(diào)用各項(xiàng)程序功能。這些軟件通過(guò)內(nèi)置的腳本引擎對(duì)腳本代碼進(jìn)行解析并執(zhí)行。內(nèi)置腳本引擎除了支持標(biāo)準(zhǔn)的腳本語(yǔ)言規(guī)范,還提供了一系列擴(kuò)展的應(yīng)用程序編程接口(Application programming interface,API)和內(nèi)置對(duì)象。用戶可以通過(guò)調(diào)用擴(kuò)展 API 來(lái)執(zhí)行由本地代碼(Native code)實(shí)現(xiàn)的程序功能。

      腳本引擎在豐富軟件功能的同時(shí),也引入了額外的攻擊面。攻擊者可以利用腳本引擎漏洞,編寫(xiě)特定攻擊代碼,達(dá)到控制用戶設(shè)備、竊取用戶隱私等目的。根據(jù)漏洞庫(kù)中的信息,近年來(lái)頻繁出現(xiàn)腳本引擎相關(guān)的程序安全漏洞,已造成大量經(jīng)濟(jì)損失與安全危害[1]。通過(guò)對(duì)已公開(kāi)的漏洞利用樣本進(jìn)行分析[2],我們發(fā)現(xiàn)絕大多數(shù)的腳本引擎漏洞是由于擴(kuò)展API和內(nèi)置對(duì)象使用不當(dāng)產(chǎn)生的。

      針對(duì)腳本引擎中的程序漏洞,目前主流的檢測(cè)技術(shù)為模糊測(cè)試(Fuzzing)[3],使用特定的生成/變異策略產(chǎn)生大量測(cè)試樣本,并監(jiān)測(cè)測(cè)試樣本的執(zhí)行是否觸發(fā)程序異常。然而,現(xiàn)有的模糊測(cè)試研究工作主要關(guān)注如何生成符合腳本語(yǔ)言語(yǔ)法規(guī)范的測(cè)試樣本。雖然取得了一定的成效,但是這些研究工作僅能檢測(cè)出腳本引擎淺層解析代碼中的漏洞,難以有效檢測(cè)出腳本引擎深層代碼中的漏洞。

      腳本引擎中的深層次漏洞通常與擴(kuò)展API 及內(nèi)置對(duì)象相關(guān)。以釋放后使用(Use-After-Free,UAF)漏洞為例,其本質(zhì)為通過(guò)懸掛指針?lè)欠ㄔL問(wèn)了被釋放的內(nèi)存區(qū)域。在腳本引擎中,通過(guò)調(diào)用特定的API序列,可以創(chuàng)建內(nèi)置對(duì)象內(nèi)部的共享內(nèi)存區(qū)域,進(jìn)而產(chǎn)生不同對(duì)象在共享內(nèi)存區(qū)域上的別名關(guān)系。釋放其中一個(gè)對(duì)象內(nèi)部的共享內(nèi)存區(qū)域,將會(huì)在與其存在別名關(guān)系的另一對(duì)象內(nèi)部產(chǎn)生懸掛指針,訪問(wèn)該懸掛指針會(huì)觸發(fā)釋放后使用漏洞?,F(xiàn)有的模糊測(cè)試技術(shù)沒(méi)有關(guān)注內(nèi)置對(duì)象內(nèi)部結(jié)構(gòu),因而在發(fā)現(xiàn)釋放后使用漏洞方面效果較差。

      為了檢測(cè)由對(duì)象別名關(guān)系導(dǎo)致的釋放后使用漏洞,需要解決兩個(gè)關(guān)鍵的技術(shù)挑戰(zhàn)。其一,如何高效地識(shí)別內(nèi)置對(duì)象別名關(guān)系。腳本引擎中的內(nèi)置對(duì)象由腳本引擎負(fù)責(zé)維護(hù),用戶可以通過(guò)使用API 的方式來(lái)創(chuàng)建、更改和刪除內(nèi)置對(duì)象。生成合理的API序列對(duì)不同對(duì)象進(jìn)行有針對(duì)性的操作是首要解決的問(wèn)題。除此之外,由于內(nèi)置對(duì)象別名關(guān)系與對(duì)象結(jié)構(gòu)緊密相關(guān),需要實(shí)現(xiàn)一種機(jī)制快速檢測(cè)API 序列的執(zhí)行是否建立了對(duì)象間的共享內(nèi)存區(qū)域。其二,如何利用識(shí)別出的對(duì)象別名關(guān)系檢測(cè)腳本引擎的釋放后使用漏洞。為了觸發(fā)腳本引擎釋放后使用漏洞,需要構(gòu)造性地利用對(duì)象別名關(guān)系以產(chǎn)生懸掛指針。別名關(guān)系代表不同內(nèi)置對(duì)象內(nèi)部存在共享內(nèi)存區(qū)域,因此需要考慮如何生成API 序列釋放對(duì)象內(nèi)部的共享內(nèi)存區(qū)域,以產(chǎn)生懸掛指針。進(jìn)一步,利用API 序列針對(duì)性地訪問(wèn)懸掛指針,觸發(fā)釋放后使用漏洞。

      為了解決上述挑戰(zhàn),我們提出了一種基于數(shù)據(jù)結(jié)構(gòu)特征發(fā)現(xiàn)的腳本引擎內(nèi)置對(duì)象別名關(guān)系識(shí)別方法,并利用內(nèi)置對(duì)象別名關(guān)系輔助檢測(cè)腳本引擎中的釋放后使用漏洞。具體而言,通過(guò)生成特殊的腳本引擎API 調(diào)用序列,建立內(nèi)置對(duì)象別名關(guān)系,并使用對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,將內(nèi)置對(duì)象別名關(guān)系識(shí)別轉(zhuǎn)化為圖連通性識(shí)別,加快了內(nèi)置對(duì)象別名關(guān)系識(shí)別速度。在此基礎(chǔ)上,我們提出了一種利用別名關(guān)系構(gòu)造式觸發(fā)釋放后使用漏洞的檢測(cè)方案。對(duì)于具有別名關(guān)系的兩個(gè)對(duì)象,通過(guò)調(diào)用特殊的腳本引擎API 序列,釋放其中一個(gè)對(duì)象內(nèi)部的共享內(nèi)存區(qū)域,從而在另一個(gè)對(duì)象內(nèi)部產(chǎn)生懸掛指針,隨后調(diào)用特殊的腳本引擎API 序列訪問(wèn)另懸掛指針,以觸發(fā)釋放后使用漏洞。

      本文的主要貢獻(xiàn)有:

      (1) 提出了一種基于數(shù)據(jù)結(jié)構(gòu)特征的腳本引擎內(nèi)置對(duì)象別名關(guān)系識(shí)別方法。通過(guò)利用內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,自動(dòng)化提取腳本引擎API 參數(shù)信息并生成合理API 序列,提高了對(duì)象別名關(guān)系的產(chǎn)生概率。同時(shí),利用對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,將內(nèi)置對(duì)象別名關(guān)系識(shí)別轉(zhuǎn)化為圖連通性識(shí)別。在保證識(shí)別準(zhǔn)確率的前提下,顯著減小了性能開(kāi)銷,加快了內(nèi)置對(duì)象別名關(guān)系識(shí)別速度。

      (2) 創(chuàng)新性地將內(nèi)置對(duì)象別名關(guān)系應(yīng)用于檢測(cè)腳本引擎釋放后使用漏洞。通過(guò)使用內(nèi)置對(duì)象別名關(guān)系,搭配特殊API 序列,增加了釋放操作產(chǎn)生的懸掛指針數(shù)量。相比于傳統(tǒng)釋放后使用漏洞,由對(duì)象別名關(guān)系導(dǎo)致的釋放后使用漏洞更容易利用且更難修補(bǔ)。

      (3) 設(shè)計(jì)并實(shí)現(xiàn)了別名關(guān)系識(shí)別方法的系統(tǒng)原型,成功提取出了284 組內(nèi)置對(duì)象別名關(guān)系,并設(shè)計(jì)評(píng)估實(shí)驗(yàn)證明了方法的高效性與準(zhǔn)確性。進(jìn)一步,針對(duì)真實(shí)軟件中的腳本引擎進(jìn)行了漏洞檢測(cè),成功發(fā)現(xiàn)了4 個(gè)未知釋放后使用漏洞,幫助提高了軟件安全性。

      2 相關(guān)工作

      針對(duì)腳本引擎中的安全漏洞,目前主流的檢測(cè)技術(shù)為模糊測(cè)試(Fuzzing)技術(shù)。模糊測(cè)試技術(shù)根據(jù)特定的生成策略產(chǎn)生大量測(cè)試樣本,并監(jiān)測(cè)測(cè)試樣本的執(zhí)行能否觸發(fā)程序異常。按照技術(shù)細(xì)節(jié)不同,具體又可分為生成型模糊測(cè)試以及變異型模糊測(cè)試[4]。

      生成型模糊測(cè)試技術(shù)基于給定的規(guī)范(如語(yǔ)言語(yǔ)法,樣本結(jié)構(gòu)等)生成測(cè)試樣本,部分生成型模糊測(cè)試框架也會(huì)借助語(yǔ)料庫(kù)信息[5],常見(jiàn)的測(cè)試框架有SPIKE[6]和jsfunfuzz[7]等。為了生成語(yǔ)法正確的測(cè)試樣本,通常使用上下文無(wú)關(guān)語(yǔ)法作為規(guī)范[8-9]。除此之外,HyungSeok 等人[10]和Soyeon 等人[11]提出利用現(xiàn)有正確測(cè)試樣本中的語(yǔ)法信息來(lái)完善樣本生成規(guī)范。進(jìn)一步,Suyoung 等人[12]提出利用神經(jīng)網(wǎng)絡(luò)來(lái)訓(xùn)練模型以產(chǎn)生樣本生成規(guī)范,旨在通過(guò)完善規(guī)范來(lái)提升測(cè)試樣本質(zhì)量。然而,不同腳本語(yǔ)句之間存在依賴關(guān)系,生成型模糊測(cè)試技術(shù)無(wú)法捕獲此類依賴關(guān)系,因而無(wú)法避免由依賴關(guān)系導(dǎo)致的運(yùn)行時(shí)異常。

      變異型模糊測(cè)試技術(shù)基于給定的種子輸入,采用不同的變異策略(如比特翻轉(zhuǎn),隨機(jī)替換等)生成新的測(cè)試樣本,常見(jiàn)的測(cè)試框架有AFL[13]和SymFuzz[14]等。變異型模糊測(cè)試技術(shù)通常以代碼覆蓋率為指標(biāo)評(píng)估測(cè)試樣本的質(zhì)量,認(rèn)為代碼覆蓋率越高測(cè)試樣本質(zhì)量越好。為了提高測(cè)試樣本的質(zhì)量,常使用污染傳播[15-16],符號(hào)執(zhí)行[17]和約束求解[18]等技術(shù)。除此之外,Sanjay 等人[19]通過(guò)設(shè)置程序路徑權(quán)重,有針對(duì)性地進(jìn)行變異以生成測(cè)試樣本,以及Caroline 等人[20]提出在變異過(guò)程中加入已知漏洞樣本(Proof of Concept)信息,以生成高質(zhì)量測(cè)試樣本。然而,變異型模糊測(cè)試容易破壞種子輸入的完整性,導(dǎo)致無(wú)法通過(guò)完整性校驗(yàn)。

      在測(cè)試腳本引擎漏洞方面,Sung 等人[21]提出了一種使用內(nèi)置API 和內(nèi)置對(duì)象來(lái)測(cè)試JavaScript 腳本引擎的方法,以減少運(yùn)行時(shí)錯(cuò)誤的產(chǎn)生。該方法雖然利用腳本引擎API 和內(nèi)置對(duì)象信息減少了運(yùn)行時(shí)錯(cuò)誤的數(shù)量,但測(cè)試樣本的生成不夠自動(dòng)化,且需要一些先驗(yàn)知識(shí)做引導(dǎo)。除此之外,Nicolas 等人[22]提出利用程序運(yùn)行時(shí)的內(nèi)存訪問(wèn)信息來(lái)改進(jìn)測(cè)試樣本,以測(cè)試更復(fù)雜的程序模塊,但對(duì)于大型腳本引擎效果不佳。

      別名分析的主要目的在于確定程序中指針的具體指向,進(jìn)而判定指針操作是否存在潛在風(fēng)險(xiǎn)[23]?,F(xiàn)有別名分析技術(shù)主要分為靜態(tài)別名分析以及動(dòng)態(tài)別名分析。靜態(tài)別名分析通過(guò)分析程序源代碼來(lái)識(shí)別別名關(guān)系,常結(jié)合控制流圖或調(diào)用圖進(jìn)行分析[24],即過(guò)程間分析[25-26]。通常靜態(tài)別名分析所需時(shí)間與控制流圖的復(fù)雜程度成正比,為了精簡(jiǎn)控制流圖,Tobias 等人[27]提出將分支條件與變量狀態(tài)關(guān)聯(lián),并依據(jù)變量狀態(tài)來(lái)刪除冗余分支。動(dòng)態(tài)別名分析則通過(guò)監(jiān)控內(nèi)存中變量的變化來(lái)識(shí)別別名關(guān)系,常在中間代碼層面進(jìn)行程序插裝以判斷不同變量之間是否共享同一內(nèi)存區(qū)域[28-29]。Manu 等人[30]提出實(shí)施簡(jiǎn)單的可達(dá)性分析,縮小監(jiān)控范圍提高分析性能。然而,由于腳本引擎結(jié)構(gòu)復(fù)雜,使用現(xiàn)有技術(shù)獲得精確分析結(jié)果存在性能開(kāi)銷大的問(wèn)題,且內(nèi)置對(duì)象結(jié)構(gòu)特殊,無(wú)法使用通用的處理策略。

      3 腳本引擎與釋放后使用漏洞

      腳本引擎作為腳本語(yǔ)言運(yùn)行的載體,負(fù)責(zé)解析執(zhí)行腳本語(yǔ)言,以及提供相應(yīng)的運(yùn)行環(huán)境。腳本引擎提供了一系列定制的應(yīng)用程序接口(Application programming interface,API)來(lái)幫助用戶高效使用內(nèi)部功能,我們稱之為特殊API,如Adobe Reader 內(nèi)嵌腳本引擎中的Doc.createIcon 負(fù)責(zé)在文檔中創(chuàng)建按鈕元件。與特殊API 類似,腳本引擎中的內(nèi)置對(duì)象也具有特殊的結(jié)構(gòu)和語(yǔ)義,如Adobe Reader 內(nèi)嵌引擎中的Doc 對(duì)象代表當(dāng)前文檔。特殊API 以及內(nèi)置對(duì)象是腳本引擎的重要組成部分,不同腳本引擎中特殊API 以及內(nèi)置對(duì)象的數(shù)量和功能均有較大差異,合理使用特殊API 與內(nèi)置對(duì)象能觸及更多、更深層次的引擎代碼。

      在使用腳本引擎API 時(shí),需要遵照特定的使用規(guī)范,即提供正確數(shù)量和類型的參數(shù)。當(dāng)腳本引擎API 參數(shù)的數(shù)量或類型錯(cuò)誤時(shí),腳本引擎會(huì)拋出運(yùn)行時(shí)異常,并終止腳本代碼的執(zhí)行。腳本引擎中API參數(shù)的類型包括布爾類型,整數(shù)類型,浮點(diǎn)類型,字符串類型以及對(duì)象類型五類,不同類型之間可以動(dòng)態(tài)轉(zhuǎn)化。

      進(jìn)一步,經(jīng)過(guò)實(shí)驗(yàn)發(fā)現(xiàn),腳本引擎API 在運(yùn)行時(shí)需要特定結(jié)構(gòu)的內(nèi)置對(duì)象,因此需要分析內(nèi)置對(duì)象的細(xì)粒度類型信息。通常,對(duì)于腳本引擎API,軟件開(kāi)發(fā)者會(huì)提供一份官方的使用規(guī)范,說(shuō)明不同腳本引擎API 需要的參數(shù)個(gè)數(shù)以及類型。然而,以Adobe Reader 內(nèi)嵌腳本引擎為例,官方提供的使用規(guī)范并不詳細(xì),未說(shuō)明腳本引擎API 對(duì)象參數(shù)的細(xì)粒度類型信息。我們統(tǒng)計(jì)了Adobe Reader 內(nèi)嵌腳本引擎中的386 個(gè)API,其中使用對(duì)象類型參數(shù)的API 有255個(gè),占比約66%。為了減少運(yùn)行時(shí)錯(cuò)誤,我們需要提取API 參數(shù)的細(xì)粒度類型,進(jìn)而正確且針對(duì)性地使用腳本引擎API 和內(nèi)置對(duì)象。

      內(nèi)置對(duì)象的生命周期由腳本引擎負(fù)責(zé)維護(hù),在生命周期結(jié)束時(shí)被腳本引擎回收。用戶可通過(guò)調(diào)用腳本引擎API 來(lái)創(chuàng)建,更改和刪除內(nèi)置對(duì)象,即能夠通過(guò)調(diào)用腳本引擎API 影響內(nèi)置對(duì)象生命周期。按照創(chuàng)建方式的不同,具體可以分為靜態(tài)內(nèi)置對(duì)象以及動(dòng)態(tài)內(nèi)置對(duì)象。靜態(tài)內(nèi)置對(duì)象由腳本引擎預(yù)創(chuàng)建,可直接使用對(duì)象名稱訪問(wèn),而動(dòng)態(tài)內(nèi)置對(duì)象需要調(diào)用腳本引擎API 創(chuàng)建后才能訪問(wèn)。

      對(duì)于靜態(tài)內(nèi)置對(duì)象以及動(dòng)態(tài)內(nèi)置對(duì)象,腳本引擎采用一個(gè)活躍對(duì)象集合維護(hù)其生命周期?;钴S對(duì)象集合存儲(chǔ)腳本引擎中存活的內(nèi)置對(duì)象,其狀態(tài)隨著內(nèi)置對(duì)象的創(chuàng)建和刪除實(shí)時(shí)變化。活躍對(duì)象集合由腳本引擎負(fù)責(zé)維護(hù),用戶無(wú)法直接更改其狀態(tài),但可以通過(guò)影響內(nèi)置對(duì)象生命周期,間接影響活躍對(duì)象集合的狀態(tài)。活躍對(duì)象集合常用于查詢內(nèi)置對(duì)象生命周期信息,在腳本引擎中具有重要意義。

      腳本引擎在通過(guò)豐富的API 以及內(nèi)置對(duì)象提供便利的同時(shí),也引入了更多安全漏洞。攻擊者可利用腳本引擎API 以及內(nèi)置對(duì)象構(gòu)造特殊的攻擊代碼,觸發(fā)多種類型的安全漏洞,對(duì)用戶造成危害。其中,釋放后使用漏洞與非法內(nèi)存操作緊密相關(guān),可利用性強(qiáng),常成為攻擊者的重點(diǎn)關(guān)注目標(biāo)。釋放后使用漏洞的本質(zhì)為通過(guò)懸掛指針訪問(wèn)了被釋放的內(nèi)存區(qū)域,而懸掛指針是指向被釋放內(nèi)存區(qū)域的指針,是由于對(duì)象釋放后缺乏合理的訪問(wèn)檢查導(dǎo)致。我們以圖1 為例具體說(shuō)明釋放后使用漏洞的觸發(fā)模式和修補(bǔ)方式。

      圖1 展示了1 個(gè)典型釋放后使用漏洞的觸發(fā)模式。首先執(zhí)行創(chuàng)建操作(malloc)創(chuàng)建對(duì)象p(對(duì)應(yīng)標(biāo)號(hào)為①的語(yǔ)句)。接著調(diào)用合適的API 序列執(zhí)行釋放操作(free),釋放創(chuàng)建出的對(duì)象p并產(chǎn)生了懸掛指針(對(duì)應(yīng)標(biāo)號(hào)為②的語(yǔ)句)。最后,使用(use)被釋放的對(duì)象p并訪問(wèn)其內(nèi)部的懸掛指針,觸發(fā)了釋放后使用類型的安全漏洞(對(duì)應(yīng)標(biāo)號(hào)為③的語(yǔ)句)?,F(xiàn)有工作針對(duì)釋放后使用漏洞的修補(bǔ)方式對(duì)應(yīng)語(yǔ)句⑤⑦⑧,即增加對(duì)象釋放標(biāo)志并根據(jù)對(duì)象狀態(tài)實(shí)時(shí)維護(hù)釋放標(biāo)志(對(duì)應(yīng)標(biāo)號(hào)為⑦的語(yǔ)句),同時(shí)在每次訪問(wèn)對(duì)象前檢查釋放標(biāo)志的狀態(tài)(對(duì)應(yīng)標(biāo)號(hào)為⑧的語(yǔ)句),當(dāng)對(duì)象釋放標(biāo)志被設(shè)置為T(mén)rue 時(shí)拒絕訪問(wèn)對(duì)象。

      修復(fù)釋放后使用漏洞的核心在于消除懸掛指針,現(xiàn)有設(shè)置對(duì)象釋放標(biāo)志的方式簡(jiǎn)單有效,且適用于所有類型的對(duì)象,通用性強(qiáng)。然而,由于腳本引擎內(nèi)部存在復(fù)雜對(duì)象關(guān)系,比如內(nèi)置對(duì)象別名關(guān)系,導(dǎo)致不同內(nèi)置對(duì)象內(nèi)部存在共享內(nèi)存區(qū)域,進(jìn)而在釋放時(shí)出現(xiàn)多個(gè)懸掛指針。相比于原有的釋放后使用漏洞,使用對(duì)象別名關(guān)系可以在不同對(duì)象中引入懸掛指針,增加了漏洞的不確定性,利用釋放標(biāo)志進(jìn)行修補(bǔ)也更加困難。我們將由對(duì)象別名關(guān)系導(dǎo)致的釋放后使用漏洞觸發(fā)模式總結(jié)為圖2 所示。

      如圖2 所示,首先執(zhí)行創(chuàng)建操作產(chǎn)生了對(duì)象p和對(duì)象q(對(duì)應(yīng)標(biāo)號(hào)為①②的語(yǔ)句)。接著,通過(guò)執(zhí)行特定腳本引擎API 序列,建立了對(duì)象p和對(duì)象q之間的別名關(guān)系(對(duì)應(yīng)標(biāo)號(hào)為③的語(yǔ)句),具體對(duì)應(yīng)對(duì)象p,q內(nèi)部的共享內(nèi)存區(qū)域。之后,執(zhí)行釋放操作釋放對(duì)象p(對(duì)應(yīng)標(biāo)號(hào)為④的語(yǔ)句),產(chǎn)生了懸掛指針。不同于傳統(tǒng)釋放后使用漏洞觸發(fā)模式,在最后訪問(wèn)懸掛指針時(shí),并未使用上一步中釋放的對(duì)象p,而是使用了與對(duì)象p存在別名關(guān)系的對(duì)象q(對(duì)應(yīng)標(biāo)號(hào)為⑤的語(yǔ)句)。

      相較于傳統(tǒng)的釋放后使用漏洞,通過(guò)建立內(nèi)置對(duì)象別名關(guān)系,引入了更多的懸掛指針,增加了釋放后使用漏洞的可利用性。傳統(tǒng)的釋放后使用漏洞觸發(fā)模式與對(duì)象別名關(guān)系導(dǎo)致的釋放后使用漏洞觸發(fā)模式有如下異同點(diǎn):二者均通過(guò)訪問(wèn)懸掛指針觸發(fā)安全漏洞,但在傳統(tǒng)釋放后使用漏洞觸發(fā)模式中,釋放以及使用的為同一個(gè)對(duì)象,僅產(chǎn)生了一個(gè)懸掛指針。在別名關(guān)系導(dǎo)致的釋放后使用漏洞中,釋放以及使用操作涉及不同對(duì)象,產(chǎn)生了多個(gè)懸掛指針。相較于傳統(tǒng)的釋放后使用漏洞,別名關(guān)系觸發(fā)的釋放后使用漏洞更為復(fù)雜,涉及不同內(nèi)置對(duì)象的交互,并且現(xiàn)有的防御措施無(wú)法有效抵御別名關(guān)系導(dǎo)致的釋放后使用漏洞。

      4 別名關(guān)系識(shí)別

      本研究提出了一種基于數(shù)據(jù)結(jié)構(gòu)特征腳本引擎內(nèi)置對(duì)象別名關(guān)系識(shí)別方法,能高效準(zhǔn)確地建立并識(shí)別腳本引擎內(nèi)置對(duì)象別名關(guān)系,如圖3 所示,整個(gè)內(nèi)置對(duì)象別名關(guān)系識(shí)別方法共分為三個(gè)階段。

      第一階段對(duì)應(yīng)文章3.2 節(jié),負(fù)責(zé)提取腳本引擎內(nèi)置對(duì)象的數(shù)據(jù)結(jié)構(gòu)特征。該階段主要采用動(dòng)態(tài)插裝的方式,使用腳本引擎API 創(chuàng)建并訪問(wèn)內(nèi)置對(duì)象并監(jiān)控程序執(zhí)行,獲取程序運(yùn)行時(shí)內(nèi)置對(duì)象的內(nèi)存地址。進(jìn)一步,通過(guò)識(shí)別與對(duì)象起始地址相關(guān)的內(nèi)存單元類型,提取腳本引擎內(nèi)置對(duì)象的數(shù)據(jù)結(jié)構(gòu)特征。

      第二階段對(duì)應(yīng)文章3.3 節(jié),負(fù)責(zé)生成參數(shù)類型正確的腳本引擎API 調(diào)用實(shí)例。此階段我們采用靜態(tài)分析技術(shù)來(lái)提取腳本引擎API 對(duì)象參數(shù)的內(nèi)存訪問(wèn)模式,并與第一階段中提取的對(duì)象數(shù)據(jù)結(jié)構(gòu)特征匹配,獲得API 對(duì)象參數(shù)候選集。進(jìn)一步,使用獲得的API 對(duì)象參數(shù)列表,生成參數(shù)類型正確的腳本引擎API 調(diào)用語(yǔ)句,并組合不同API 調(diào)用語(yǔ)句產(chǎn)生測(cè)試樣本。

      第三階段對(duì)應(yīng)文章3.4 節(jié),負(fù)責(zé)監(jiān)測(cè)共享內(nèi)存區(qū)域來(lái)識(shí)別內(nèi)置對(duì)象別名關(guān)系。該階段主要使用動(dòng)態(tài)測(cè)試的技術(shù),獲取程序運(yùn)行時(shí)對(duì)象的內(nèi)存地址,提取對(duì)應(yīng)的內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,并轉(zhuǎn)化為數(shù)據(jù)結(jié)構(gòu)特征圖存儲(chǔ)。通過(guò)在API 執(zhí)行前后插入檢查點(diǎn)的方式,分析數(shù)據(jù)結(jié)構(gòu)特征圖的變化,并根據(jù)數(shù)據(jù)結(jié)構(gòu)特征圖的變化識(shí)別內(nèi)置對(duì)象別名關(guān)系。

      在接下來(lái)的部分,我們首先介紹內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征的定義,之后依次介紹流程每個(gè)階段的具體實(shí)現(xiàn)。

      4.1 內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征

      內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征T定義為由不同類型內(nèi)存單元組成的,具有明顯分層與指向關(guān)系的一種內(nèi)存特征。我們以字長(zhǎng)為單位劃分內(nèi)置對(duì)象所在的內(nèi)存區(qū)域,并將劃分后的字長(zhǎng)大小的內(nèi)存區(qū)域稱為內(nèi)存單元。字長(zhǎng)的大小與操作系統(tǒng)相關(guān),在64 位操作系統(tǒng)中字長(zhǎng)大小為8 字節(jié),32 位操作系統(tǒng)中字長(zhǎng)大小為4 字節(jié)。對(duì)于內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征T,我們采用有向圖的方式表示如下:

      其中,V代表有向圖中頂點(diǎn)的集合,E代表有向圖中邊的集合,具體如下:

      頂點(diǎn)集合V中每個(gè)元素vi均對(duì)應(yīng)一個(gè)內(nèi)存單元,vi的具體定義如下:

      vi定義為由Value,Type和Ancient 組成的三元組,其中Value 代表運(yùn)行時(shí)內(nèi)存單元中存儲(chǔ)的數(shù)值,隨著腳本引擎API 的執(zhí)行發(fā)生變化。Type 代表內(nèi)存單元數(shù)值的類型,具體包括可變數(shù)值類型(Number),固定數(shù)值類型(Padding)以及指針類型(Pointer)3 種,在具體實(shí)現(xiàn)時(shí)用不同數(shù)值代表3 種類型(如指針類型對(duì)應(yīng)數(shù)值0x1)。固定數(shù)值類型代表內(nèi)存單元中數(shù)據(jù)的數(shù)值固定,即相同類型的內(nèi)置對(duì)象擁有相同的數(shù)值。同時(shí),固定數(shù)值類型對(duì)應(yīng)的數(shù)值與運(yùn)行狀態(tài)無(wú)關(guān),即多次創(chuàng)建出相同類型的內(nèi)置對(duì)象,其固定數(shù)值類型對(duì)應(yīng)的數(shù)值均相同??勺償?shù)值類型的定義與固定數(shù)值類型相反。對(duì)于相同類型對(duì)象,可變數(shù)值類型內(nèi)存單元中數(shù)據(jù)的數(shù)值不固定,且與運(yùn)行狀態(tài)緊密相關(guān),在多次運(yùn)行中會(huì)得到不同的數(shù)值。指針類型的內(nèi)存單元代表該內(nèi)存單元中的數(shù)據(jù)指向其他合法內(nèi)存單元,能夠通過(guò)指針解引用操作進(jìn)行層級(jí)展開(kāi)。Ancient為內(nèi)存單元所屬標(biāo)識(shí),代表該內(nèi)存單元從屬于特定內(nèi)置對(duì)象。我們?yōu)橥粌?nèi)置對(duì)象下屬所有內(nèi)存單元設(shè)置統(tǒng)一的Ancient,并使用唯一Ancient值以區(qū)分不同內(nèi)置對(duì)象。通常,Ancient 值被設(shè)置為內(nèi)置對(duì)象運(yùn)行時(shí)內(nèi)存起始地址,方便查詢內(nèi)置對(duì)象信息。

      邊集E中每個(gè)元素ei代表有向圖中頂點(diǎn)的指向關(guān)系,其具體定義如下:

      其中,vs和ve分別代表該有向邊的起始頂點(diǎn)和終止頂點(diǎn),對(duì)應(yīng)頂點(diǎn)集合V中的元素。Offset 為頂點(diǎn)vs代表內(nèi)存單元到頂點(diǎn)ve代表內(nèi)存單元的內(nèi)存偏移。在ei中,頂點(diǎn)vs對(duì)應(yīng)指針類型的內(nèi)存單元,我們根據(jù)其中包含的指向信息劃分對(duì)象數(shù)據(jù)結(jié)構(gòu)特征內(nèi)部的層級(jí)。以Stream 對(duì)象為例,Stream 對(duì)象起始地址對(duì)應(yīng)的內(nèi)存區(qū)域稱為第一層級(jí),第一層級(jí)中指針類型指向的內(nèi)存區(qū)域?yàn)榈诙蛹?jí),以此類推。

      我們將存儲(chǔ)對(duì)象數(shù)據(jù)結(jié)構(gòu)特征的有向圖稱為數(shù)據(jù)結(jié)構(gòu)特征圖。數(shù)據(jù)結(jié)構(gòu)特征圖中的根節(jié)點(diǎn)代表具體內(nèi)置對(duì)象,每個(gè)子節(jié)點(diǎn)對(duì)應(yīng)數(shù)據(jù)結(jié)構(gòu)特征中的每個(gè)內(nèi)存單元。以Stream 類型對(duì)象為例,最終轉(zhuǎn)化成的數(shù)據(jù)結(jié)構(gòu)特征圖如圖4 所示。以圖4 右下角陰影標(biāo)注的頂點(diǎn)為例,三元組中Value 的值為0x1340,代表運(yùn)行時(shí)內(nèi)存單元中的數(shù)值為0x1340。Type 值為0x1代表該頂點(diǎn)的類型為指針類型。Ancient 值為0x1220對(duì)應(yīng)對(duì)象根節(jié)點(diǎn)的Value 值(即圖4 中Stream 標(biāo)注的頂點(diǎn)),標(biāo)明該頂點(diǎn)屬于Stream 對(duì)象。

      內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征中的層級(jí)個(gè)數(shù)以及內(nèi)存單元個(gè)數(shù)可自主配置。通常而言,使用的層級(jí)個(gè)數(shù)和內(nèi)存單元個(gè)數(shù)越多,特征的分類效果越好,而性能開(kāi)銷則越大。為了確定合適的配置,我們進(jìn)行了相關(guān)探索,結(jié)果如表1 所示。當(dāng)層級(jí)個(gè)數(shù)為1,每個(gè)層級(jí)中內(nèi)存單元的個(gè)數(shù)為4 時(shí),所有內(nèi)置對(duì)象被歸為一個(gè)類,沒(méi)有任何區(qū)分度。隨著層級(jí)個(gè)數(shù)與內(nèi)存單元個(gè)數(shù)的增加,內(nèi)置對(duì)象種類的數(shù)量也隨之上升,上升幅度呈遞減趨勢(shì)。最終,出于平衡性能開(kāi)銷與分類效果的考慮,確定層級(jí)個(gè)數(shù)為3,層級(jí)中內(nèi)存單元個(gè)數(shù)為8。第6 章的實(shí)驗(yàn)評(píng)估結(jié)果也表明,這樣的配置可以保證較高的測(cè)試用例生成效率。

      表1 內(nèi)置對(duì)象種類統(tǒng)計(jì)表Table 1 Statistics of built-in object type

      4.2 提取內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征

      在該節(jié)中我們具體介紹如何提取內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征。該階段主要采用動(dòng)態(tài)插裝的方式,獲取程序運(yùn)行時(shí)內(nèi)置對(duì)象的內(nèi)存地址,具體又分為獲取對(duì)象內(nèi)存地址以及內(nèi)存單元類型識(shí)別兩部分。進(jìn)一步,通過(guò)識(shí)別內(nèi)置對(duì)象內(nèi)存地址相關(guān)的內(nèi)存單元類型,提取出內(nèi)置對(duì)象的數(shù)據(jù)結(jié)構(gòu)特征。

      4.2.1 提取內(nèi)置對(duì)象列表

      首先需要提取腳本引擎中所有靜態(tài)、動(dòng)態(tài)內(nèi)置對(duì)象。為了提取腳本引擎所有的靜態(tài)內(nèi)置對(duì)象,我們采用深度優(yōu)先遍歷的方式,從文檔根節(jié)點(diǎn)出發(fā)依次訪問(wèn)文檔中所有節(jié)點(diǎn)。具體實(shí)現(xiàn)時(shí)我們使用for-in的方式進(jìn)行遍歷,對(duì)于訪問(wèn)到的每一個(gè)節(jié)點(diǎn),調(diào)用內(nèi)置操作符typeof 判斷其節(jié)點(diǎn)類型,并記錄對(duì)象類型節(jié)點(diǎn)的信息,即靜態(tài)內(nèi)置對(duì)象信息。同時(shí),為了避免遍歷過(guò)程陷入死循環(huán),我們標(biāo)記了所有已訪問(wèn)的節(jié)點(diǎn),并以集合的方式存儲(chǔ)。當(dāng)某次訪問(wèn)的節(jié)點(diǎn)位于標(biāo)記集合中時(shí),不再?gòu)脑摴?jié)點(diǎn)出發(fā)進(jìn)行更深層次的遍歷。

      腳本引擎中的動(dòng)態(tài)內(nèi)置對(duì)象需要調(diào)用腳本引擎API 創(chuàng)建。由于官方文檔的說(shuō)明信息不全,如針對(duì)Collab 這一類型的內(nèi)置對(duì)象,官方文檔中僅包含三個(gè)子方法說(shuō)明,而實(shí)際存在23 個(gè)子方法。因此,需要提取不在官方文檔中的腳本引擎API,以獲得完整的腳本引擎API 列表。我們同樣采用從文檔根節(jié)點(diǎn)出發(fā)深度優(yōu)先遍歷的方式,記錄類型為函數(shù)的節(jié)點(diǎn)信息,將其整理為最終的腳本引擎API 列表,使用提取出的API 列表可以獲得所有動(dòng)態(tài)內(nèi)置對(duì)象。接下來(lái),針對(duì)提取出的所有內(nèi)置對(duì)象,提取對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)特征。

      4.2.2 獲取內(nèi)置對(duì)象內(nèi)存地址

      為了獲得內(nèi)置對(duì)象內(nèi)存地址,需要使用腳本引擎API 創(chuàng)建和訪問(wèn)內(nèi)置對(duì)象。通過(guò)在腳本引擎API執(zhí)行前后插入檢查點(diǎn),結(jié)合動(dòng)態(tài)插裝技術(shù)來(lái)獲得內(nèi)置對(duì)象內(nèi)存地址。我們以圖5 中偽代碼為例,說(shuō)明如何獲得內(nèi)置對(duì)象內(nèi)存地址。

      為了獲取對(duì)象內(nèi)存地址,我們生成腳本引擎API 調(diào)用語(yǔ)句創(chuàng)建和訪問(wèn)內(nèi)置對(duì)象,對(duì)應(yīng)圖5 中②④,同時(shí)在每條腳本引擎API 調(diào)用語(yǔ)句前后設(shè)置檢查點(diǎn),對(duì)應(yīng)圖5 中①③⑤行。使用微軟提供的動(dòng)態(tài)調(diào)試工具Windbg 可以在檢查點(diǎn)判斷上一條API 調(diào)用語(yǔ)句返回值的類型,根據(jù)返回值的類型可以獲取部分由API 創(chuàng)建的動(dòng)態(tài)內(nèi)置對(duì)象內(nèi)存地址。除此之外,還可以依據(jù)腳本引擎活躍對(duì)象集合狀態(tài)的變化獲取內(nèi)置對(duì)象內(nèi)存地址。當(dāng)創(chuàng)建新內(nèi)置對(duì)象時(shí),活躍對(duì)象集合將相應(yīng)地增加新元素,通過(guò)分析活躍對(duì)象集合的變化可以獲取內(nèi)置對(duì)象內(nèi)存地址。

      4.2.3 識(shí)別內(nèi)存單元類型

      在獲取了內(nèi)置對(duì)象內(nèi)存地址后,需要識(shí)別內(nèi)存單元類型,具體為從對(duì)象內(nèi)存地址出發(fā),識(shí)別其對(duì)應(yīng)內(nèi)存區(qū)域中內(nèi)存單元數(shù)據(jù)的類型。接下來(lái),我們將結(jié)合圖6 闡述識(shí)別內(nèi)存單元數(shù)據(jù)類型的具體流程。

      為了提取對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,需要將內(nèi)存單元識(shí)別為指針類型,可變數(shù)值類型或固定數(shù)值類型。進(jìn)一步,依據(jù)指針類型內(nèi)存單元的指向關(guān)系,識(shí)別出層級(jí)結(jié)構(gòu)特征,并組合各個(gè)層級(jí)形成對(duì)象數(shù)據(jù)結(jié)構(gòu)特征。我們使用進(jìn)程的內(nèi)存布局信息作為先驗(yàn)知識(shí)來(lái)初步區(qū)分指針類型或數(shù)值類型。在Windows 系統(tǒng)中程序的內(nèi)存布局可大致分為代碼段,數(shù)據(jù)段,棧以及堆。對(duì)于指針類型的內(nèi)存單元,其存儲(chǔ)數(shù)值對(duì)應(yīng)的內(nèi)存地址位于堆中。通過(guò)獲取進(jìn)程運(yùn)行時(shí)內(nèi)存布局信息,得到堆起始和終止內(nèi)存地址,并依據(jù)內(nèi)存單元中數(shù)據(jù)數(shù)值是否位于堆范圍來(lái)初步區(qū)分指針類型與數(shù)值類型(超出堆范圍的數(shù)據(jù)可判定為數(shù)值類型)。使用進(jìn)程的內(nèi)存布局信息能識(shí)別大約90%的內(nèi)存單元類型,但仍有10%的數(shù)據(jù)因數(shù)值特殊而無(wú)法區(qū)分,如數(shù)值類型中存在位于堆的范圍的特殊值。此類數(shù)據(jù)對(duì)應(yīng)的內(nèi)存單元(后續(xù)稱為待定數(shù)值單元)將進(jìn)一步進(jìn)行內(nèi)存單元的類型識(shí)別。

      我們發(fā)現(xiàn)開(kāi)啟地址隨機(jī)化之后,在多次測(cè)試中,待定數(shù)值單元中的數(shù)值每次均位于堆范圍內(nèi)的概率較小。因此,可以進(jìn)行多次獨(dú)立測(cè)試,并統(tǒng)計(jì)待定數(shù)值單元中數(shù)值位于堆范圍的次數(shù),來(lái)判斷該待定數(shù)值單元的類型。同時(shí),由于固定數(shù)值類型在多次測(cè)試中將具有相同的數(shù)值,也可用該方法來(lái)區(qū)分可變數(shù)值類型與固定數(shù)值類型。從內(nèi)置對(duì)象內(nèi)存起始地址出發(fā)進(jìn)行層級(jí)展開(kāi)時(shí),我們通過(guò)配置參數(shù)的方式設(shè)置層級(jí)的個(gè)數(shù)以及層級(jí)的大小,并通過(guò)不斷實(shí)驗(yàn)調(diào)整配置參數(shù),以達(dá)到最好的區(qū)分效果。最終,結(jié)合各層級(jí)中的內(nèi)存單元類型可以提取出準(zhǔn)確的內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征。

      在提取出內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征后,需要將數(shù)據(jù)結(jié)構(gòu)特征轉(zhuǎn)換為數(shù)據(jù)結(jié)構(gòu)特征圖進(jìn)行存儲(chǔ)。在轉(zhuǎn)換的過(guò)程中,我們重點(diǎn)關(guān)注指針類型對(duì)應(yīng)的內(nèi)存單元,并將其指向關(guān)系對(duì)應(yīng)的內(nèi)存偏移映射為數(shù)據(jù)結(jié)構(gòu)特征圖中的邊。

      4.3 生成參數(shù)類型正確的API 序列

      官方文檔中對(duì)于腳本引擎API 的描述通常較為粗略,如針對(duì)腳本引擎API 參數(shù)的描述中僅說(shuō)明了參數(shù)的基礎(chǔ)類型(整數(shù)類型,布爾類型,對(duì)象類型等),而沒(méi)有說(shuō)明參數(shù)的細(xì)粒度類型。根據(jù)統(tǒng)計(jì),在Adobe Reader 內(nèi)置腳本引擎中總共包含163 種不同類型的內(nèi)置對(duì)象。當(dāng)一個(gè)腳本引擎API 的參數(shù)為對(duì)象類型時(shí),能接收腳本引擎中所有類型的內(nèi)置對(duì)象,且不會(huì)提示類型錯(cuò)誤。然而,當(dāng)輸入?yún)?shù)的細(xì)粒度類型與腳本引擎API 參數(shù)需求的細(xì)粒度類型不符時(shí),API 無(wú)法正確處理所提供的參數(shù),從而無(wú)法產(chǎn)生對(duì)象別名關(guān)系。我們發(fā)現(xiàn)當(dāng)為腳本引擎API 提供正確類型的對(duì)象參數(shù)時(shí),涉及的參數(shù)內(nèi)存訪問(wèn)模式能夠匹配對(duì)應(yīng)的對(duì)象數(shù)據(jù)結(jié)構(gòu)特征。

      我們按照腳本引擎內(nèi)置對(duì)象具體數(shù)據(jù)結(jié)構(gòu)的不同,劃分內(nèi)置對(duì)象的細(xì)粒度類型。相較于粗粒度類型,即基礎(chǔ)類型(如對(duì)象類型,字符串類型,整型等),細(xì)粒度類型能夠更全面地展現(xiàn)不同腳本引擎內(nèi)置對(duì)象的差異。使用內(nèi)置對(duì)象細(xì)粒度類型,我們可以在調(diào)用腳本引擎API 時(shí)針對(duì)性地搭配內(nèi)置對(duì)象,在最大程度上保證API 調(diào)用具有合法語(yǔ)義,同時(shí)也減少了運(yùn)行時(shí)錯(cuò)誤的產(chǎn)生,間接增加了代碼覆蓋率。

      在獲得腳本引擎API 對(duì)象參數(shù)信息之后,將生成腳本引擎API 調(diào)用語(yǔ)句。對(duì)于API 需求的對(duì)象類型參數(shù),我們根據(jù)參數(shù)候選集,選取類型符合的內(nèi)置對(duì)象作為輸入。當(dāng)參數(shù)包含多個(gè)候選對(duì)象時(shí),需分別使用不同候選對(duì)象生成對(duì)應(yīng)的API 調(diào)用語(yǔ)句。同時(shí),在單個(gè)測(cè)試樣本的生成過(guò)程中,我們以列表的形式記錄已生成的內(nèi)置對(duì)象,方便后續(xù)使用。當(dāng)引用新的靜態(tài)內(nèi)置對(duì)象或由于API 調(diào)用產(chǎn)生了新的動(dòng)態(tài)內(nèi)置對(duì)象時(shí),需要相應(yīng)地更改對(duì)象列表的內(nèi)容。對(duì)于其他基礎(chǔ)類型的API 參數(shù)(整數(shù)類型,字符串類型等),我們通過(guò)構(gòu)建常量表的方式,每次采用隨機(jī)策略從常量表中選擇類型合適的數(shù)據(jù)填充。

      4.3.1 API 參數(shù)內(nèi)存訪問(wèn)模式

      對(duì)于API 參數(shù)內(nèi)存訪問(wèn)模式M,我們采用如下定義:

      M=<函數(shù)名,參數(shù)位次,內(nèi)存解引用序列>

      其中函數(shù)名為具體腳本引擎API 的名稱,參數(shù)位次代表參數(shù)在API 調(diào)用時(shí)對(duì)應(yīng)的序號(hào),而內(nèi)存解引用序列為該參數(shù)被使用時(shí),按照層級(jí)的訪問(wèn)順序,依次對(duì)應(yīng)層級(jí)跳轉(zhuǎn)時(shí)的內(nèi)存偏移。

      以Collab 內(nèi)置對(duì)象下屬getInitiatorSource方法為例,該方法在使用時(shí)需要兩個(gè) Stream 類型或類Stream 類型的參數(shù),而官方文檔中僅說(shuō)明了兩個(gè)參數(shù)為基礎(chǔ)對(duì)象類型。對(duì)于Collab.getInitiatorSource 方法中參數(shù)的內(nèi)存訪問(wèn)模式和對(duì)應(yīng)的對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,我們總結(jié)如圖7 所示。以Collab.getInitiatorSource的第二個(gè)參數(shù)為例,提取出的內(nèi)存訪問(wèn)模式可表示為。

      在圖7左側(cè)標(biāo)號(hào)①②的語(yǔ)句為具體腳本引擎API,在語(yǔ)句①中通過(guò)API Collab.newWrStream ToCosObj創(chuàng)建了FileStream 類型的內(nèi)置對(duì)象ObjA,并作為語(yǔ)句②中API 的第二個(gè)參數(shù)使用。圖7左側(cè)下半部分為API Collab.getInitiatorSource 對(duì)應(yīng)函數(shù)體的偽代碼,函數(shù)體中的*號(hào)代表指針解引用操作,即讀取指針指向內(nèi)存單元中的數(shù)據(jù)。在腳本引擎 API Collab.getInitiatorSource 對(duì)應(yīng)的函數(shù)體中,首先對(duì)第二個(gè)參數(shù)進(jìn)行了指針解引用操作,并將讀取的值存儲(chǔ)于變量v1中,其內(nèi)存訪問(wèn)模式偏移為0x0(下劃線部分)。之后,通過(guò)將變量v1傳給函數(shù)G,并將函數(shù)的返回值賦值給變量v2。函數(shù)G 針對(duì)傳入的參數(shù)再次進(jìn)行了指針解引用操作,此時(shí)的內(nèi)存訪問(wèn)模式偏移為0x4(下劃線部分)。據(jù)此,可以發(fā)現(xiàn)Collab.getInitiatorSource 對(duì)應(yīng)的函數(shù)F 中對(duì)第二個(gè)參數(shù)進(jìn)行了兩次指針解引用操作,對(duì)應(yīng)的內(nèi)存訪問(wèn)模式偏移分別為0x0以及0x4。

      在圖7 右側(cè)為FileStream類型內(nèi)置對(duì)象的部分?jǐn)?shù)據(jù)結(jié)構(gòu)特征,其中存在0x0 和0x4 的特征信息(虛線框部分,分別為第二層級(jí)到第三層級(jí),以及第三層級(jí)到第四層級(jí)對(duì)應(yīng)的內(nèi)存偏移),與Collab.getInitiatorSource 函數(shù)第二個(gè)參數(shù)的內(nèi)存訪問(wèn)模式相匹配。同時(shí),不同內(nèi)置對(duì)象的數(shù)據(jù)結(jié)構(gòu)特征擁有不同的內(nèi)存偏移信息,而不同腳本引擎API 中對(duì)象參數(shù)的內(nèi)存訪問(wèn)模式也不同。因此,可以通過(guò)匹配腳本引擎API 對(duì)象參數(shù)的內(nèi)存訪問(wèn)模式與內(nèi)置對(duì)象內(nèi)存結(jié)構(gòu)特征,推斷腳本引擎API 對(duì)象參數(shù)的候選列表。

      對(duì)于兩個(gè)不同類型的內(nèi)置對(duì)象,其數(shù)據(jù)結(jié)構(gòu)特征中包含的偏移信息分別為(0x1,0x2,0x4)以及(0x1,0x2,0x6,0x8),而腳本引擎API對(duì)象參數(shù)內(nèi)存訪問(wèn)模式對(duì)應(yīng)的偏移為(0x1,0x2),則該腳本引擎API 參數(shù)候選集將同時(shí)包含上述兩種內(nèi)置對(duì)象。精確的靜態(tài)分析技術(shù)需要考慮多種因素,如控制流信息,數(shù)據(jù)依賴等,針對(duì)大型腳本引擎存在性能開(kāi)銷過(guò)大的問(wèn)題。我們的目標(biāo)在于盡可能地縮小測(cè)試樣本生成時(shí)API 的搜索空間,因此我們提出了一種上下文不敏感,路徑不敏感,流不敏感的過(guò)程間數(shù)據(jù)流分析方法,用于提取API 對(duì)象參數(shù)的內(nèi)存訪問(wèn)模式?;趦?nèi)存訪問(wèn)模式,可以獲得參數(shù)類型的候選列表,即正確參數(shù)類型的超集。該方法在縮小腳本引擎API 參數(shù)搜索空間的同時(shí),保證覆蓋正確的API 對(duì)象參數(shù)類型,減少參數(shù)類型錯(cuò)誤導(dǎo)致的運(yùn)行時(shí)異常。接下來(lái),我們將介紹如何提取腳本引擎API 對(duì)象參數(shù)的內(nèi)存訪問(wèn)模式。

      4.3.2 提取API 參數(shù)內(nèi)存訪問(wèn)模式

      不同于已有的基于控制流圖或程序調(diào)用圖的靜態(tài)分析技術(shù),我們將重心放在提取腳本引擎API 對(duì)象參數(shù)的內(nèi)存訪問(wèn)模式,主要關(guān)注API 實(shí)現(xiàn)體中與對(duì)象類型參數(shù)相關(guān)的處理邏輯。

      我們的分析方法為上下文不敏感以及路徑不敏感,因此我們不關(guān)注API 實(shí)現(xiàn)體中的分支或循環(huán)等語(yǔ)句的控制條件,粗粒度地認(rèn)為API 實(shí)現(xiàn)體中每一條語(yǔ)句均有被執(zhí)行的可能?;跀?shù)據(jù)流分析的思路,我們認(rèn)為API 實(shí)現(xiàn)體中涉及對(duì)象參數(shù)的語(yǔ)句均為分析目標(biāo)。我們提出的分析方法為過(guò)程間的數(shù)據(jù)流分析,因此遇到函數(shù)調(diào)用時(shí),需要展開(kāi)函數(shù)調(diào)用,嵌套分析函數(shù)調(diào)用內(nèi)部的處理邏輯。在匯編語(yǔ)言中,函數(shù)調(diào)用又可細(xì)分為直接函數(shù)調(diào)用以及間接函數(shù)調(diào)用。直接函數(shù)調(diào)用以函數(shù)名為句柄調(diào)用函數(shù),能在靜態(tài)分析時(shí)直接展開(kāi);間接函數(shù)調(diào)用通過(guò)函數(shù)表的方式進(jìn)行函數(shù)調(diào)用,僅能在動(dòng)態(tài)執(zhí)行時(shí)展開(kāi)。接下來(lái),以圖8 的一段函數(shù)實(shí)現(xiàn)體為例,具體介紹所使用的靜態(tài)分析方法。

      在圖8 中,腳本引擎API 對(duì)應(yīng)的實(shí)現(xiàn)體F,其使用兩個(gè)參數(shù)分別用arg1和arg2表示,其中arg1和arg2對(duì)應(yīng)的參數(shù)類型為對(duì)象。為了獲取參數(shù)的內(nèi)存訪問(wèn)模式,需要跟蹤函數(shù)實(shí)現(xiàn)體中arg1參數(shù)的使用。在函數(shù)實(shí)現(xiàn)體F 中,arg1被作為另一函數(shù)G 的參數(shù)使用,因而需要進(jìn)一步展開(kāi)函數(shù)G 以分析函數(shù)G 中參數(shù)arg1的使用情況。此處,函數(shù)G 表現(xiàn)為直接函數(shù)調(diào)用,可以直接展開(kāi)獲得具體函數(shù)實(shí)現(xiàn)。對(duì)于間接調(diào)用的情況,由于無(wú)法獲取具體函數(shù)實(shí)現(xiàn),我們將在稍后進(jìn)行說(shuō)明。

      在函數(shù)G 中針對(duì)arg1進(jìn)行了兩次指針解引用操作,并最終返回指針解引用的結(jié)果。兩次指針解引用分別對(duì)應(yīng)的固定偏移值為0x4 和0x8。因此,我們將偏移值0x4 和0x8 作為函數(shù)G 中arg1參數(shù)的內(nèi)存訪問(wèn)模式,記為。同時(shí),該固定偏移與內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征中的偏移對(duì)應(yīng),代表著對(duì)象參數(shù)的類型信息。同理,可以提取函數(shù)H 中參數(shù)的內(nèi)存訪問(wèn)模式,記為。對(duì)于函數(shù)F,通過(guò)分析可以得知,參數(shù)arg1被函數(shù)G 使用,而參數(shù)arg2被函數(shù)H 所使用。結(jié)合函數(shù)G 和函數(shù)H 提取出的參數(shù)內(nèi)存訪問(wèn)模式,函數(shù)F 的參數(shù)內(nèi)存訪問(wèn)模式可以歸納為。進(jìn)一步,我們稱函數(shù)F 為父函數(shù),函數(shù)H 和函數(shù)G 為子函數(shù),父函數(shù)參數(shù)的內(nèi)存訪問(wèn)模式為所有子函數(shù)參數(shù)內(nèi)存訪問(wèn)模式的并集。對(duì)于間接調(diào)用的情況,以圖9 中代碼為例進(jìn)行說(shuō)明。

      在函數(shù)P 的實(shí)現(xiàn)體中,Indirect-Call 代表間接函數(shù)調(diào)用,其將arg1作為參數(shù)使用,并將函數(shù)調(diào)用的返回值賦值給了變量b,后續(xù)變量b作為直接函數(shù)調(diào)用Q 的參數(shù)使用。對(duì)于圖9 中的間接函數(shù)調(diào)用,由于無(wú)法獲得具體函數(shù)實(shí)現(xiàn)體進(jìn)行參數(shù)分析,我們粗粒度地認(rèn)為變量b等同于參數(shù)arg1,即變量b提取出的內(nèi)存訪問(wèn)模式也作為參數(shù)arg1的內(nèi)存訪問(wèn)模式。進(jìn)一步,通過(guò)分析直接函數(shù)調(diào)用Q的實(shí)現(xiàn)體,可以提取出函數(shù)Q 中參數(shù)arg1對(duì)應(yīng)的內(nèi)存訪問(wèn)模式,記為。最終,可以得到變量b對(duì)應(yīng)的內(nèi)存訪問(wèn)模式為,從而可以獲得函數(shù)P中參數(shù)的內(nèi)存訪問(wèn)模式為。

      使用靜態(tài)分析的方式結(jié)合所有腳本引擎API 的實(shí)現(xiàn)體,可以提取出對(duì)象類型參數(shù)的內(nèi)存訪問(wèn)模式。進(jìn)一步,將內(nèi)存訪問(wèn)模式與對(duì)象數(shù)據(jù)結(jié)構(gòu)信息匹配,獲得腳本引擎API 參數(shù)的細(xì)粒度信息。由于使用粗粒度的提取方式,最終提取結(jié)果為正確參數(shù)類型的超集,如針對(duì)Collab.getInitiatorSource 這一API,其正確參數(shù)類型為FileStream 類型,而提取出的參數(shù)候選集中包含 FileStream 類型,Stream 類型以及ReadStream 類型。除此之外,可以用同樣的方法提取腳本引擎API 返回值的內(nèi)存訪問(wèn)模式,并采用同樣的方式進(jìn)行存儲(chǔ)(對(duì)于API 返回值不像參數(shù)一樣區(qū)分序號(hào),將統(tǒng)一用R 代替,如)。

      4.4 識(shí)別對(duì)象別名關(guān)系

      我們將3.3 中生成的測(cè)試樣本輸入腳本引擎,動(dòng)態(tài)識(shí)別測(cè)試樣本運(yùn)行過(guò)程中的內(nèi)置對(duì)象別名關(guān)系。由于內(nèi)置對(duì)象別名關(guān)系的本質(zhì)在于不同對(duì)象內(nèi)部的共享內(nèi)存單元,相較于已有別名關(guān)系識(shí)別方法,我們將內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征轉(zhuǎn)化為對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)特征圖,根據(jù)數(shù)據(jù)結(jié)構(gòu)特征圖狀態(tài)的變化來(lái)高效準(zhǔn)確地識(shí)別內(nèi)置對(duì)象別名關(guān)系。

      在該節(jié)中,我們著重表述如何依據(jù)數(shù)據(jù)結(jié)構(gòu)特征圖識(shí)別內(nèi)置對(duì)象別名關(guān)系。首先,對(duì)于腳本引擎中的每個(gè)內(nèi)置對(duì)象,按照3.2 節(jié)中描述的方法,獲取對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)特征圖。當(dāng)出現(xiàn)對(duì)象別名關(guān)系時(shí),不同對(duì)象對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)特征圖之間將出現(xiàn)新的連通節(jié)點(diǎn),對(duì)應(yīng)別名關(guān)系中的共享內(nèi)存單元。接下來(lái),依據(jù)建立對(duì)象別名關(guān)系前后,對(duì)象數(shù)據(jù)結(jié)構(gòu)特征圖的變化來(lái)具體說(shuō)明如何識(shí)別對(duì)象別名關(guān)系。以Stream 類型和ReadStream 類型的內(nèi)置對(duì)象為例,在建立別名關(guān)系之前,其數(shù)據(jù)結(jié)構(gòu)特征圖如圖10 所示。

      在圖10 中左半部分Obj1_Id 標(biāo)識(shí)的數(shù)據(jù)結(jié)構(gòu)特征圖代表Stream 類型的內(nèi)置對(duì)象,右半部分Obj2_Id標(biāo)識(shí)的數(shù)據(jù)結(jié)構(gòu)特征圖代表ReadStream 類型的內(nèi)置對(duì)象,Obj1_Id 以及Obj2_Id 分別為內(nèi)置對(duì)象運(yùn)行時(shí)的內(nèi)存地址。由于執(zhí)行腳本引擎API 引起了內(nèi)置對(duì)象的變化,需要重新計(jì)算內(nèi)置對(duì)象對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)特征圖。當(dāng)執(zhí)行完某條腳本引擎API 之后,Stream 對(duì)象和ReadStream 對(duì)應(yīng)數(shù)據(jù)結(jié)構(gòu)特征圖的變化如圖11所示。

      在圖11 中用我們虛線框代表別名關(guān)系對(duì)應(yīng)的節(jié)點(diǎn),即別名關(guān)系對(duì)應(yīng)的共享內(nèi)存單元。我們采用圖12 中描述的算法,通過(guò)對(duì)比腳本引擎API 執(zhí)行前后對(duì)象數(shù)據(jù)結(jié)構(gòu)特征圖的狀態(tài)變化,識(shí)別內(nèi)置對(duì)象別名關(guān)系。

      我們?cè)O(shè)置監(jiān)控粒度為單條腳本語(yǔ)句,如圖12 所示,首先我們初始化最終輸出的別名關(guān)系內(nèi)置對(duì)象集合R為空集。在執(zhí)行腳本引擎API 前,之后,依據(jù)內(nèi)置對(duì)象內(nèi)存地址集合S,計(jì)算對(duì)應(yīng)的對(duì)象數(shù)據(jù)結(jié)構(gòu)特征圖集GA(對(duì)應(yīng)算法中步驟2,3,4)。當(dāng)執(zhí)行完某條腳本語(yǔ)句后,再次計(jì)算內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征圖集,記為GB。最后,以對(duì)象內(nèi)存地址為索引,對(duì)比先后兩次生成的對(duì)象數(shù)據(jù)結(jié)構(gòu)特征圖,根據(jù)數(shù)據(jù)結(jié)構(gòu)特征圖的變化來(lái)識(shí)別內(nèi)置對(duì)象別名關(guān)系。

      當(dāng)建立內(nèi)置對(duì)象別名關(guān)系時(shí),共享內(nèi)存單元對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)特征圖節(jié)點(diǎn)(圖11 中虛線框節(jié)點(diǎn))的祖先屬性將發(fā)生變化。因?yàn)楣蚕砉?jié)點(diǎn)可以歸屬于不同內(nèi)置對(duì)象,所以該節(jié)點(diǎn)的祖先屬性將增多(對(duì)應(yīng)圖12中步驟11)。我們依據(jù)腳本引擎API 執(zhí)行前后是否存在數(shù)據(jù)結(jié)構(gòu)特征圖節(jié)點(diǎn)的祖先屬性符合上述變化,來(lái)判斷是否建立了內(nèi)置對(duì)象別名關(guān)系。

      通常,在單個(gè)測(cè)試樣本中,涉及的腳本引擎內(nèi)置對(duì)象數(shù)量較少,因此每次重新計(jì)算數(shù)據(jù)結(jié)構(gòu)特征圖的性能開(kāi)銷較小。相比于已有的別名關(guān)系識(shí)別方法,我們提出的基于數(shù)據(jù)結(jié)構(gòu)特征的方法具有更高的識(shí)別效率。

      5 利用別名關(guān)系檢測(cè)釋放后使用漏洞

      內(nèi)置對(duì)象別名關(guān)系有助于檢測(cè)與對(duì)象內(nèi)存操作相關(guān)的程序漏洞。通過(guò)建立內(nèi)置對(duì)象別名關(guān)系,并搭配合適的腳本引擎API 釋放內(nèi)置對(duì)象,可以在多個(gè)對(duì)象內(nèi)部引入懸掛指針,進(jìn)而觸發(fā)釋放后使用漏洞。該部分具體分為三個(gè)部分進(jìn)行介紹,分別為釋放后使用漏洞的檢測(cè)流程,提取特殊API 序列以及生成測(cè)試樣本檢測(cè)釋放后使用漏洞。

      5.1 釋放后使用漏洞的檢測(cè)流程

      在釋放后使用漏洞中,根本原因是訪問(wèn)了被釋放內(nèi)存區(qū)域,從而觸發(fā)程序錯(cuò)誤。對(duì)于釋放后使用漏洞,必不可少的環(huán)節(jié)為釋放對(duì)象產(chǎn)生懸掛指針以及訪問(wèn)懸掛指針。同時(shí),必須遵循釋放操作在前,使用操作在后的原則,否則無(wú)法觸發(fā)釋放后使用漏洞。因此,需要針對(duì)內(nèi)置對(duì)象提取釋放API 序列以及使用API 序列,并基于提取的API 序列生成測(cè)試樣本以檢測(cè)釋放后使用漏洞,整個(gè)系統(tǒng)的具體檢測(cè)流程如圖13 所示。

      整個(gè)檢測(cè)流程按從左到右的順序執(zhí)行,核心在于利用內(nèi)置對(duì)象別名關(guān)系。為了提取釋放對(duì)象API序列以及使用對(duì)象API 序列,需要使用不同的判斷邏輯。進(jìn)一步,利用提取出的釋放序列和使用序列生成測(cè)試樣本以檢測(cè)腳本引擎中的程序漏洞。

      對(duì)于建立的別名關(guān)系的兩個(gè)內(nèi)置對(duì)象(記為內(nèi)置對(duì)象A以及內(nèi)置對(duì)象B),分別獲取API 測(cè)試樣本運(yùn)行時(shí)的對(duì)象內(nèi)存地址。進(jìn)一步,依據(jù)對(duì)象內(nèi)存地址以及對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,獲取別名內(nèi)存單元對(duì)應(yīng)的內(nèi)存地址,又稱為別名地址。我依據(jù)API 測(cè)試樣本運(yùn)行時(shí)是否滿足設(shè)定的內(nèi)置對(duì)象釋放條件來(lái)提取釋放對(duì)象API 序列(具體條件在4.2 節(jié)中進(jìn)行描述)。在提取使用對(duì)象API 序列時(shí),我們針對(duì)別名地址設(shè)置內(nèi)存訪問(wèn)斷點(diǎn)。通過(guò)監(jiān)控測(cè)試樣本運(yùn)行過(guò)程中內(nèi)存斷點(diǎn)的觸發(fā)情況,獲取使用對(duì)象API 序列。

      最后,需要按照一定模式組合釋放對(duì)象API 序列和使用對(duì)象API序列,并在釋放對(duì)象API序列執(zhí)行前建立內(nèi)置對(duì)象別名關(guān)系,以檢測(cè)腳本引擎中的釋放后使用漏洞。

      5.2 提取特殊API 序列

      在本節(jié)中,我們主要敘述如何提取釋放對(duì)象API 序列以及使用對(duì)象API 序列,提取過(guò)程對(duì)應(yīng)的具體流程如圖14 所示。我們首先使用動(dòng)態(tài)插裝技術(shù)獲得內(nèi)置對(duì)象內(nèi)存地址,之后結(jié)合建立的對(duì)象別名關(guān)系獲得別名單元的內(nèi)存地址。根據(jù)測(cè)試樣本運(yùn)行過(guò)程中,別名單元內(nèi)存地址是否滿足特定釋放/使用模式,提取對(duì)應(yīng)的釋放/使用API 序列。

      5.2.1 提取釋放API 序列

      首先介紹釋放對(duì)象API 序列的提取,我們著重關(guān)注對(duì)象內(nèi)部共享內(nèi)存區(qū)域的釋放情況,通過(guò)判定對(duì)象內(nèi)部共享內(nèi)存區(qū)域是否被釋放,來(lái)提取釋放對(duì)象API 序列。我們具體使用3 種檢查策略來(lái)判定共享內(nèi)存區(qū)域是否被釋放,分別為判定別名區(qū)域中數(shù)據(jù)的狀態(tài),判定內(nèi)置對(duì)象存活性以及判定系統(tǒng)釋放函數(shù)是否觸發(fā)。

      我們將根據(jù)3.2 節(jié)中提取的API 參數(shù)信息,隨機(jī)生成API 調(diào)用序列。通過(guò)歸納已知釋放對(duì)象API 序列的特征,在填充API 參數(shù)時(shí),盡量選擇空值作為參數(shù),如長(zhǎng)度為0 的字符串,數(shù)字0 等。除此之外,還可以利用腳本引擎垃圾回收機(jī)制釋放內(nèi)置對(duì)象。通過(guò)消除內(nèi)置對(duì)象的引用或引入臨時(shí)變量的方式可以影響對(duì)象生命周期,如將指向內(nèi)置對(duì)象的變量指向空對(duì)象,或不使用變量存儲(chǔ)API 返回值,進(jìn)而觸發(fā)腳本引擎垃圾回收機(jī)制釋放內(nèi)置對(duì)象。

      在第一種檢查策略中,我們根據(jù)別名區(qū)域中數(shù)據(jù)的狀態(tài)來(lái)判定對(duì)象是否被釋放。當(dāng)內(nèi)置對(duì)象被系統(tǒng)回收時(shí),對(duì)象內(nèi)存區(qū)域中的數(shù)據(jù)被填充為特殊值,該特殊值可通過(guò)簡(jiǎn)單人工分析獲得。根據(jù)別名地址中的數(shù)據(jù)是否等于該特殊值,可以判斷別名區(qū)域是否被釋放,進(jìn)而判定API 序列是否觸發(fā)了釋放行為。

      第二種檢查策略直接判斷內(nèi)置對(duì)象存活性。在第2章中我們介紹了活躍對(duì)象集合的概念,通過(guò)檢查內(nèi)置對(duì)象是否從活躍對(duì)象集合消失來(lái)判定API 序列是否觸發(fā)了釋放行為。

      第三種檢查策略為監(jiān)控系統(tǒng)釋放函數(shù)。腳本引擎本質(zhì)為操作系統(tǒng)中的進(jìn)程,一切內(nèi)存操作均需調(diào)用操作系統(tǒng)的底層函數(shù),即使用API 創(chuàng)建和釋放內(nèi)置對(duì)象的同時(shí),也調(diào)用了操作系統(tǒng)的創(chuàng)建及釋放函數(shù)。對(duì)于操作系統(tǒng)底層的釋放函數(shù),其參數(shù)為需要釋放的內(nèi)存地址??梢酝ㄟ^(guò)監(jiān)控底層釋放函數(shù)的調(diào)用,判斷參數(shù)值是否等于對(duì)象別名單元內(nèi)存地址,決定當(dāng)前API 序列是否觸發(fā)了釋放行為。

      在提取釋放對(duì)象API 序列的過(guò)程中,我們依舊選擇單個(gè)腳本引擎API 作為插裝粒度,并在單條API調(diào)用語(yǔ)句前后加入檢查點(diǎn)。每當(dāng)遭遇檢查點(diǎn)時(shí),需要實(shí)施上述三種檢查策略,判斷當(dāng)前情景下是否發(fā)生了內(nèi)置對(duì)象釋放行為。同時(shí),可以在單個(gè)測(cè)試樣本中同時(shí)監(jiān)控多個(gè)存在別名關(guān)系的內(nèi)置對(duì)象,提高測(cè)試效率。

      5.2.2 提取使用API 序列

      在提取使用對(duì)象API 序列時(shí),無(wú)需關(guān)注對(duì)象的狀態(tài),即對(duì)象存活與否與是否能訪問(wèn)別名區(qū)域中的數(shù)據(jù)無(wú)直接關(guān)系。雖然,正常的使用規(guī)范要求對(duì)象被釋放后無(wú)法訪問(wèn)對(duì)象內(nèi)部數(shù)據(jù)。但是,當(dāng)內(nèi)置對(duì)象被釋放后仍能成功訪問(wèn)其內(nèi)部數(shù)據(jù),說(shuō)明該內(nèi)置對(duì)象未設(shè)置相應(yīng)的釋放標(biāo)志位,因此更容易產(chǎn)生懸掛指針。綜上,在提取使用對(duì)象API 序列時(shí),僅關(guān)心對(duì)象內(nèi)部的別名區(qū)域是否能被成功訪問(wèn)。

      接下來(lái)介紹如何提取使用API 序列。為了提取使用API 序列,在生成API 測(cè)試樣本時(shí),將待測(cè)內(nèi)置對(duì)象作為API 參數(shù)使用以滿足內(nèi)置對(duì)象訪問(wèn)條件。我們利用Windbg 調(diào)試工具提供的內(nèi)存讀寫(xiě)監(jiān)控功能來(lái)判斷當(dāng)前API 序列是否能夠訪問(wèn)特定內(nèi)置對(duì)象。通過(guò)將內(nèi)置對(duì)象內(nèi)部別名單元內(nèi)存地址設(shè)置為讀斷點(diǎn),依據(jù)API 測(cè)試樣本運(yùn)行過(guò)程中是否觸發(fā)了讀斷點(diǎn),提取對(duì)應(yīng)的使用API 序列。我們針對(duì)每一對(duì)存在別名關(guān)系的內(nèi)置對(duì)象,分別提取對(duì)應(yīng)的使用API 序列。

      5.3 生成測(cè)試樣本檢測(cè)釋放后使用漏洞

      為了檢測(cè)腳本引擎中的釋放后使用漏洞,需要構(gòu)造特殊的腳本引擎API 調(diào)用序列以滿足釋放后使用漏洞的模式,對(duì)應(yīng)到腳本引擎中為先調(diào)用釋放對(duì)象API 序列,后調(diào)用使用對(duì)象API 序列。由于單懸掛指針導(dǎo)致的釋放后使用漏洞容易被修補(bǔ),需要引入內(nèi)置對(duì)象別名關(guān)系以創(chuàng)建多懸掛指針,具體的測(cè)試樣本生成策略如圖15 所示。

      對(duì)于存在別名關(guān)系的內(nèi)置對(duì)象(記為對(duì)象A以及對(duì)象B),我們分別搭配對(duì)應(yīng)的釋放API 序列集合以及使用API序列集合,如圖15中對(duì)象A搭配釋放API序列集合,對(duì)象B搭配使用API 序列集合。按照第2章中介紹的別名關(guān)系釋放后使用漏洞觸發(fā)模式,我們選取釋放API 序列集合和使用API 序列集合中的元素進(jìn)行組合,并遵循釋放在前使用在后的順序,生成不同測(cè)試樣本。同時(shí),在執(zhí)行釋放API 序列之前需要先建立內(nèi)置對(duì)象別名關(guān)系。

      在實(shí)驗(yàn)中我們發(fā)現(xiàn),為了提高內(nèi)置對(duì)象間別名關(guān)系的出現(xiàn)概率,需要腳本引擎API 間需要具有較強(qiáng)的關(guān)聯(lián)性。通過(guò)提取API 參數(shù)和返回值的內(nèi)存訪問(wèn)模式,可分別獲得參數(shù)以及返回值的候選對(duì)象列表,記為Param_Set 以及Return_Set,而不同腳本引擎API 之間Param_Set 和Return_Set 存在交集。在生成具體測(cè)試樣本時(shí),我們考慮將腳本引擎API 的返回值作為另一API 的參數(shù),以增加API 之間的關(guān)聯(lián)性。同時(shí),為了保證合理語(yǔ)義,如API-1 的Param_Set與API-2的Return_Set存在交集,在生成測(cè)試樣本時(shí),將優(yōu)先調(diào)用API-2 創(chuàng)建內(nèi)置對(duì)象,再將API-2 的返回值作為API-1 的參數(shù)。最后,將產(chǎn)生的測(cè)試樣本輸入腳本引擎,以檢測(cè)腳本引擎中的釋放后使用漏洞。

      6 實(shí)驗(yàn)結(jié)果評(píng)估

      本章中,我們針對(duì)論文中提出的內(nèi)置對(duì)象別名關(guān)系識(shí)別方法設(shè)計(jì)多項(xiàng)評(píng)估實(shí)驗(yàn),分別從別名關(guān)系準(zhǔn)確率,測(cè)試樣本生成效率以及別名關(guān)系識(shí)別開(kāi)銷三個(gè)方面進(jìn)行評(píng)估。同時(shí),對(duì)于提出的釋放后使用漏洞檢測(cè)方法,我們?cè)谡鎸?shí)軟件Adobe Reader 內(nèi)嵌JavaScript 引擎上實(shí)施了漏洞檢測(cè)實(shí)驗(yàn),評(píng)估該方法檢測(cè)釋放后使用漏洞的性能,驗(yàn)證該方法的有效性和可用性。

      6.1 別名關(guān)系準(zhǔn)確率

      論文的一個(gè)核心點(diǎn)在于利用對(duì)象數(shù)據(jù)結(jié)構(gòu)特征建立并識(shí)別內(nèi)置對(duì)象別名關(guān)系,因此需要評(píng)估內(nèi)置對(duì)象別名關(guān)系的準(zhǔn)確性。

      為了評(píng)估測(cè)試樣本中內(nèi)置對(duì)象別名關(guān)系是否準(zhǔn)確,我們生成了長(zhǎng)度相同的測(cè)試樣本,分批識(shí)別其中的內(nèi)置對(duì)象別名關(guān)系。對(duì)于每個(gè)待測(cè)樣本,依據(jù)提取出的腳本引擎API 參數(shù)類型信息,生成100 條腳本引擎API 調(diào)用語(yǔ)句,并動(dòng)態(tài)監(jiān)測(cè)樣本運(yùn)行過(guò)程中是否建立了內(nèi)置對(duì)象間別名關(guān)系。最終,我們統(tǒng)計(jì)了100 個(gè)測(cè)試樣本的運(yùn)行結(jié)果,總計(jì)包含18354 條別名關(guān)系記錄,平均每個(gè)測(cè)試樣本包含183 條別名關(guān)系,平均每條腳本引擎API 生成了1.8 個(gè)內(nèi)置對(duì)象別名關(guān)系。通過(guò)對(duì)18354 條別名關(guān)系記錄進(jìn)行去重,我們最終提取出284 條不同的內(nèi)置對(duì)象別名關(guān)系,共涉及27 個(gè)不同類型的內(nèi)置對(duì)象,占動(dòng)態(tài)內(nèi)置對(duì)象比例的51%。

      我們采用圖16 中的模式來(lái)評(píng)估內(nèi)置對(duì)象別名關(guān)系識(shí)別的準(zhǔn)確性。針對(duì)一組待驗(yàn)證別名關(guān)系的內(nèi)置對(duì)象,變更其中一個(gè)內(nèi)置對(duì)象的狀態(tài),如改變對(duì)象屬性值等,并監(jiān)控另一內(nèi)置對(duì)象的變化。依據(jù)待驗(yàn)證別名關(guān)系的內(nèi)置對(duì)象狀態(tài)是否同步變化,來(lái)判定內(nèi)置對(duì)象別名關(guān)系是否準(zhǔn)確。

      存在別名關(guān)系的兩個(gè)內(nèi)置對(duì)象分別記為ObjA和ObjB,并將ObjA對(duì)象與ObjB對(duì)象最終存在別名關(guān)系的內(nèi)存單元抽象為ObjA.X.Y以及ObjB.E.F(對(duì)應(yīng)圖16 中共享內(nèi)存單元M)。初始時(shí),共享內(nèi)存單元M中存儲(chǔ)的數(shù)值為1。我們使用腳本引擎API 對(duì)ObjA.X.Y進(jìn)行賦值操作,更改M中的數(shù)值為2。之后,通過(guò)ObjB.E.F讀取M中存儲(chǔ)的數(shù)值,并判斷讀取的數(shù)值是否等于更改后的數(shù)值。當(dāng)讀取的數(shù)值為1 時(shí),我們認(rèn)為識(shí)別ObjA對(duì)象和ObjB對(duì)象間別名關(guān)系時(shí)產(chǎn)生了誤報(bào);當(dāng)讀取的數(shù)值為2 時(shí),我們認(rèn)為對(duì)象別名關(guān)系識(shí)別正確。我們采用如上方式對(duì)提取出的284 條內(nèi)置對(duì)象別名關(guān)系進(jìn)行了評(píng)估,并人工審查了評(píng)估結(jié)果。最終,我們證明了提取出的284 條內(nèi)置對(duì)象別名關(guān)系真實(shí)存在,即提出的內(nèi)置對(duì)象別名關(guān)系識(shí)別方法沒(méi)有產(chǎn)生誤報(bào)。

      同樣,我們采用圖16中的模式來(lái)評(píng)估文中提出的別名關(guān)系識(shí)別方法是否存在漏報(bào)現(xiàn)象。我們將測(cè)試范圍設(shè)置為全體內(nèi)置對(duì)象,即腳本引擎中存活的所有靜態(tài)內(nèi)置對(duì)象以及動(dòng)態(tài)內(nèi)置對(duì)象。通過(guò)運(yùn)行測(cè)試腳本代碼,并統(tǒng)計(jì)不同狀態(tài)下腳本引擎中存在的所有內(nèi)置對(duì)象別名關(guān)系,以此作為對(duì)比的標(biāo)準(zhǔn)。在實(shí)驗(yàn)過(guò)程中,針對(duì)全體內(nèi)置對(duì)象別名關(guān)系進(jìn)行多次統(tǒng)計(jì),排除內(nèi)置對(duì)象隨機(jī)初始化數(shù)值引發(fā)的干擾。在統(tǒng)計(jì)多次實(shí)驗(yàn)結(jié)果后,平均每個(gè)測(cè)試樣本中包含總計(jì)196條內(nèi)置對(duì)象別名關(guān)系,使用論文中的別名關(guān)系識(shí)別方法能識(shí)別出183條內(nèi)置對(duì)象別名關(guān)系,最終漏報(bào)率約6.6%。

      進(jìn)一步,我們將本文中提出的別名關(guān)系識(shí)別方法與現(xiàn)有研究中的別名關(guān)系識(shí)別方法進(jìn)行對(duì)比,比較不同方法在識(shí)別腳本引擎內(nèi)置對(duì)象別名關(guān)系時(shí)的性能差異。我們選用Pintool 工具[31]實(shí)現(xiàn)現(xiàn)有研究中的別名關(guān)系識(shí)別方法[32],核心思想為監(jiān)測(cè)程序運(yùn)行過(guò)程中的內(nèi)存讀寫(xiě)操作。當(dāng)監(jiān)測(cè)到內(nèi)存寫(xiě)指令涉及的不同操作數(shù)分別屬于不同內(nèi)置對(duì)象時(shí),認(rèn)為出現(xiàn)了內(nèi)置對(duì)象別名關(guān)系。在保持測(cè)試樣本一致的前提下,我們分別統(tǒng)計(jì)了相同時(shí)間內(nèi),不同別名關(guān)系識(shí)別方法的相關(guān)指標(biāo),包括別名關(guān)系數(shù)量、誤報(bào)率及漏報(bào)率,同時(shí)將測(cè)試樣本中別名關(guān)系總數(shù)作為對(duì)照標(biāo)準(zhǔn),最終統(tǒng)計(jì)結(jié)果如表2 所示。

      表2 別名關(guān)系識(shí)別方法對(duì)比Table 2 Comparison of different alias relationship recognition method

      從結(jié)果中可見(jiàn),在測(cè)試時(shí)長(zhǎng)為10 min 時(shí),使用傳統(tǒng)別名關(guān)系識(shí)別方法,總共識(shí)別出17 組內(nèi)置對(duì)象別名關(guān)系,漏報(bào)率為88%,而使用論文中提出的基于數(shù)據(jù)結(jié)構(gòu)特征的別名關(guān)系識(shí)別方法能夠識(shí)別出137組別名關(guān)系,漏報(bào)率為6%,明顯優(yōu)于傳統(tǒng)方法。同樣,我們分別測(cè)試了30 min 以及60 min 條件下,不同別名關(guān)系識(shí)別方法所能識(shí)別出的別名關(guān)系數(shù)量,最終證明了論文中的別名關(guān)系識(shí)別方法相較于傳統(tǒng)方法有較大優(yōu)勢(shì)。

      6.2 測(cè)試樣本生成效率

      本節(jié)中,我們主要評(píng)估使用對(duì)象數(shù)據(jù)結(jié)構(gòu)特征對(duì)于生成測(cè)試樣本的影響。當(dāng)腳本引擎API 參數(shù)為對(duì)象類型,生成測(cè)試樣本時(shí)搜索空間的大小與API參數(shù)候選集的大小成正比。在不提取細(xì)粒度參數(shù)類型的情況下,API 參數(shù)候選集的大小等于腳本引擎中所有內(nèi)置對(duì)象的個(gè)數(shù)。依據(jù)統(tǒng)計(jì)結(jié)果,平均一個(gè)腳本引擎API 需要3 個(gè)對(duì)象參數(shù),而腳本引擎中共包含237 個(gè)API 以及163 種內(nèi)置對(duì)象,則生成測(cè)試樣本時(shí)最終搜索空間大小為237*163*163*163。我們通過(guò)實(shí)驗(yàn)發(fā)現(xiàn),不同腳本引擎API 需要不同細(xì)粒度類型的內(nèi)置對(duì)象作為參數(shù),而傳遞其余類型的內(nèi)置對(duì)象將引發(fā)運(yùn)行時(shí)錯(cuò)誤。通過(guò)提取腳本引擎API 參數(shù)的內(nèi)存訪問(wèn)模式,結(jié)合內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,縮小了腳本引擎API 對(duì)象參數(shù)的候選集大小。

      我們分析并提取了每個(gè)腳本引擎API 的細(xì)粒度參數(shù)信息,最終確定了每個(gè)腳本引擎API 中對(duì)象參數(shù)的候選集大小,最終的統(tǒng)計(jì)結(jié)果如圖17 所示。根據(jù)圖17 中的統(tǒng)計(jì)結(jié)果可以發(fā)現(xiàn),約80%腳本引擎API 的參數(shù)候選集的大小不超過(guò)6。通過(guò)提取腳本引擎API 細(xì)粒度參數(shù)信息,能明顯優(yōu)化生成測(cè)試樣本時(shí)的搜索空間,大幅減少待測(cè)樣本個(gè)數(shù)(從237*163*163*163 縮小為237*6*6*6),提高了測(cè)試效率。

      除此之外,提取腳本引擎API 細(xì)粒度參數(shù)信息對(duì)于減少運(yùn)行時(shí)錯(cuò)誤有明顯助益。我們分別在使用API 細(xì)粒度參數(shù)信息與不使用的情況下,生成相同數(shù)量的測(cè)試樣本,并統(tǒng)計(jì)測(cè)試樣本運(yùn)行過(guò)程中產(chǎn)生的運(yùn)行時(shí)錯(cuò)誤。通過(guò)對(duì)比運(yùn)行時(shí)錯(cuò)誤數(shù)量,評(píng)估腳本引擎API 細(xì)粒度參數(shù)信息對(duì)于減少運(yùn)行時(shí)錯(cuò)誤的效果,具體統(tǒng)計(jì)結(jié)果如表3 中所示。

      表3 運(yùn)行時(shí)錯(cuò)誤數(shù)量Table 3 Number of runtime errors

      在表3 中,我們分別生成了100 個(gè),200 個(gè),300個(gè)以及400 個(gè)測(cè)試樣本,并統(tǒng)計(jì)產(chǎn)生運(yùn)行時(shí)錯(cuò)誤的樣本數(shù)量。在使用API 參數(shù)細(xì)粒度信息時(shí),存在運(yùn)行時(shí)錯(cuò)誤的樣本數(shù)量分別為17 個(gè),32 個(gè),46 個(gè)以及57個(gè),而在不使用API 細(xì)粒度參數(shù)信息時(shí),運(yùn)行時(shí)錯(cuò)誤的數(shù)量分別為73 個(gè),153 個(gè),231 個(gè)以及316 個(gè)??梢园l(fā)現(xiàn),使用API 細(xì)粒度類型信息生成的測(cè)試樣本中,包含的運(yùn)行時(shí)錯(cuò)誤數(shù)量明顯少于不使用細(xì)粒度參數(shù)信息。因此,可以證明提取腳本引擎API 細(xì)粒度信息對(duì)于減少運(yùn)行時(shí)錯(cuò)誤,提高測(cè)試樣本質(zhì)量有明顯幫助。

      6.3 別名關(guān)系識(shí)別開(kāi)銷

      為了評(píng)估論文中別名關(guān)系識(shí)別方法的高效性,即相較于已有別名關(guān)系識(shí)別方法,我們提出的別名關(guān)系識(shí)別方法具有較短的檢測(cè)時(shí)長(zhǎng)。我們生成了包含隨機(jī)數(shù)量腳本語(yǔ)言代碼的測(cè)試樣本,統(tǒng)計(jì)了測(cè)試樣本在不識(shí)別別名關(guān)系,使用傳統(tǒng)別名識(shí)別方法以及基于對(duì)象數(shù)據(jù)結(jié)構(gòu)特征識(shí)別別名關(guān)系三種場(chǎng)景下的運(yùn)行時(shí)長(zhǎng),取單條腳本語(yǔ)言代碼平均運(yùn)行時(shí)長(zhǎng)作為性能評(píng)估的依據(jù)。

      傳統(tǒng)別名關(guān)系識(shí)別通過(guò)監(jiān)控內(nèi)存數(shù)據(jù)的方式進(jìn)行實(shí)現(xiàn),具體為監(jiān)控程序運(yùn)行過(guò)程中的內(nèi)存讀寫(xiě)指令,根據(jù)讀寫(xiě)指令涉及的操作數(shù)來(lái)識(shí)別對(duì)象別名關(guān)系。內(nèi)存讀指令用于標(biāo)明操作數(shù)與對(duì)象的從屬關(guān)系,內(nèi)存寫(xiě)指令用于判斷對(duì)象別名關(guān)系。當(dāng)內(nèi)存寫(xiě)指令涉及的兩個(gè)操作數(shù)分別來(lái)自不同對(duì)象時(shí),認(rèn)為檢測(cè)到對(duì)象別名關(guān)系。我們總計(jì)測(cè)試了100 組數(shù)據(jù),結(jié)果如圖18 所示。

      在圖18 中,運(yùn)行耗時(shí)以秒為單位。在不識(shí)別內(nèi)置對(duì)象別名關(guān)系時(shí),單條腳本語(yǔ)言代碼的平均運(yùn)行時(shí)長(zhǎng)約為1 s。使用傳統(tǒng)別名識(shí)別方法時(shí),單條腳本語(yǔ)言代碼的平均運(yùn)行時(shí)長(zhǎng)為269 s,相比于不識(shí)別別名關(guān)系,其運(yùn)行耗時(shí)明顯增加。采用我們提出的基于對(duì)象數(shù)據(jù)結(jié)構(gòu)特征的別名關(guān)系識(shí)別方法,單條腳本語(yǔ)言代碼的平均運(yùn)行時(shí)長(zhǎng)為13 s。雖然相比于不進(jìn)行別名分析運(yùn)行時(shí)長(zhǎng)有所上升,但額外提取了內(nèi)置對(duì)象別名關(guān)系,且性能開(kāi)銷仍在可接受范圍。同時(shí),相比于傳統(tǒng)別名關(guān)系識(shí)別方法能顯著縮短運(yùn)行時(shí)長(zhǎng)。因此,我們提出的基于對(duì)象數(shù)據(jù)結(jié)構(gòu)特征的別名關(guān)系識(shí)別方法,能快速檢測(cè)腳本引擎內(nèi)置對(duì)象別名關(guān)系,提升了別名關(guān)系識(shí)別效率。

      6.4 別名關(guān)系識(shí)別方案的通用性

      在軟件內(nèi)嵌腳本引擎中,為了方便用戶,定義了不同結(jié)構(gòu)的內(nèi)置對(duì)象與不同功能的腳本引擎API,搭配使用腳本引擎API 與內(nèi)置對(duì)象可實(shí)現(xiàn)多種復(fù)雜功能。根據(jù)我們的調(diào)查結(jié)果,腳本引擎中的安全漏洞常與內(nèi)置對(duì)象緊密相關(guān),究其原因在于內(nèi)置對(duì)象的內(nèi)部結(jié)構(gòu)復(fù)雜,且可通過(guò)腳本引擎API 建立深層次聯(lián)系,使得管理和維護(hù)內(nèi)置對(duì)象具有較大難度。在本文中,為了檢測(cè)腳本引擎中的深層次安全漏洞,我們將重心放在識(shí)別內(nèi)置對(duì)象別名關(guān)系。進(jìn)一步,為了證明論文中別名關(guān)系識(shí)別方法的通用性,我們?cè)O(shè)計(jì)了如下實(shí)驗(yàn)。

      在軟件內(nèi)嵌腳本引擎中,除了具有特殊結(jié)構(gòu)的內(nèi)置對(duì)象,還存在用戶自定義對(duì)象,即由用戶自定義對(duì)象內(nèi)部結(jié)構(gòu)及屬性。我們采用包含自定義對(duì)象的數(shù)據(jù)集,并使用論文中方法識(shí)別內(nèi)置對(duì)象別名關(guān)系。進(jìn)一步,使用6.1 節(jié)中描述的方法來(lái)驗(yàn)證別名關(guān)系的準(zhǔn)確性,最終實(shí)驗(yàn)結(jié)果如表4 所示。

      表4 自定義對(duì)象別名關(guān)系識(shí)別統(tǒng)計(jì)表Table 4 Statistics of custom object alias relationship

      如表4 所示,在所使用的數(shù)據(jù)集中,總共包含對(duì)象別名關(guān)系153,165,138 以及144 組,其中自定義對(duì)象別名關(guān)系總數(shù)為36,43,25 以及31 組,而使用論文中的方法共能識(shí)別出自定義對(duì)象別名關(guān)系33,39,23以及29。進(jìn)一步我們計(jì)算了自定義對(duì)象別名關(guān)系識(shí)別的漏報(bào)率以及誤報(bào)率,其中誤報(bào)率采用6.1 節(jié)中方法計(jì)算,最終證明無(wú)誤報(bào)現(xiàn)象,而漏報(bào)率分別為8.3%,9.3%,8%以及6.4%,證明了論文中方法能以較高效率識(shí)別自定義對(duì)象別名關(guān)系,從而證明方法的通用性。

      6.5 釋放后使用漏洞檢測(cè)結(jié)果

      在本節(jié)中,我們以發(fā)現(xiàn)的未知釋放后使用漏洞為例,介紹具體的檢測(cè)思路。首先是漏洞編號(hào)“CVE-2020-3745”的釋放后使用漏洞,具體漏洞代碼如圖19 所示。

      通過(guò)調(diào)用腳本引擎API util.streamFromString 創(chuàng)建了Stream 類型的內(nèi)置對(duì)象,記為ObjA對(duì)象,對(duì)應(yīng)圖19 中第①行。在圖19 第②行中,調(diào)用了腳本引擎API Collab.drivers.getInitiatorSource 并將ObjA對(duì)象作為參數(shù),創(chuàng)建了ReadStream 類型的內(nèi)置對(duì)象,記為ObjB。同時(shí),該API 也建立了ObjA對(duì)象和ObjB對(duì)象間的別名關(guān)系。之后,通過(guò)調(diào)用API this.reset-Form 釋放了ObjB對(duì)象。由于ObjA對(duì)象和ObjB對(duì)象存在別名關(guān)系,導(dǎo)致ObjA對(duì)象內(nèi)部出現(xiàn)了懸掛指針。在圖19 第④行中,通過(guò)API util.stringFrom-Stream 訪問(wèn)了ObjA對(duì)象內(nèi)部的懸掛指針,觸發(fā)了釋放后使用漏洞。我們將上述漏洞的觸發(fā)模式總結(jié)為圖20。

      通過(guò)使用論文中提出的方法,總計(jì)檢測(cè)出4 個(gè)未知的釋放后使用漏洞,現(xiàn)將每個(gè)未知釋放后使用漏洞對(duì)應(yīng)的漏洞編號(hào),及其涉及的具體腳本引擎內(nèi)置對(duì)象信息總結(jié)如表5 所示。

      表5 檢測(cè)出的釋放后使用漏洞列表Table 5 List of detected UAF vulnerabilities

      7 總結(jié)與展望

      在腳本引擎漏洞挖掘領(lǐng)域,利用模糊測(cè)試來(lái)檢測(cè)漏洞的方法已經(jīng)被證明有效,但現(xiàn)有的模糊測(cè)試方法主要關(guān)注如何生成符合腳本語(yǔ)言語(yǔ)法規(guī)范的測(cè)試樣本,未能很好地利用腳本引擎API 以及內(nèi)置對(duì)象,在挖掘腳本引擎深層次漏洞方面未能取得較好的效果。

      針對(duì)上述局限性,本研究提出了一種基于數(shù)據(jù)結(jié)構(gòu)特征的腳本引擎內(nèi)置對(duì)象別名關(guān)系識(shí)別技術(shù),通過(guò)快速識(shí)別內(nèi)置對(duì)象別名關(guān)系來(lái)輔助檢測(cè)釋放后使用漏洞。與傳統(tǒng)腳本引擎漏洞檢測(cè)方案不同,我們重點(diǎn)關(guān)注腳本引擎中的特殊API 及內(nèi)置對(duì)象,采取自動(dòng)化的方式提取內(nèi)置對(duì)象數(shù)據(jù)結(jié)構(gòu)特征,并基于提取出的對(duì)象特征識(shí)別腳本引擎API 細(xì)粒度參數(shù)信息。進(jìn)一步,搭配合理API 參數(shù),我們可以生成高質(zhì)量的測(cè)試樣本,提高內(nèi)置對(duì)象別名關(guān)系的出現(xiàn)概率。同時(shí),我們利用對(duì)象數(shù)據(jù)結(jié)構(gòu)特征快速準(zhǔn)確地識(shí)別內(nèi)置對(duì)象別名關(guān)系,大幅縮短了現(xiàn)有別名分析技術(shù)所需時(shí)間。最后,利用識(shí)別的內(nèi)置對(duì)象別名關(guān)系,搭配特定API 序列有針對(duì)性地釋放和使用內(nèi)置對(duì)象,構(gòu)造性地檢測(cè)腳本引擎中的釋放后使用漏洞。最終,我們提取出284 組內(nèi)置對(duì)象別名關(guān)系,并據(jù)此檢測(cè)出4 個(gè)未知的釋放后使用漏洞。

      誠(chéng)然,本方法也存在諸多不足和需要繼續(xù)改進(jìn)的地方。首先,在提取腳本引擎API 細(xì)粒度參數(shù)信息時(shí),現(xiàn)有的靜態(tài)分析方法在處理間接函數(shù)調(diào)用時(shí)粒度較粗,提取的參數(shù)信息不夠精確,后續(xù)可針對(duì)識(shí)別精度進(jìn)行改進(jìn),進(jìn)一步縮小腳本引擎API 參數(shù)候選集的大小,實(shí)現(xiàn)精確的API 參數(shù)細(xì)粒度類型識(shí)別。

      其次,生成測(cè)試樣本時(shí),對(duì)于如何填充腳本引擎API 的參數(shù)考慮不足,如針對(duì)基礎(chǔ)類型只是簡(jiǎn)單地選取隨機(jī)常量值,對(duì)象類型僅考慮了參數(shù)候選集中的元素。在后續(xù)工作中,可以更深入地探究腳本引擎API的執(zhí)行邏輯,探究參數(shù)對(duì)于API執(zhí)行軌跡的影響,從而更針對(duì)性地提供API 所需參數(shù)。除此之外,使用內(nèi)置對(duì)象別名關(guān)系檢測(cè)釋放后使用漏洞時(shí),提取的內(nèi)置對(duì)象別名關(guān)系數(shù)量及釋放API 序列數(shù)量較少。對(duì)于這一問(wèn)題,可以通過(guò)加強(qiáng)腳本引擎API 的關(guān)聯(lián)性,以及改進(jìn)監(jiān)控策略,來(lái)發(fā)現(xiàn)更多的釋放API 序列。

      最后,本工作未在JavaScript 以外的腳本引擎中進(jìn)行實(shí)驗(yàn),后續(xù)考慮將實(shí)驗(yàn)移植到JavaScript 語(yǔ)言以外的腳本引擎中,進(jìn)一步證明方法的通用性。在其他腳本引擎中,可通過(guò)分析對(duì)象內(nèi)部結(jié)構(gòu),來(lái)識(shí)別對(duì)象內(nèi)部別名關(guān)系,進(jìn)而檢測(cè)安全漏洞。

      猜你喜歡
      腳本數(shù)據(jù)結(jié)構(gòu)內(nèi)置
      酒駕
      內(nèi)置加勁環(huán)T型管節(jié)點(diǎn)抗沖擊承載力計(jì)算
      安奇奇與小cool 龍(第二回)
      數(shù)據(jù)庫(kù)系統(tǒng)shell腳本應(yīng)用
      芯片內(nèi)置測(cè)試電路的設(shè)計(jì)
      快樂(lè)假期
      “翻轉(zhuǎn)課堂”教學(xué)模式的探討——以《數(shù)據(jù)結(jié)構(gòu)》課程教學(xué)為例
      高職高專數(shù)據(jù)結(jié)構(gòu)教學(xué)改革探討
      內(nèi)置管腸排列術(shù)治療嚴(yán)重粘連性腸梗阻的臨床分析
      TRIZ理論在“數(shù)據(jù)結(jié)構(gòu)”多媒體教學(xué)中的應(yīng)用
      临汾市| 蕲春县| 遂昌县| 政和县| 岳阳县| 凤凰县| 霞浦县| 开远市| 浑源县| 奉节县| 南华县| 夹江县| 屯昌县| 德阳市| 广州市| 分宜县| 南江县| 息烽县| 朝阳区| 蒲城县| 千阳县| 易门县| 察隅县| 龙门县| 永济市| 家居| 乌拉特后旗| 哈尔滨市| 安仁县| 安丘市| 正定县| 鄂伦春自治旗| 左权县| 昆山市| 泾源县| 神木县| 黎川县| 浪卡子县| 湖口县| 嘉定区| 嘉峪关市|