• 
    

    
    

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

      ?

      源代碼漏洞靜態(tài)分析技術(shù)

      2022-08-16 09:34:14劉嘉勇韓家璇
      信息安全學(xué)報 2022年4期
      關(guān)鍵詞:污點源代碼漏洞

      劉嘉勇 ,韓家璇 ,黃 誠

      1 四川大學(xué) 網(wǎng)絡(luò)空間安全學(xué)院 成都 中國 610207

      1 引言

      隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,計算機(jī)軟件系統(tǒng)與用戶隱私、資產(chǎn)等重要信息的關(guān)系越來越緊密,大量的用戶隱私數(shù)據(jù)被上傳到云端存儲。根據(jù)第47 次《中國互聯(lián)網(wǎng)絡(luò)發(fā)展?fàn)顩r統(tǒng)計報告》[1],截至到2020 年12 月,我國網(wǎng)民的規(guī)模已經(jīng)達(dá)到9.89 億,互聯(lián)網(wǎng)普及率達(dá)70.4%。網(wǎng)絡(luò)購物、線上支付、即時通信已然成為當(dāng)今社會主流的生活方式。據(jù)統(tǒng)計,2020 年疫情期間全國一體化政務(wù)服務(wù)平臺推出的“防疫健康碼”使用次數(shù)超過400 億次,在線會議和課程等全新的工作和學(xué)習(xí)模式迅速融入到人們的生活中,互聯(lián)網(wǎng)技術(shù)為中國抗擊疫情提供了強(qiáng)大的支持。然而,互聯(lián)網(wǎng)技術(shù)的普及也為各類軟件系統(tǒng)的安全性提出了巨大的考驗。根據(jù)OWASP Top 10 2017 報告[2]顯示,由node.js 和Spring Boot 編寫的微服務(wù)逐漸成為軟件開發(fā)的新方向;軟件系統(tǒng)中高擴(kuò)展性的、功能豐富的模塊被攻擊者們重點關(guān)注;XXE(XML External Entities)注入、反序列化攻擊等手段逐漸成為主流。在巨大利益等因素的驅(qū)使下,攻擊者們不斷嘗試尋找各類軟件系統(tǒng)中存在的漏洞,試圖繞過系統(tǒng)的訪問控制,實現(xiàn)竊取和修改重要數(shù)據(jù)、控制系統(tǒng)等非法操作。

      軟件漏洞檢測一直是學(xué)術(shù)界和工業(yè)界討論的核心問題。參考長亭科技發(fā)布的《2019 長亭年度漏洞威脅分析與2020 安全展望》[3],截至到2019 年年底,中國國家信息安全漏洞庫(China National Vulnerability Database of Information Security,CNNVD)共收集了17820 個漏洞,中國國家信息安全漏洞共享平臺(China National Vulnerability Database,CNVD)共收集了16208 個漏洞,相當(dāng)于2019 年每天約有48 個漏洞被曝光。同時,根據(jù)著名安全研究機(jī)構(gòu)SkyBox Security 發(fā)布的《2020 Vulnerability and Threat Trends Report Mid-Year Update:Key Findings》報告[4]顯示,2020 年上半年有9000 多個漏洞被曝光,移動端漏洞的數(shù)量增長迅速。雖然企業(yè)為其軟件系統(tǒng)制定了一系列安全方案,也配置和部署了各類安全設(shè)備,但軟件漏洞仍然被頻頻曝出;其根本原因是開發(fā)人員缺乏安全意識,在軟件開發(fā)時就為其埋下了不安全因素。此外,隨著計算機(jī)軟件領(lǐng)域的發(fā)展,軟件代碼開源化已然成為一種趨勢?,F(xiàn)如今,軟件的功能越來越多,系統(tǒng)越來越復(fù)雜,開發(fā)人員將開源代碼引入到項目中能夠極大地提高開發(fā)效率;但在增加開發(fā)便利度的同時,引入開源代碼也增加了軟件系統(tǒng)存在漏洞的可能。

      軟件漏洞的檢測方法主要有三種:靜態(tài)檢測(又稱:靜態(tài)分析)、動態(tài)檢測(又稱:動態(tài)分析)和動靜結(jié)合的檢測(又稱:動靜結(jié)合的分析或混合分析)。靜態(tài)分析是指在不運行軟件程序的前提下,對軟件代碼進(jìn)行抽象建模,通過分析程序的屬性進(jìn)而實現(xiàn)漏洞檢測;動態(tài)分析是指向軟件程序輸入特定構(gòu)造的數(shù)據(jù),觀察程序的運行狀態(tài),通過狀態(tài)判斷程序是否存在漏洞;混合分析則是一種將靜態(tài)分析和動態(tài)分析相結(jié)合的混合式漏洞檢測方法。本文以面向源代碼的靜態(tài)分析領(lǐng)域典型的研究成果作為切入點,將該領(lǐng)域的研究分為傳統(tǒng)靜態(tài)分析和基于學(xué)習(xí)的靜態(tài)分析兩個方向,分別對這兩個方向上的研究進(jìn)展和研究成果進(jìn)行歸納總結(jié),討論該領(lǐng)域目前存在的困難并對未來的發(fā)展方向進(jìn)行展望。

      2 軟件漏洞分析技術(shù)基本概念

      2.1 靜態(tài)分析技術(shù)

      靜態(tài)分析技術(shù)是指在不運行程序代碼的情況下,對其進(jìn)行詞法分析、語法分析以及語義分析,配合數(shù)據(jù)流分析和污點分析等技術(shù),對程序代碼進(jìn)行抽象和建模,分析程序的控制依賴、數(shù)據(jù)依賴和變量受污染狀態(tài)等信息,通過安全規(guī)則檢查、模式匹配等方式挖掘程序代碼中存在的漏洞[5-7]。常見的靜態(tài)分析工具有:WALA[8]、FindBugs[9]、JSPrime[10]、CodeQL[11]、Fortify[12]、Cppcheck[13]、Cobot[14]等。

      依據(jù)分析目標(biāo)的不同,靜態(tài)分析可分為:面向源代碼的靜態(tài)分析和面向二進(jìn)制代碼的靜態(tài)分析。面向源代碼的靜態(tài)分析以程序的源代碼作為輸入,將其轉(zhuǎn)換為某種特定形式的中間表示,基于該中間表示進(jìn)行分析。因為分析是基于源代碼進(jìn)行的,所以能夠捕獲豐富的代碼結(jié)構(gòu)、語義和邏輯等信息。面向二進(jìn)制代碼的靜態(tài)分析則是以經(jīng)過反匯編等手段處理后的二進(jìn)制代碼作為輸入,設(shè)法恢復(fù)程序的信息,運用模式匹配或補丁對比等方式實現(xiàn)漏洞檢測。相比源代碼,二進(jìn)制代碼缺乏與代碼相關(guān)的高級語義信息,且以二進(jìn)制代碼形式表示的漏洞模式更為復(fù)雜;然而,由于存在一部分軟件程序是以二進(jìn)制形式發(fā)布的,并不包含軟件程序的源代碼,所以對于非程序開發(fā)方的安全人員而言,研究面向二進(jìn)制代碼的漏洞分析是很重要的。

      2.2 動態(tài)分析技術(shù)

      與靜態(tài)分析不同,動態(tài)分析是指在沙箱等受控環(huán)境中執(zhí)行程序,向程序輸入特定的數(shù)據(jù),監(jiān)視其運行時的行為,收集函數(shù)的執(zhí)行結(jié)果、程序的異常行為和崩潰情況等信息以判斷目標(biāo)程序是否存在漏洞[15-16]。常見的動態(tài)分析工具有:AFL[17]、Sage[18]和jsfunfuzz[19]等。動態(tài)分析技術(shù)包括動態(tài)符號執(zhí)行和模糊測試兩種。其中,符號執(zhí)行的目標(biāo)是獲得讓特定代碼區(qū)域執(zhí)行的輸入,通常分為靜態(tài)符號執(zhí)行和動態(tài)符號執(zhí)行兩種。靜態(tài)符號執(zhí)行不會真正執(zhí)行程序,也不會向程序提供具體的數(shù)據(jù)輸入;而是通過將程序的輸入抽象為符號,使用約束求解器求解,進(jìn)而獲得讓特定代碼區(qū)域執(zhí)行的輸入,如文章[20]中所做的工作;動態(tài)符號執(zhí)行則是將具體執(zhí)行和符號執(zhí)行相結(jié)合,以具體的值作為程序的輸入,執(zhí)行程序,收集符號約束,修改收集的符號約束內(nèi)容以構(gòu)造不同的可執(zhí)行路徑,進(jìn)而實現(xiàn)對程序所有路徑的遍歷[21]。相比于動態(tài)符號執(zhí)行,模糊測試是近年來動態(tài)分析領(lǐng)域研究的熱門。模糊測試是Miller 等在1991 年提出的一個概念[22],其核心思想是通過向程序輸入畸形數(shù)據(jù),觀察程序的執(zhí)行狀態(tài)(如:程序的異常行為和崩潰情況),進(jìn)而判斷程序是否存在漏洞。

      2.3 差異性分析

      靜態(tài)分析和動態(tài)分析的差異性對比如表1 所示。靜態(tài)分析和動態(tài)分析面向的目標(biāo)不同;靜態(tài)分析面向的是軟件源代碼和二進(jìn)制代碼,而動態(tài)分析大多面向軟件程序本身。通常,靜態(tài)分析可以貫穿整個軟件生命周期,輔助開發(fā)人員及早地發(fā)現(xiàn)軟件代碼中存在的問題;分析過程不需要將程序?qū)嶋H地運行起來,而是對程序代碼進(jìn)行抽象和建模,因此分析器能夠在低資源需求的前提下實現(xiàn)高代碼覆蓋率。但是,由于分析器對程序代碼具有極高的依賴性,導(dǎo)致在程序代碼缺失的情況下難以對程序進(jìn)行分析;由于分析是基于對程序代碼的抽象和建模,分析器的分析邏輯很大程度上取決于對漏洞已有的先驗知識,所以在面對未定義的程序錯誤行為時,靜態(tài)分析往往存在誤報率高的問題;此外,靜態(tài)分析還存在運行時漏洞檢測難問題。

      表1 靜態(tài)分析和動態(tài)分析差異性對比Table 1 Comparison of differences between static analysis and dynamic analysis

      對于動態(tài)分析而言,因為分析器需要對程序的運行時信息進(jìn)行跟蹤、收集和分析,所以對系統(tǒng)環(huán)境的要求較高,需要為不同的程序配置不同的運行環(huán)境;但是由于是基于程序的實際運行情況進(jìn)行分析的,因此分析的精確度較高,而且能夠?qū)?jīng)過混淆的代碼進(jìn)行檢測。不過,因為需要運行程序觀察其執(zhí)行情況,而當(dāng)前環(huán)境下很多程序的代碼空間很大,分析器在短時間內(nèi)難以覆蓋整個程序空間,所以動態(tài)分析的漏報率相對較高;而且以動態(tài)符號執(zhí)行為主的動態(tài)分析還面臨著路徑爆炸[23]等問題。

      無論是靜態(tài)分析技術(shù)還是動態(tài)分析技術(shù),都能夠為處在互聯(lián)網(wǎng)快速發(fā)展背景下的軟件系統(tǒng)安全提供強(qiáng)有力的保障。近年來,為了在軟件系統(tǒng)上線前就對其可能存在的漏洞進(jìn)行檢測,將軟件系統(tǒng)面臨的風(fēng)險扼殺在搖籃中,進(jìn)一步減少軟件系統(tǒng)上線后可能受到的安全威脅,越來越多的企業(yè)開始在軟件開發(fā)過程中使用靜態(tài)分析對軟件漏洞進(jìn)行挖掘。本節(jié)對軟件漏洞分析技術(shù)的基本概念進(jìn)行了解釋,讓讀者對該領(lǐng)域的基本情況有一個初步的了解。在接下來的章節(jié)中,我們會對靜態(tài)分析領(lǐng)域的相關(guān)概念和技術(shù)、研究進(jìn)展以及研究成果進(jìn)行詳細(xì)闡述,并給出我們對該領(lǐng)域未來發(fā)展趨勢的一些看法。

      3 源代碼漏洞靜態(tài)分析技術(shù)

      3.1 源代碼的表示方法

      將源代碼轉(zhuǎn)換成合適的中間表示是進(jìn)行源代碼漏洞靜態(tài)分析的第一步。源代碼的表示方法主要分為兩大類:樹形表示和圖形表示。樹形表示主要以抽象語法樹(Abstract Syntax Tree,AST)為主;圖形表示主要包括:控制流圖(Control Flow Graph,CFG)、數(shù)據(jù)流圖(Data Flow Graph,DFG)、調(diào)用圖(Call Graph,CG)、程序依賴圖(Program Dependence Graph,PDG)、系統(tǒng)依賴圖(System Dependence Graph,SDG)和代碼屬性圖(Code Property Graph,CPG)。如圖1 所示,AST 是由代碼解析器對源代碼進(jìn)行詞法分析和語法分析后生成的最基本的中間表示,也是其他中間表示的基礎(chǔ),能夠清楚地反映源代碼的結(jié)構(gòu)信息,在源代碼漏洞檢測中有著很重要的作用。陳肇炫等人[24]提出的Astor模型[24]通過將源代碼轉(zhuǎn)換成AST,采用深度優(yōu)先遍歷算法獲取AST 的語法表征并訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型對其進(jìn)行學(xué)習(xí),實現(xiàn)了基于源代碼結(jié)構(gòu)信息的智能化漏洞檢測。Hantao Feng 等[25]將源代碼轉(zhuǎn)換成AST,然后將AST 轉(zhuǎn)換為序列,利用詞嵌入技術(shù)將序列轉(zhuǎn)換為向量,保留了源代碼的語義特征;通過訓(xùn)練BGRU (Bidirectional Gate Recurrent Unite)模型,從向量中提取特征以實現(xiàn)漏洞檢測。文章[26]從源代碼中提取AST,將其嵌入到向量空間中,然后使用潛在語義分析技術(shù)[27]識別代碼的結(jié)構(gòu)模式,從而實現(xiàn)漏洞外推。

      CFG、DFG 和CG 可以通過分析AST 直接獲得。CFG 能夠描述語句的執(zhí)行順序以及語句間的支配關(guān)系(即:控制依賴關(guān)系),DFG 能夠表示語句和變量間的數(shù)據(jù)依賴關(guān)系,CG 能夠表示函數(shù)的調(diào)用情況。通過從CFG 中提取控制依賴關(guān)系,從DFG 中提取數(shù)據(jù)依賴關(guān)系,將兩種關(guān)系融合到同一張圖中,進(jìn)而形成PDG;再依據(jù)CG 將不同函數(shù)的PDG 連接起來,形成過程間程序依賴圖,即SDG。

      CPG 是Yamaguchi 等人在論文[28]中提出的一種全新的源代碼中間表示形式,是當(dāng)前源代碼漏洞靜態(tài)分析技術(shù)中最新、使用最為廣泛的源代碼圖形表示,由AST、CFG 和PDG 合并而成,如圖2 所示。相比于其他源代碼中間表示形式,CPG 能夠很好地反映源代碼的結(jié)構(gòu)、語句執(zhí)行順序、控制依賴和數(shù)據(jù)依賴等信息;在文章[28]中,作者首次提出使用CPG 表示源代碼,采用圖形數(shù)據(jù)庫Neo4J[29]存儲并遍歷CPG以實現(xiàn)漏洞檢測。同時,Yamaguchi 等在文章[30]中還提出了一種自動推斷C 代碼中污點型漏洞搜索模式的方法,該方法通過對CPG 進(jìn)行擴(kuò)展以支持過程間分析;通過給定Sink(Sink 指污點的匯聚點),該方法能夠自動識別對應(yīng)的Source-Sink(Source 指污點源)系統(tǒng)并對系統(tǒng)中的數(shù)據(jù)流和Sanitization (Sanitization 指對污點數(shù)據(jù)的無害處理,即凈化)進(jìn)行建模,生成污點型漏洞的搜索模式;基于推斷的搜索模式對CPG 進(jìn)行遍歷,從而檢測源代碼中存在的漏洞。Peng Wu 等[31]提出基于CPG 從AST 和API 的子樹中提取代碼特征,然后使用詞袋模型和TF-IDF 模型將代碼特征嵌入到向量空間;同時從CVE 上提取漏洞代碼及其補丁的代碼切片,計算源代碼、漏洞代碼、補丁代碼之間的相似性以實現(xiàn)漏洞檢測。

      3.2 源代碼的分析方法

      源代碼的分析方法可以分為兩類,一類是傳統(tǒng)靜態(tài)分析,另一類是基于學(xué)習(xí)的靜態(tài)分析。傳統(tǒng)靜態(tài)分析主要基于數(shù)據(jù)流分析和污點分析,通過對源代碼進(jìn)行抽象、建模和分析實現(xiàn)漏洞檢測;基于學(xué)習(xí)的靜態(tài)分析則是將機(jī)器學(xué)習(xí)技術(shù)運用到靜態(tài)分析中,利用其強(qiáng)大的大數(shù)據(jù)挖掘能力,學(xué)習(xí)源代碼的運行邏輯、數(shù)據(jù)流動等信息,進(jìn)一步通過學(xué)習(xí)模型判斷源代碼中是否存在漏洞。下面將對這兩種分析方法的實現(xiàn)原理和典型技術(shù)進(jìn)行詳細(xì)介紹。

      3.2.1 傳統(tǒng)靜態(tài)分析技術(shù)

      傳統(tǒng)靜態(tài)分析的基本流程如圖3 所示。首先需要對待檢測源代碼進(jìn)行抽象和建模,通過解析器執(zhí)行詞法分析和語法分析,生成特定的中間表示;然后基于該中間表示,采用預(yù)設(shè)的漏洞分析規(guī)則,結(jié)合數(shù)據(jù)流分析和污點分析,收集源代碼中與漏洞相關(guān)的信息;最后,對收集的信息進(jìn)行分析,給出檢測結(jié)果。

      傳統(tǒng)靜態(tài)分析的核心技術(shù)是數(shù)據(jù)流分析和污點分析。數(shù)據(jù)流分析是一種基于格(lattice)理論的、用來獲取相關(guān)數(shù)據(jù)(如:變量及其取值)沿著程序執(zhí)行路徑流動的信息的程序分析技術(shù),常用于源代碼的編譯優(yōu)化過程,能夠獲得變量在某個程序點上的性質(zhì)、狀態(tài)、取值等信息[32-33]。常用的數(shù)據(jù)流分析方法有:

      (1) 到達(dá)定義分析(Reaching Definition Analysis):給定一個程序點p 和變量定義d,判斷在CFG上是否存在一條從d 到p 的路徑,該路徑上沒有對d進(jìn)行重新定義的指令。如果存在這么一條路徑,則稱定義d 可以到達(dá)程序點p;否則,定義d 不能到達(dá)程序點p。

      (2) 存活變量分析(Live Variable Analysis):給定一個程序點p 和變量v,判斷在CFG 上是否存在一條從p 開始的路徑,該路徑上有使用了v 的指令。如果存在這么一條路徑,則稱變量v 在程序點p 處是存活的;否則,變量v 在程序點p 處不存活。

      (3) 可用表達(dá)式分析(Available Expression Analysis):給定一個程序點p 和表達(dá)式x op y(其中,op 表示operator,指操作符),判斷在 CFG 上從ENTRY節(jié)點到p的所有路徑是否都執(zhí)行了x op y,且最后一次執(zhí)行x op y 后,沒有對x 和y 進(jìn)行重新定義。如果滿足上述條件(即: CFG 上從ENTRY 節(jié)點到p 的所有路徑都執(zhí)行了x op y,且最后一次執(zhí)行x op y后沒有對x 和y進(jìn)行重新定義),則稱表達(dá)式x op y 在程序點p 處是可用的;否則,表達(dá)式x op y 在程序點p 處不可用。

      除了上面提到的三種數(shù)據(jù)流分析方法外,數(shù)據(jù)流分析方法還包括:常量傳播分析(Constant Propagation Analysis)[34]、指針分析(Pointer Analysis)[35]等。常量傳播分析的目標(biāo)是判斷在給定程序點p 處指令i中的變量v 的值是否為常數(shù);指針分析則是一種用于分析變量指向的技術(shù),如:對于Java 語言,利用指針分析判斷給定變量v 所指向的對象o(Object)。

      污點分析是一種信息流分析技術(shù),通過對程序中的敏感數(shù)據(jù)進(jìn)行標(biāo)記,跟蹤標(biāo)記數(shù)據(jù)在程序中的傳播,從而檢測系統(tǒng)中存在的安全問題[36-37]。根據(jù)王蕾等[38]的論文,污點分析的基本流程如圖4 所示。污點分析被定義為三元組,建立在SC:{Tainted,Untainted}集合的格上。如果信息從Tainted 類型的變量(圖中標(biāo)記為“污點變量”)傳遞到Untainted 類型的變量(圖中標(biāo)記為“變量”),則Untainted 類型的變量將被標(biāo)記為Tainted 類型;如果在Tainted 類型變量的傳播過程中對其進(jìn)行了凈化處理,則當(dāng)其傳遞到Tainted 類型或Untainted 類型的變量時,不會改變目標(biāo)變量的污染狀態(tài)。在污點分析過程中,如果Tainted 類型的變量能夠傳遞到Sink,則說明當(dāng)前程序存在安全問題。

      傳統(tǒng)靜態(tài)分析技術(shù)在軟件源代碼漏洞檢測中有著廣泛的應(yīng)用。Johannes Dahse 等[39]對PHP 語言進(jìn)分析,為每個PHP 文件構(gòu)建對應(yīng)的AST,從中提取出用戶自定義函數(shù)的相關(guān)信息,如:函數(shù)名和參數(shù),同時構(gòu)建函數(shù)體的AST,然后將用戶自定義函數(shù)從前面為PHP 文件構(gòu)建的AST(文中稱為主AST)中刪除;接著,使用名為CFGBuilder 的模塊將獲取的AST 轉(zhuǎn)換為CFG;在構(gòu)建CFG 的過程中,對每個基本塊進(jìn)行數(shù)據(jù)流分析和污點分析,將分析結(jié)果存儲在一個稱為塊摘要(Block Summary)的數(shù)據(jù)結(jié)構(gòu)中,以便后續(xù)執(zhí)行過程間分析使用。在進(jìn)行污點分析時,為保證分析的準(zhǔn)確性,作者對925 個PHP 內(nèi)置函數(shù)進(jìn)行建模,同時還引入了字符串分析(String Analysis);此外,通過對包含的文件(即:通過include 等關(guān)鍵字引入的文件)進(jìn)行建模,將包含的文件視作為函數(shù),進(jìn)一步提高了分析的精確度。作者讓模型在5 個開源軟件上進(jìn)行了測試,平均TP(True Positive)達(dá)到了72%,平均FP(False Positive)達(dá)到了28%,平均FN(False Negative)達(dá)到了24%。

      Xuexiong Yan 等[40]提出一種基于后向污點分析的Web 應(yīng)用程序漏洞檢測模型。該模型首先從PHP代碼中提取AST、CFG 和CG,然后對Sink 進(jìn)行查找,構(gòu)建與Sink 相關(guān)的上下文信息;接著,執(zhí)行污點分析,在基本塊內(nèi)和基本塊間跟蹤敏感變量的流動,最終在測試數(shù)據(jù)集上成功檢測出13 個漏洞。Pixy[41]是Nenad Jovanovic 等提出的用于檢測Web 應(yīng)用程序漏洞的靜態(tài)分析工具。該工具采用流和上下文敏感的過程間數(shù)據(jù)流分析方法,同時基于別名分析和常量傳播分析,對采用PHP 語言編寫的Web 應(yīng)用程序漏洞進(jìn)行檢測。

      Libo Chen 等[42]提出一種針對嵌入式設(shè)備中提供的Web 服務(wù)漏洞的污點分析方法。作者發(fā)現(xiàn)網(wǎng)絡(luò)接口上的字符串通常在前端文件和后端二進(jìn)制文件之間共享以編碼用戶輸入。基于這個發(fā)現(xiàn),該方法首先在未打包固件的前端文件(HTML、XML 和JavaScript 文件)中提取關(guān)鍵字,然后基于前端提取的關(guān)鍵字,在后端二進(jìn)制文件中查找與關(guān)鍵字對應(yīng)的入口點,利用路徑探索和污點分析技術(shù)跟蹤輸入數(shù)據(jù)的流動,實現(xiàn)對嵌入式設(shè)備中提供的Web 服務(wù)漏洞的檢測。作者使用該方法成功在包括Tenda W20E在內(nèi)的12 款路由器中找出了33 個bug,其中有30個已經(jīng)被確認(rèn)。

      Yichen Xie 和Alex Aiken[43]針對PHP 語言提出了一種結(jié)合基本塊內(nèi)、過程內(nèi)和過程間分析的腳本語言漏洞檢測模型。該模型將輸入的PHP 代碼解析為AST,基于AST 構(gòu)建對應(yīng)的CFG,然后使用符號執(zhí)行技術(shù)分析CFG 的每一個基本塊并對基本塊內(nèi)的動態(tài)特性進(jìn)行建模,生成塊摘要;接著使用可達(dá)性分析將每個塊摘要合并成相應(yīng)的函數(shù)摘要,基于函數(shù)摘要實現(xiàn)過程間分析。此外,該模型維護(hù)了一個已知正則表達(dá)式的數(shù)據(jù)庫(包含正則表達(dá)式的效果),支持對凈化的分析,進(jìn)一步提高了對PHP 語言建模的準(zhǔn)確性。作者在6 個流行的開源PHP 項目代碼上對模型進(jìn)行了測試,發(fā)現(xiàn)了105 個可疑的漏洞。

      V.Benjamin Livshits 和Monica S.Lam[44]構(gòu)建了一個Eclipse 的 Java 應(yīng)用程序靜態(tài)分析插件工具。該工具向使用者提供基于PQL(Program Query Language,程序查詢語言)的分析接口,采用上下文敏感的指針分析對污點對象的傳播進(jìn)行有效地建模,實現(xiàn)了對Java 應(yīng)用程序中存在漏洞的檢測。作者使用該工具在9 個開源Java 應(yīng)用程序中發(fā)現(xiàn)了29 個安全漏洞。

      針對RCE(Remote Code Execution,遠(yuǎn)程代碼執(zhí)行)漏洞,Yunhui Zheng 等[45]提出了一種基于路徑敏感的靜態(tài)分析方法。該方法對目標(biāo)PHP 代碼進(jìn)行切片,刪除與檢測目標(biāo)無關(guān)的語句;然后對切片中針對字符串和非字符串類型處理的行為進(jìn)行抽象和建模,基于路徑敏感和上下文敏感的過程間分析對變量進(jìn)行跟蹤,進(jìn)而能夠跨多個腳本檢測RCE 漏洞。此外,該方法還能夠?qū)討B(tài)腳本包含進(jìn)行處理,進(jìn)一步提高了分析的準(zhǔn)確性。作者在10 個PHP 應(yīng)用程序上測試了該方法,成功發(fā)現(xiàn)了21 個真實的RCE 漏洞,其中有8 個是以前從未報告過的。

      3.2.2 基于學(xué)習(xí)的靜態(tài)分析技術(shù)

      基于學(xué)習(xí)的靜態(tài)分析基本流程如圖5 所示。無論是機(jī)器學(xué)習(xí)模型還是深度學(xué)習(xí)模型,都無法直接處理以源代碼作為輸入的情況,因此需要對源代碼進(jìn)行預(yù)處理。通常,源代碼都是以文本形式給出的,第一步是對其進(jìn)行解析或構(gòu)建程序切片以保留與漏洞檢測相關(guān)的信息;接著使用詞嵌入等技術(shù)將源代碼中間表示或切片映射到向量空間;最后借助機(jī)器學(xué)習(xí)或深度學(xué)習(xí)模型強(qiáng)大的大數(shù)據(jù)挖掘能力學(xué)習(xí)源代碼蘊含的各類信息(如:控制依賴和數(shù)據(jù)依賴信息),進(jìn)而實現(xiàn)漏洞檢測。同時,可以利用傳統(tǒng)靜態(tài)分析方法提取源代碼污點變量的傳播情況、凈化函數(shù)的有效性等信息,豐富模型學(xué)習(xí)的知識空間,從而獲得性能更好的檢測模型。

      VulDeePecker是Zhen Li等[46]提出的一種基于深度學(xué)習(xí)技術(shù)的C/C++漏洞檢測模型。該模型首先提取與library/API 函數(shù)相關(guān)的調(diào)用并獲取與這些調(diào)用相關(guān)的參數(shù)或變量的程序切片;然后將獲得的程序切片組裝成一系列在控制依賴或數(shù)據(jù)依賴上相關(guān)的語句集合(文中稱為代碼gadget);接著將代碼gadget映射為長度相等的向量并利用其訓(xùn)練BiLSTM(Bidirectional Long Short-Term Memory)模型以實現(xiàn)漏洞檢測。作者將 VulDeePecker 應(yīng)用在 Xen、Seamonkey 和Libav 這3 個軟件產(chǎn)品上,檢測到了4個未出現(xiàn)在NVD 中的漏洞。

      Yuelong Wu 等[47]將CPG 進(jìn)行簡化,使其只包含AST 和CFG 相關(guān)的邊,并結(jié)合圖神經(jīng)網(wǎng)絡(luò)和多層感知機(jī)學(xué)習(xí)代碼的圖形表示以從中提取特征。Yaqin Zhou 等[48]提出的Devign 模型以源代碼AST 為主干,將CFG、DFG 以及自然代碼序列(Natural Code Sequence,NCS)引入其中,通過過濾、刪除等操作對融入了額外信息的AST 進(jìn)行優(yōu)化,構(gòu)建了一個稱為聯(lián)合圖(Joint Graph,JG)的代碼圖形表示;最終使用圖神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)源代碼綜合的語義信息進(jìn)而實現(xiàn)漏洞檢測。經(jīng)過測試,該模型相較現(xiàn)有技術(shù),平均準(zhǔn)確率提高了10.51%,平均F1 評分提高了8.68%。

      FTCLNet 模型[49]創(chuàng)新性地將基于傅里葉變換的深度卷積LSTM(Long Short-Term Memory)神經(jīng)網(wǎng)絡(luò)引入到源代碼漏洞檢測中,通過代碼重寫技術(shù)對源代碼進(jìn)行規(guī)范化,使其具有統(tǒng)一的代碼樣式和標(biāo)識符命名規(guī)范,并基于重寫后的代碼提取前向切片和后向切片;接著,采用預(yù)定義的token 映射表對切片進(jìn)行編碼,將其映射到向量空間并進(jìn)行代碼嵌入操作。使用傅里葉變換將代碼映射到頻域,提取代碼的局部特征和全局特征,使用注意力機(jī)制確定代碼空間中每個元素的權(quán)重。實驗表明,針對緩沖區(qū)溢出錯誤(CWE-119),模型的F1 評分達(dá)到90.69%;針對資源管理錯誤(CWE-399),模型的F1 評分達(dá)到95.69%。

      Ibéria Medeiros 等[50]提出了一個以自然語言處理技術(shù)為主導(dǎo)的 PHP 源代碼漏洞檢測工具DEKANT。該工具首先收集一系列存在漏洞和不存在漏洞的PHP 代碼,然后對收集的代碼進(jìn)行過程內(nèi)和過程間分析,提取從程序入口點開始到Sink 結(jié)束的切片;通過預(yù)定義的中間切片語言(Intermediate Slice Language,ISL)語法規(guī)則,將切片轉(zhuǎn)換為ISL 表示(即:將切片轉(zhuǎn)換為token 表示),并為每個token 分配對應(yīng)的狀態(tài)(token 和state(狀態(tài))組成的二元組,稱為觀測序列)。對觀測序列進(jìn)行去重后構(gòu)建用于訓(xùn)練HMM(Hidden Markov Model)模型的語料庫;接著,從語料庫中提取知識(HMM 模型的參數(shù))并用概率矩陣表示,最后訓(xùn)練HMM 模型實現(xiàn)漏洞檢測。作者將模型應(yīng)用在一組開源的PHP 軟件程序和WordPress 插件上,發(fā)現(xiàn)了16 個0-day 漏洞。

      Xin Li 等[51]認(rèn)為編程語言是人類和計算機(jī)之間溝通的橋梁,與自然語言有著相同的功能,因此可以將自然語言處理領(lǐng)域的相關(guān)技術(shù)遷移到對代碼的處理中。通過對源代碼進(jìn)行依賴分析、安全切片、標(biāo)簽化(tokenization)和序列化(serialization),獲得一個名為最小中間表示的源代碼中間表示結(jié)構(gòu)。接著使用CBoW(Continuous Bag-of-Word)模型獲取源代碼的分布式向量表示;然后使用三個級聯(lián)的神經(jīng)網(wǎng)絡(luò)來學(xué)習(xí)源代碼的高級特征,最終使用卷積神經(jīng)網(wǎng)絡(luò)實現(xiàn)漏洞檢測。作者在測試數(shù)據(jù)集上對模型進(jìn)行了全方位的評估,模型最終實現(xiàn)了1.5%的FPR(False Positive Rate)、9.6%的FNR(False Negative Rate)、95.7%的精確率、90.4%的召回率以及93.0%的F1 評分。

      Huanting Wang 等[52]提出了一種基于GGNN(Gated Graph Neural Network)的、能夠跨編程語言遷移的漏洞檢測模型。模型以源代碼的函數(shù)為輸入單位生成對應(yīng)的AST。為了獲取源代碼的語法、數(shù)據(jù)流和控制流等信息,文章向AST 添加了八種類型的邊以構(gòu)成擴(kuò)展的AST。接著使用Word2Vec 將擴(kuò)展的AST 節(jié)點和token 映射為向量,訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型實現(xiàn)漏洞檢測。作者使用該模型對與包括CWE-400、CWE-772 在內(nèi)的前30 種CWE 漏洞類型相關(guān)的C 函數(shù)進(jìn)行了檢測,平均準(zhǔn)確率達(dá)到92.0%。此外,作者還提出了一種名為專家混合的模型以解決訓(xùn)練樣本短缺的問題。

      DeepWuKong[53]是Xiao Cheng 等提出的一種基于深度圖神經(jīng)網(wǎng)絡(luò)的源代碼漏洞檢測模型。作者受到“易受攻擊代碼和安全代碼之間的代碼模式可能有很大的不同,這些不同主要表現(xiàn)在代碼的token、API、控制流和數(shù)據(jù)流這四個方面”這一觀點的啟發(fā),提出一種新的代碼切片算法以捕獲源代碼的高級語義特征。通過對輸入的源代碼構(gòu)建過程間控制流圖(Inter-procedural Control Flow Graph,ICFG)和值流圖(Value Flow Graph),在別名分析的配合下,對控制流信息和數(shù)據(jù)流信息進(jìn)行整合,進(jìn)而構(gòu)建PDG。接著采用提出的代碼切片算法對PDG 進(jìn)行遍歷,提取對應(yīng)的XFG(PDG 的子圖);然后基于XFG 提取結(jié)構(gòu)化信息(XFG 的邊)和非結(jié)構(gòu)化信息(使用Doc2Vec 將代碼轉(zhuǎn)換成的向量),最后訓(xùn)練GNN 模型實現(xiàn)漏洞檢測。作者將DeepWuKong 運用到redis 和lua 兩個開源應(yīng)用程序中,實現(xiàn)了5.0%的FPR、10.0%的FNR、93.0%的準(zhǔn)確率以及90.0%的F1 評分。

      4 分析與討論

      本文立足于源代碼漏洞靜態(tài)分析技術(shù),介紹了該領(lǐng)域典型研究的技術(shù)原理和方法特點,并從源代碼分析方法、中間表示方法、檢測目標(biāo)、關(guān)鍵工具或技術(shù)4 個方面對上文中涉及的文獻(xiàn)進(jìn)行總結(jié)和歸納,如表2 所示。同時,我們還對這些文獻(xiàn)中提到的開源數(shù)據(jù)集或代碼進(jìn)行了總結(jié)和歸納,以支持后續(xù)對該領(lǐng)域的進(jìn)一步研究,結(jié)果如表3 所示。

      表2 文獻(xiàn)關(guān)鍵信息總結(jié)與歸納Table 2 Summary and induction of key information in literatures

      續(xù)表

      表3 開源數(shù)據(jù)集或代碼Table 3 Open source dataset or code

      隨著計算機(jī)軟件領(lǐng)域的發(fā)展,軟件程序與我們生活的聯(lián)系越來越密切,對軟件源代碼漏洞靜態(tài)分析技術(shù)的需求也會隨之變大;因此,對源代碼漏洞靜態(tài)分析技術(shù)的研究勢必會成為今后軟件安全研究者們關(guān)注的重點。然而,在對該領(lǐng)域典型的研究進(jìn)行深入剖析后,我們認(rèn)為在進(jìn)行源代碼漏洞靜態(tài)分析時,主要存在以下5 個難點:

      (1) 源代碼的表示:無論是傳統(tǒng)靜態(tài)分析還是基于學(xué)習(xí)的靜態(tài)分析,都需要將源代碼轉(zhuǎn)換為某種中間表示。不同的中間表示所包含的源代碼信息不同,如:AST 僅能夠表示源代碼的結(jié)構(gòu)信息,無法提供控制流和數(shù)據(jù)流信息;CFG 能夠給出源代碼語句之間的控制依賴關(guān)系,但無法提供數(shù)據(jù)依賴信息。如何選擇和構(gòu)建合理的源代碼中間表示方法以盡可能多地包含源代碼信息是當(dāng)前的一個難點;此外,對于基于學(xué)習(xí)的靜態(tài)分析,由于學(xué)習(xí)模型的輸入是向量形式,所以如何有效地將源代碼映射到向量空間,同時盡可能減少源代碼原有信息的損失也尤為重要。

      (2) 源代碼的建模:對于傳統(tǒng)靜態(tài)分析而言,如何對源代碼進(jìn)行有效建模十分重要,源代碼的建模方式直接決定了分析的準(zhǔn)確性。通常的做法是對程序的結(jié)構(gòu)和行為進(jìn)行抽象,如:對程序的順序、選擇和循環(huán)結(jié)構(gòu)進(jìn)行抽象,亦或是對字符串和非字符串處理例程進(jìn)行抽象,以此實現(xiàn)對程序中語句執(zhí)行邏輯的模擬。然而,僅通過對源代碼的結(jié)構(gòu)、執(zhí)行邏輯等進(jìn)行建模很難適應(yīng)當(dāng)前的軟件開發(fā)環(huán)境。由于代碼對內(nèi)置函數(shù)和外部庫的引用越來越頻繁,各種動態(tài)代碼的引入也越來越常見;如何在缺乏源代碼支持的情況下,對內(nèi)置函數(shù)和外部引用庫的行為進(jìn)行建模、如何對程序的動態(tài)行為進(jìn)行分析、如何針對大型項目進(jìn)行高效的過程間分析以保證程序數(shù)據(jù)流的完整性是當(dāng)前研究的難點;同時,如何自動化地對Source 和Sink 進(jìn)行識別和推理,對代碼中出現(xiàn)的凈化例程進(jìn)行合理地評估也是具有挑戰(zhàn)的。

      (3) 機(jī)器學(xué)習(xí)方法的選擇:機(jī)器學(xué)習(xí)技術(shù)在數(shù)據(jù)挖掘、自然語言處理、計算機(jī)視覺等領(lǐng)域有非常顯著的成果,如:Huang Chen 等[76]提出的利用機(jī)器學(xué)習(xí)技術(shù)自動挖掘關(guān)鍵黑客的模型、Kaiming He 等[77]提出的深度殘差神經(jīng)網(wǎng)絡(luò)圖像識別框架等。將機(jī)器學(xué)習(xí)技術(shù)引入到靜態(tài)分析中是當(dāng)前的研究趨勢,但并不是所有的機(jī)器學(xué)習(xí)方法都適用于程序分析。如何選擇和構(gòu)建合理的學(xué)習(xí)模型來理解和學(xué)習(xí)源代碼表示的信息是基于學(xué)習(xí)的靜態(tài)分析的關(guān)鍵問題。

      (4) 漏洞分析方法的普適性:當(dāng)前的研究大多針對用某一特定類型語言(如:C 和Java)編寫的軟件程序展開。雖然已有的檢測方法在特定的應(yīng)用場景下表現(xiàn)不錯,但在對編程語言的多樣性和迭代更新快等特性的適應(yīng)性問題處理上仍然存在不足。因此,改善漏洞分析方法的普適性,提高分析模型的適配能力是當(dāng)前靜態(tài)分析中的關(guān)鍵問題。

      (5) 數(shù)據(jù)集的匱乏:雖然網(wǎng)絡(luò)上有非常多與軟件漏洞相關(guān)的信息,但是不同于其他領(lǐng)域,能夠用于對漏洞分析模型進(jìn)行訓(xùn)練和評估的數(shù)據(jù)集很少;而且正如李韻等在其文章[78]中提到的,存在部分罕見類型的漏洞,這類漏洞出現(xiàn)的頻率非常低,但其危害性不容忽視;然而由于缺乏合適的數(shù)據(jù)集,導(dǎo)致現(xiàn)有靜態(tài)分析面臨罕見漏洞挖掘困難的問題。因此,如何構(gòu)建統(tǒng)一規(guī)范的數(shù)據(jù)集,如何在數(shù)據(jù)稀缺的情況下對漏洞進(jìn)行有效挖掘是一大難題。

      此外,依據(jù)目標(biāo)場景合理地選擇模型在漏報率和誤報率上的取向也是關(guān)鍵。無論是靜態(tài)分析還是動態(tài)分析,我們都希望分析模型能夠檢測出目標(biāo)代碼中存在的所有漏洞,而且沒有誤報;也就是說分析模型既沒有漏報,也沒有誤報。然而,根據(jù)Rice定理[79]和圖靈停機(jī)問題[80]可知,這種情況是不存在的。如圖6 所示,粉色部分表示Soundness(可以簡單理解為沒有漏報),藍(lán)色部分表示Completeness(可以簡單理解為沒有誤報),綠色部分表示Truth(表示目標(biāo)程序存在漏洞的真實情況)。對于Soundness 而言,包含了目標(biāo)程序存在漏洞的真實情況,但是也包含了真實情況之外的結(jié)果,即存在誤報。對于Completeness 而言,所包含的結(jié)果都屬于真實情況,但是沒有包含全部的真實情況,即存在漏報。因此,在設(shè)計檢測模型時,不管是基于靜態(tài)分析還是動態(tài)分析,都需要根據(jù)具體場景確定模型是傾向于Soundness 還是Completeness,然后再優(yōu)化模型使其靠近Truth。

      5 總結(jié)

      靜態(tài)分析作為軟件分析領(lǐng)域的關(guān)鍵技術(shù),被廣泛運用于對各類軟件的健壯性檢驗和安全檢測中。靜態(tài)分析貫穿整個軟件的生命周期,能夠有效地幫助軟件開發(fā)人員在開發(fā)過程中及時發(fā)現(xiàn)程序存在的錯誤和漏洞,降低軟件上線后被攻擊的風(fēng)險。本文介紹了源代碼漏洞靜態(tài)分析技術(shù)的核心思想和基本原理,分析和總結(jié)了該領(lǐng)域典型的研究工作,闡述了我們認(rèn)為當(dāng)前靜態(tài)分析中存在的難點。

      近年來,機(jī)器學(xué)習(xí)技術(shù)取得了巨大的突破,為靜態(tài)分析注入了新的活力。構(gòu)建自動化、智能化的靜態(tài)分析模型勢必會成為未來的發(fā)展趨勢。在這里我們提供了一些研究思路供同方向的研究人員參考。

      (1) 使用直觀的圖形化結(jié)構(gòu)表示源代碼:使用直觀的圖形化結(jié)構(gòu)表示源代碼不僅便于人類理解源代碼,也能夠幫助機(jī)器學(xué)習(xí)模型更好地挖掘源代碼中的信息。

      (2) 合理的代碼嵌入:合理地將源代碼轉(zhuǎn)換為機(jī)器學(xué)習(xí)模型所需的向量表示,同時盡可能多地包含源代碼的各類信息,降低代碼嵌入時的信息損失,能夠進(jìn)一步提高機(jī)器學(xué)習(xí)模型對源代碼含義的理解。

      (3) 將源代碼的顯式特征和隱式特征相結(jié)合:使用傳統(tǒng)靜態(tài)分析對源代碼的顯式特征進(jìn)行挖掘,使用機(jī)器學(xué)習(xí)方法對源代碼圖結(jié)構(gòu)表示中的隱式特征進(jìn)行挖掘,將這兩種特征相結(jié)合,形成互補,為源代碼漏洞的發(fā)現(xiàn)和挖掘提供更加有效地支撐。

      (4) 合理、適度地使用深度學(xué)習(xí)技術(shù):從傳統(tǒng)機(jī)器學(xué)習(xí)到深度學(xué)習(xí),人工智能領(lǐng)域的發(fā)展取得了巨大的進(jìn)步;深度學(xué)習(xí)技術(shù)在計算機(jī)各個領(lǐng)域上的應(yīng)用也隨之越來越廣泛。雖然深度學(xué)習(xí)技術(shù)在解決某些問題上表現(xiàn)出非常不錯的性能,但是其對海量數(shù)據(jù)和計算機(jī)資源的高度需求也是不容忽視的。對于基于學(xué)習(xí)的靜態(tài)分析,由于漏洞數(shù)據(jù)集稀缺、數(shù)據(jù)集所包含漏洞樣本的覆蓋面不夠廣,導(dǎo)致訓(xùn)練出來的深度學(xué)習(xí)模型存在過擬合問題;而且在面對代碼高速迭代更新的大環(huán)境時,模型的性能往往與實驗結(jié)果相差很大;因此不能盲目地追求使用深度學(xué)習(xí)技術(shù)。

      (5) 從待檢測項目中學(xué)習(xí):“對于合理規(guī)模的軟件項目,通常包含許多功能相似的代碼片段集群,這些代碼片段集群通常由不同的開發(fā)人員貢獻(xiàn),因此它們之間很可能都有相同的bug,所以可以通過識別同一代碼庫中功能相似但不一致的代碼片段來檢測bug”,這是文章[81]中提到的一種bug 檢測思路。文章創(chuàng)新性地提出了一種基于機(jī)器學(xué)習(xí)的bug 檢測技術(shù),它不需要任何外部代碼或樣本來進(jìn)行訓(xùn)練,僅通過對待檢測項目中的函數(shù)片段結(jié)構(gòu)進(jìn)行相似性聚類實現(xiàn)檢測。這為我們提供了靈感。通過從待檢測項目中學(xué)習(xí),也許能夠避免第(4)點中提到的由于數(shù)據(jù)集稀缺導(dǎo)致模型過擬合的問題,有助于我們在真實場景下構(gòu)建高性能的檢測模型。

      猜你喜歡
      污點源代碼漏洞
      人工智能下復(fù)雜軟件源代碼缺陷精準(zhǔn)校正
      漏洞
      基于代碼重寫的動態(tài)污點分析
      基于TXL的源代碼插樁技術(shù)研究
      軟件源代碼非公知性司法鑒定方法探析
      使用Lightroom污點去除工具清理照片中的瑕疵
      三明:“兩票制”堵住加價漏洞
      漏洞在哪兒
      兒童時代(2016年6期)2016-09-14 04:54:43
      揭秘龍湖產(chǎn)品“源代碼”
      高鐵急救應(yīng)補齊三漏洞
      安顺市| 安宁市| 曲麻莱县| 腾冲县| 迭部县| 南部县| 舒兰市| 普陀区| 峨眉山市| 台南县| 阳城县| 阳春市| 庄河市| 云霄县| 年辖:市辖区| 明溪县| 离岛区| 龙川县| 天门市| 顺昌县| 静宁县| 岳阳市| 濉溪县| 乌拉特中旗| 黎川县| 霍山县| 郴州市| 大悟县| 通辽市| 泰来县| 嘉定区| 红桥区| 濮阳市| 马龙县| 司法| 馆陶县| 长岭县| 永康市| 丰城市| 栖霞市| 四平市|