劉嘉勇 ,韓家璇 ,黃 誠(chéng)
1 四川大學(xué) 網(wǎng)絡(luò)空間安全學(xué)院 成都 中國(guó) 610207
隨著互聯(lián)網(wǎng)技術(shù)的發(fā)展,計(jì)算機(jī)軟件系統(tǒng)與用戶(hù)隱私、資產(chǎn)等重要信息的關(guān)系越來(lái)越緊密,大量的用戶(hù)隱私數(shù)據(jù)被上傳到云端存儲(chǔ)。根據(jù)第47 次《中國(guó)互聯(lián)網(wǎng)絡(luò)發(fā)展?fàn)顩r統(tǒng)計(jì)報(bào)告》[1],截至到2020 年12 月,我國(guó)網(wǎng)民的規(guī)模已經(jīng)達(dá)到9.89 億,互聯(lián)網(wǎng)普及率達(dá)70.4%。網(wǎng)絡(luò)購(gòu)物、線(xiàn)上支付、即時(shí)通信已然成為當(dāng)今社會(huì)主流的生活方式。據(jù)統(tǒng)計(jì),2020 年疫情期間全國(guó)一體化政務(wù)服務(wù)平臺(tái)推出的“防疫健康碼”使用次數(shù)超過(guò)400 億次,在線(xiàn)會(huì)議和課程等全新的工作和學(xué)習(xí)模式迅速融入到人們的生活中,互聯(lián)網(wǎng)技術(shù)為中國(guó)抗擊疫情提供了強(qiáng)大的支持。然而,互聯(lián)網(wǎng)技術(shù)的普及也為各類(lèi)軟件系統(tǒng)的安全性提出了巨大的考驗(yàn)。根據(jù)OWASP Top 10 2017 報(bào)告[2]顯示,由node.js 和Spring Boot 編寫(xiě)的微服務(wù)逐漸成為軟件開(kāi)發(fā)的新方向;軟件系統(tǒng)中高擴(kuò)展性的、功能豐富的模塊被攻擊者們重點(diǎn)關(guān)注;XXE(XML External Entities)注入、反序列化攻擊等手段逐漸成為主流。在巨大利益等因素的驅(qū)使下,攻擊者們不斷嘗試尋找各類(lèi)軟件系統(tǒng)中存在的漏洞,試圖繞過(guò)系統(tǒng)的訪(fǎng)問(wèn)控制,實(shí)現(xiàn)竊取和修改重要數(shù)據(jù)、控制系統(tǒng)等非法操作。
軟件漏洞檢測(cè)一直是學(xué)術(shù)界和工業(yè)界討論的核心問(wèn)題。參考長(zhǎng)亭科技發(fā)布的《2019 長(zhǎng)亭年度漏洞威脅分析與2020 安全展望》[3],截至到2019 年年底,中國(guó)國(guó)家信息安全漏洞庫(kù)(China National Vulnerability Database of Information Security,CNNVD)共收集了17820 個(gè)漏洞,中國(guó)國(guó)家信息安全漏洞共享平臺(tái)(China National Vulnerability Database,CNVD)共收集了16208 個(gè)漏洞,相當(dāng)于2019 年每天約有48 個(gè)漏洞被曝光。同時(shí),根據(jù)著名安全研究機(jī)構(gòu)SkyBox Security 發(fā)布的《2020 Vulnerability and Threat Trends Report Mid-Year Update:Key Findings》報(bào)告[4]顯示,2020 年上半年有9000 多個(gè)漏洞被曝光,移動(dòng)端漏洞的數(shù)量增長(zhǎng)迅速。雖然企業(yè)為其軟件系統(tǒng)制定了一系列安全方案,也配置和部署了各類(lèi)安全設(shè)備,但軟件漏洞仍然被頻頻曝出;其根本原因是開(kāi)發(fā)人員缺乏安全意識(shí),在軟件開(kāi)發(fā)時(shí)就為其埋下了不安全因素。此外,隨著計(jì)算機(jī)軟件領(lǐng)域的發(fā)展,軟件代碼開(kāi)源化已然成為一種趨勢(shì)。現(xiàn)如今,軟件的功能越來(lái)越多,系統(tǒng)越來(lái)越復(fù)雜,開(kāi)發(fā)人員將開(kāi)源代碼引入到項(xiàng)目中能夠極大地提高開(kāi)發(fā)效率;但在增加開(kāi)發(fā)便利度的同時(shí),引入開(kāi)源代碼也增加了軟件系統(tǒng)存在漏洞的可能。
軟件漏洞的檢測(cè)方法主要有三種:靜態(tài)檢測(cè)(又稱(chēng):靜態(tài)分析)、動(dòng)態(tài)檢測(cè)(又稱(chēng):動(dòng)態(tài)分析)和動(dòng)靜結(jié)合的檢測(cè)(又稱(chēng):動(dòng)靜結(jié)合的分析或混合分析)。靜態(tài)分析是指在不運(yùn)行軟件程序的前提下,對(duì)軟件代碼進(jìn)行抽象建模,通過(guò)分析程序的屬性進(jìn)而實(shí)現(xiàn)漏洞檢測(cè);動(dòng)態(tài)分析是指向軟件程序輸入特定構(gòu)造的數(shù)據(jù),觀(guān)察程序的運(yùn)行狀態(tài),通過(guò)狀態(tài)判斷程序是否存在漏洞;混合分析則是一種將靜態(tài)分析和動(dòng)態(tài)分析相結(jié)合的混合式漏洞檢測(cè)方法。本文以面向源代碼的靜態(tài)分析領(lǐng)域典型的研究成果作為切入點(diǎn),將該領(lǐng)域的研究分為傳統(tǒng)靜態(tài)分析和基于學(xué)習(xí)的靜態(tài)分析兩個(gè)方向,分別對(duì)這兩個(gè)方向上的研究進(jìn)展和研究成果進(jìn)行歸納總結(jié),討論該領(lǐng)域目前存在的困難并對(duì)未來(lái)的發(fā)展方向進(jìn)行展望。
靜態(tài)分析技術(shù)是指在不運(yùn)行程序代碼的情況下,對(duì)其進(jìn)行詞法分析、語(yǔ)法分析以及語(yǔ)義分析,配合數(shù)據(jù)流分析和污點(diǎn)分析等技術(shù),對(duì)程序代碼進(jìn)行抽象和建模,分析程序的控制依賴(lài)、數(shù)據(jù)依賴(lài)和變量受污染狀態(tài)等信息,通過(guò)安全規(guī)則檢查、模式匹配等方式挖掘程序代碼中存在的漏洞[5-7]。常見(jiàn)的靜態(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)行分析。因?yàn)榉治鍪腔谠创a進(jìn)行的,所以能夠捕獲豐富的代碼結(jié)構(gòu)、語(yǔ)義和邏輯等信息。面向二進(jìn)制代碼的靜態(tài)分析則是以經(jīng)過(guò)反匯編等手段處理后的二進(jìn)制代碼作為輸入,設(shè)法恢復(fù)程序的信息,運(yùn)用模式匹配或補(bǔ)丁對(duì)比等方式實(shí)現(xiàn)漏洞檢測(cè)。相比源代碼,二進(jìn)制代碼缺乏與代碼相關(guān)的高級(jí)語(yǔ)義信息,且以二進(jìn)制代碼形式表示的漏洞模式更為復(fù)雜;然而,由于存在一部分軟件程序是以二進(jìn)制形式發(fā)布的,并不包含軟件程序的源代碼,所以對(duì)于非程序開(kāi)發(fā)方的安全人員而言,研究面向二進(jìn)制代碼的漏洞分析是很重要的。
與靜態(tài)分析不同,動(dòng)態(tài)分析是指在沙箱等受控環(huán)境中執(zhí)行程序,向程序輸入特定的數(shù)據(jù),監(jiān)視其運(yùn)行時(shí)的行為,收集函數(shù)的執(zhí)行結(jié)果、程序的異常行為和崩潰情況等信息以判斷目標(biāo)程序是否存在漏洞[15-16]。常見(jiàn)的動(dòng)態(tài)分析工具有:AFL[17]、Sage[18]和jsfunfuzz[19]等。動(dòng)態(tài)分析技術(shù)包括動(dòng)態(tài)符號(hào)執(zhí)行和模糊測(cè)試兩種。其中,符號(hào)執(zhí)行的目標(biāo)是獲得讓特定代碼區(qū)域執(zhí)行的輸入,通常分為靜態(tài)符號(hào)執(zhí)行和動(dòng)態(tài)符號(hào)執(zhí)行兩種。靜態(tài)符號(hào)執(zhí)行不會(huì)真正執(zhí)行程序,也不會(huì)向程序提供具體的數(shù)據(jù)輸入;而是通過(guò)將程序的輸入抽象為符號(hào),使用約束求解器求解,進(jìn)而獲得讓特定代碼區(qū)域執(zhí)行的輸入,如文章[20]中所做的工作;動(dòng)態(tài)符號(hào)執(zhí)行則是將具體執(zhí)行和符號(hào)執(zhí)行相結(jié)合,以具體的值作為程序的輸入,執(zhí)行程序,收集符號(hào)約束,修改收集的符號(hào)約束內(nèi)容以構(gòu)造不同的可執(zhí)行路徑,進(jìn)而實(shí)現(xiàn)對(duì)程序所有路徑的遍歷[21]。相比于動(dòng)態(tài)符號(hào)執(zhí)行,模糊測(cè)試是近年來(lái)動(dòng)態(tài)分析領(lǐng)域研究的熱門(mén)。模糊測(cè)試是Miller 等在1991 年提出的一個(gè)概念[22],其核心思想是通過(guò)向程序輸入畸形數(shù)據(jù),觀(guān)察程序的執(zhí)行狀態(tài)(如:程序的異常行為和崩潰情況),進(jìn)而判斷程序是否存在漏洞。
靜態(tài)分析和動(dòng)態(tài)分析的差異性對(duì)比如表1 所示。靜態(tài)分析和動(dòng)態(tài)分析面向的目標(biāo)不同;靜態(tài)分析面向的是軟件源代碼和二進(jìn)制代碼,而動(dòng)態(tài)分析大多面向軟件程序本身。通常,靜態(tài)分析可以貫穿整個(gè)軟件生命周期,輔助開(kāi)發(fā)人員及早地發(fā)現(xiàn)軟件代碼中存在的問(wèn)題;分析過(guò)程不需要將程序?qū)嶋H地運(yùn)行起來(lái),而是對(duì)程序代碼進(jìn)行抽象和建模,因此分析器能夠在低資源需求的前提下實(shí)現(xiàn)高代碼覆蓋率。但是,由于分析器對(duì)程序代碼具有極高的依賴(lài)性,導(dǎo)致在程序代碼缺失的情況下難以對(duì)程序進(jìn)行分析;由于分析是基于對(duì)程序代碼的抽象和建模,分析器的分析邏輯很大程度上取決于對(duì)漏洞已有的先驗(yàn)知識(shí),所以在面對(duì)未定義的程序錯(cuò)誤行為時(shí),靜態(tài)分析往往存在誤報(bào)率高的問(wèn)題;此外,靜態(tài)分析還存在運(yùn)行時(shí)漏洞檢測(cè)難問(wèn)題。
表1 靜態(tài)分析和動(dòng)態(tài)分析差異性對(duì)比Table 1 Comparison of differences between static analysis and dynamic analysis
對(duì)于動(dòng)態(tài)分析而言,因?yàn)榉治銎餍枰獙?duì)程序的運(yùn)行時(shí)信息進(jìn)行跟蹤、收集和分析,所以對(duì)系統(tǒng)環(huán)境的要求較高,需要為不同的程序配置不同的運(yùn)行環(huán)境;但是由于是基于程序的實(shí)際運(yùn)行情況進(jìn)行分析的,因此分析的精確度較高,而且能夠?qū)?jīng)過(guò)混淆的代碼進(jìn)行檢測(cè)。不過(guò),因?yàn)樾枰\(yùn)行程序觀(guān)察其執(zhí)行情況,而當(dāng)前環(huán)境下很多程序的代碼空間很大,分析器在短時(shí)間內(nèi)難以覆蓋整個(gè)程序空間,所以動(dòng)態(tài)分析的漏報(bào)率相對(duì)較高;而且以動(dòng)態(tài)符號(hào)執(zhí)行為主的動(dòng)態(tài)分析還面臨著路徑爆炸[23]等問(wèn)題。
無(wú)論是靜態(tài)分析技術(shù)還是動(dòng)態(tài)分析技術(shù),都能夠?yàn)樘幵诨ヂ?lián)網(wǎng)快速發(fā)展背景下的軟件系統(tǒng)安全提供強(qiáng)有力的保障。近年來(lái),為了在軟件系統(tǒng)上線(xiàn)前就對(duì)其可能存在的漏洞進(jìn)行檢測(cè),將軟件系統(tǒng)面臨的風(fēng)險(xiǎn)扼殺在搖籃中,進(jìn)一步減少軟件系統(tǒng)上線(xiàn)后可能受到的安全威脅,越來(lái)越多的企業(yè)開(kāi)始在軟件開(kāi)發(fā)過(guò)程中使用靜態(tài)分析對(duì)軟件漏洞進(jìn)行挖掘。本節(jié)對(duì)軟件漏洞分析技術(shù)的基本概念進(jìn)行了解釋,讓讀者對(duì)該領(lǐng)域的基本情況有一個(gè)初步的了解。在接下來(lái)的章節(jié)中,我們會(huì)對(duì)靜態(tài)分析領(lǐng)域的相關(guān)概念和技術(shù)、研究進(jìn)展以及研究成果進(jìn)行詳細(xì)闡述,并給出我們對(duì)該領(lǐng)域未來(lái)發(fā)展趨勢(shì)的一些看法。
將源代碼轉(zhuǎn)換成合適的中間表示是進(jìn)行源代碼漏洞靜態(tài)分析的第一步。源代碼的表示方法主要分為兩大類(lèi):樹(shù)形表示和圖形表示。樹(shù)形表示主要以抽象語(yǔ)法樹(shù)(Abstract Syntax Tree,AST)為主;圖形表示主要包括:控制流圖(Control Flow Graph,CFG)、數(shù)據(jù)流圖(Data Flow Graph,DFG)、調(diào)用圖(Call Graph,CG)、程序依賴(lài)圖(Program Dependence Graph,PDG)、系統(tǒng)依賴(lài)圖(System Dependence Graph,SDG)和代碼屬性圖(Code Property Graph,CPG)。如圖1 所示,AST 是由代碼解析器對(duì)源代碼進(jìn)行詞法分析和語(yǔ)法分析后生成的最基本的中間表示,也是其他中間表示的基礎(chǔ),能夠清楚地反映源代碼的結(jié)構(gòu)信息,在源代碼漏洞檢測(cè)中有著很重要的作用。陳肇炫等人[24]提出的Astor模型[24]通過(guò)將源代碼轉(zhuǎn)換成AST,采用深度優(yōu)先遍歷算法獲取AST 的語(yǔ)法表征并訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型對(duì)其進(jìn)行學(xué)習(xí),實(shí)現(xiàn)了基于源代碼結(jié)構(gòu)信息的智能化漏洞檢測(cè)。Hantao Feng 等[25]將源代碼轉(zhuǎn)換成AST,然后將AST 轉(zhuǎn)換為序列,利用詞嵌入技術(shù)將序列轉(zhuǎn)換為向量,保留了源代碼的語(yǔ)義特征;通過(guò)訓(xùn)練BGRU (Bidirectional Gate Recurrent Unite)模型,從向量中提取特征以實(shí)現(xiàn)漏洞檢測(cè)。文章[26]從源代碼中提取AST,將其嵌入到向量空間中,然后使用潛在語(yǔ)義分析技術(shù)[27]識(shí)別代碼的結(jié)構(gòu)模式,從而實(shí)現(xiàn)漏洞外推。
CFG、DFG 和CG 可以通過(guò)分析AST 直接獲得。CFG 能夠描述語(yǔ)句的執(zhí)行順序以及語(yǔ)句間的支配關(guān)系(即:控制依賴(lài)關(guān)系),DFG 能夠表示語(yǔ)句和變量間的數(shù)據(jù)依賴(lài)關(guān)系,CG 能夠表示函數(shù)的調(diào)用情況。通過(guò)從CFG 中提取控制依賴(lài)關(guān)系,從DFG 中提取數(shù)據(jù)依賴(lài)關(guān)系,將兩種關(guān)系融合到同一張圖中,進(jìn)而形成PDG;再依據(jù)CG 將不同函數(shù)的PDG 連接起來(lái),形成過(guò)程間程序依賴(lài)圖,即SDG。
CPG 是Yamaguchi 等人在論文[28]中提出的一種全新的源代碼中間表示形式,是當(dāng)前源代碼漏洞靜態(tài)分析技術(shù)中最新、使用最為廣泛的源代碼圖形表示,由AST、CFG 和PDG 合并而成,如圖2 所示。相比于其他源代碼中間表示形式,CPG 能夠很好地反映源代碼的結(jié)構(gòu)、語(yǔ)句執(zhí)行順序、控制依賴(lài)和數(shù)據(jù)依賴(lài)等信息;在文章[28]中,作者首次提出使用CPG 表示源代碼,采用圖形數(shù)據(jù)庫(kù)Neo4J[29]存儲(chǔ)并遍歷CPG以實(shí)現(xiàn)漏洞檢測(cè)。同時(shí),Yamaguchi 等在文章[30]中還提出了一種自動(dòng)推斷C 代碼中污點(diǎn)型漏洞搜索模式的方法,該方法通過(guò)對(duì)CPG 進(jìn)行擴(kuò)展以支持過(guò)程間分析;通過(guò)給定Sink(Sink 指污點(diǎn)的匯聚點(diǎn)),該方法能夠自動(dòng)識(shí)別對(duì)應(yīng)的Source-Sink(Source 指污點(diǎn)源)系統(tǒng)并對(duì)系統(tǒng)中的數(shù)據(jù)流和Sanitization (Sanitization 指對(duì)污點(diǎn)數(shù)據(jù)的無(wú)害處理,即凈化)進(jìn)行建模,生成污點(diǎn)型漏洞的搜索模式;基于推斷的搜索模式對(duì)CPG 進(jìn)行遍歷,從而檢測(cè)源代碼中存在的漏洞。Peng Wu 等[31]提出基于CPG 從AST 和API 的子樹(shù)中提取代碼特征,然后使用詞袋模型和TF-IDF 模型將代碼特征嵌入到向量空間;同時(shí)從CVE 上提取漏洞代碼及其補(bǔ)丁的代碼切片,計(jì)算源代碼、漏洞代碼、補(bǔ)丁代碼之間的相似性以實(shí)現(xiàn)漏洞檢測(cè)。
源代碼的分析方法可以分為兩類(lèi),一類(lèi)是傳統(tǒng)靜態(tài)分析,另一類(lèi)是基于學(xué)習(xí)的靜態(tài)分析。傳統(tǒng)靜態(tài)分析主要基于數(shù)據(jù)流分析和污點(diǎn)分析,通過(guò)對(duì)源代碼進(jìn)行抽象、建模和分析實(shí)現(xiàn)漏洞檢測(cè);基于學(xué)習(xí)的靜態(tài)分析則是將機(jī)器學(xué)習(xí)技術(shù)運(yùn)用到靜態(tài)分析中,利用其強(qiáng)大的大數(shù)據(jù)挖掘能力,學(xué)習(xí)源代碼的運(yùn)行邏輯、數(shù)據(jù)流動(dòng)等信息,進(jìn)一步通過(guò)學(xué)習(xí)模型判斷源代碼中是否存在漏洞。下面將對(duì)這兩種分析方法的實(shí)現(xiàn)原理和典型技術(shù)進(jìn)行詳細(xì)介紹。
3.2.1 傳統(tǒng)靜態(tài)分析技術(shù)
傳統(tǒng)靜態(tài)分析的基本流程如圖3 所示。首先需要對(duì)待檢測(cè)源代碼進(jìn)行抽象和建模,通過(guò)解析器執(zhí)行詞法分析和語(yǔ)法分析,生成特定的中間表示;然后基于該中間表示,采用預(yù)設(shè)的漏洞分析規(guī)則,結(jié)合數(shù)據(jù)流分析和污點(diǎn)分析,收集源代碼中與漏洞相關(guān)的信息;最后,對(duì)收集的信息進(jìn)行分析,給出檢測(cè)結(jié)果。
傳統(tǒng)靜態(tài)分析的核心技術(shù)是數(shù)據(jù)流分析和污點(diǎn)分析。數(shù)據(jù)流分析是一種基于格(lattice)理論的、用來(lái)獲取相關(guān)數(shù)據(jù)(如:變量及其取值)沿著程序執(zhí)行路徑流動(dòng)的信息的程序分析技術(shù),常用于源代碼的編譯優(yōu)化過(guò)程,能夠獲得變量在某個(gè)程序點(diǎn)上的性質(zhì)、狀態(tài)、取值等信息[32-33]。常用的數(shù)據(jù)流分析方法有:
(1) 到達(dá)定義分析(Reaching Definition Analysis):給定一個(gè)程序點(diǎn)p 和變量定義d,判斷在CFG上是否存在一條從d 到p 的路徑,該路徑上沒(méi)有對(duì)d進(jìn)行重新定義的指令。如果存在這么一條路徑,則稱(chēng)定義d 可以到達(dá)程序點(diǎn)p;否則,定義d 不能到達(dá)程序點(diǎn)p。
(2) 存活變量分析(Live Variable Analysis):給定一個(gè)程序點(diǎn)p 和變量v,判斷在CFG 上是否存在一條從p 開(kāi)始的路徑,該路徑上有使用了v 的指令。如果存在這么一條路徑,則稱(chēng)變量v 在程序點(diǎn)p 處是存活的;否則,變量v 在程序點(diǎn)p 處不存活。
(3) 可用表達(dá)式分析(Available Expression Analysis):給定一個(gè)程序點(diǎn)p 和表達(dá)式x op y(其中,op 表示operator,指操作符),判斷在 CFG 上從ENTRY節(jié)點(diǎn)到p的所有路徑是否都執(zhí)行了x op y,且最后一次執(zhí)行x op y 后,沒(méi)有對(duì)x 和y 進(jìn)行重新定義。如果滿(mǎn)足上述條件(即: CFG 上從ENTRY 節(jié)點(diǎn)到p 的所有路徑都執(zhí)行了x op y,且最后一次執(zhí)行x op y后沒(méi)有對(duì)x 和y進(jìn)行重新定義),則稱(chēng)表達(dá)式x op y 在程序點(diǎn)p 處是可用的;否則,表達(dá)式x op y 在程序點(diǎn)p 處不可用。
除了上面提到的三種數(shù)據(jù)流分析方法外,數(shù)據(jù)流分析方法還包括:常量傳播分析(Constant Propagation Analysis)[34]、指針?lè)治?Pointer Analysis)[35]等。常量傳播分析的目標(biāo)是判斷在給定程序點(diǎn)p 處指令i中的變量v 的值是否為常數(shù);指針?lè)治鰟t是一種用于分析變量指向的技術(shù),如:對(duì)于Java 語(yǔ)言,利用指針?lè)治雠袛嘟o定變量v 所指向的對(duì)象o(Object)。
污點(diǎn)分析是一種信息流分析技術(shù),通過(guò)對(duì)程序中的敏感數(shù)據(jù)進(jìn)行標(biāo)記,跟蹤標(biāo)記數(shù)據(jù)在程序中的傳播,從而檢測(cè)系統(tǒng)中存在的安全問(wèn)題[36-37]。根據(jù)王蕾等[38]的論文,污點(diǎn)分析的基本流程如圖4 所示。污點(diǎn)分析被定義為三元組
傳統(tǒng)靜態(tài)分析技術(shù)在軟件源代碼漏洞檢測(cè)中有著廣泛的應(yīng)用。Johannes Dahse 等[39]對(duì)PHP 語(yǔ)言進(jìn)分析,為每個(gè)PHP 文件構(gòu)建對(duì)應(yīng)的AST,從中提取出用戶(hù)自定義函數(shù)的相關(guān)信息,如:函數(shù)名和參數(shù),同時(shí)構(gòu)建函數(shù)體的AST,然后將用戶(hù)自定義函數(shù)從前面為PHP 文件構(gòu)建的AST(文中稱(chēng)為主AST)中刪除;接著,使用名為CFGBuilder 的模塊將獲取的AST 轉(zhuǎn)換為CFG;在構(gòu)建CFG 的過(guò)程中,對(duì)每個(gè)基本塊進(jìn)行數(shù)據(jù)流分析和污點(diǎn)分析,將分析結(jié)果存儲(chǔ)在一個(gè)稱(chēng)為塊摘要(Block Summary)的數(shù)據(jù)結(jié)構(gòu)中,以便后續(xù)執(zhí)行過(guò)程間分析使用。在進(jìn)行污點(diǎn)分析時(shí),為保證分析的準(zhǔn)確性,作者對(duì)925 個(gè)PHP 內(nèi)置函數(shù)進(jìn)行建模,同時(shí)還引入了字符串分析(String Analysis);此外,通過(guò)對(duì)包含的文件(即:通過(guò)include 等關(guān)鍵字引入的文件)進(jìn)行建模,將包含的文件視作為函數(shù),進(jìn)一步提高了分析的精確度。作者讓模型在5 個(gè)開(kāi)源軟件上進(jìn)行了測(cè)試,平均TP(True Positive)達(dá)到了72%,平均FP(False Positive)達(dá)到了28%,平均FN(False Negative)達(dá)到了24%。
Xuexiong Yan 等[40]提出一種基于后向污點(diǎn)分析的Web 應(yīng)用程序漏洞檢測(cè)模型。該模型首先從PHP代碼中提取AST、CFG 和CG,然后對(duì)Sink 進(jìn)行查找,構(gòu)建與Sink 相關(guān)的上下文信息;接著,執(zhí)行污點(diǎn)分析,在基本塊內(nèi)和基本塊間跟蹤敏感變量的流動(dòng),最終在測(cè)試數(shù)據(jù)集上成功檢測(cè)出13 個(gè)漏洞。Pixy[41]是Nenad Jovanovic 等提出的用于檢測(cè)Web 應(yīng)用程序漏洞的靜態(tài)分析工具。該工具采用流和上下文敏感的過(guò)程間數(shù)據(jù)流分析方法,同時(shí)基于別名分析和常量傳播分析,對(duì)采用PHP 語(yǔ)言編寫(xiě)的Web 應(yīng)用程序漏洞進(jìn)行檢測(cè)。
Libo Chen 等[42]提出一種針對(duì)嵌入式設(shè)備中提供的Web 服務(wù)漏洞的污點(diǎn)分析方法。作者發(fā)現(xiàn)網(wǎng)絡(luò)接口上的字符串通常在前端文件和后端二進(jìn)制文件之間共享以編碼用戶(hù)輸入?;谶@個(gè)發(fā)現(xiàn),該方法首先在未打包固件的前端文件(HTML、XML 和JavaScript 文件)中提取關(guān)鍵字,然后基于前端提取的關(guān)鍵字,在后端二進(jìn)制文件中查找與關(guān)鍵字對(duì)應(yīng)的入口點(diǎn),利用路徑探索和污點(diǎn)分析技術(shù)跟蹤輸入數(shù)據(jù)的流動(dòng),實(shí)現(xiàn)對(duì)嵌入式設(shè)備中提供的Web 服務(wù)漏洞的檢測(cè)。作者使用該方法成功在包括Tenda W20E在內(nèi)的12 款路由器中找出了33 個(gè)bug,其中有30個(gè)已經(jīng)被確認(rèn)。
Yichen Xie 和Alex Aiken[43]針對(duì)PHP 語(yǔ)言提出了一種結(jié)合基本塊內(nèi)、過(guò)程內(nèi)和過(guò)程間分析的腳本語(yǔ)言漏洞檢測(cè)模型。該模型將輸入的PHP 代碼解析為AST,基于AST 構(gòu)建對(duì)應(yīng)的CFG,然后使用符號(hào)執(zhí)行技術(shù)分析CFG 的每一個(gè)基本塊并對(duì)基本塊內(nèi)的動(dòng)態(tài)特性進(jìn)行建模,生成塊摘要;接著使用可達(dá)性分析將每個(gè)塊摘要合并成相應(yīng)的函數(shù)摘要,基于函數(shù)摘要實(shí)現(xiàn)過(guò)程間分析。此外,該模型維護(hù)了一個(gè)已知正則表達(dá)式的數(shù)據(jù)庫(kù)(包含正則表達(dá)式的效果),支持對(duì)凈化的分析,進(jìn)一步提高了對(duì)PHP 語(yǔ)言建模的準(zhǔn)確性。作者在6 個(gè)流行的開(kāi)源PHP 項(xiàng)目代碼上對(duì)模型進(jìn)行了測(cè)試,發(fā)現(xiàn)了105 個(gè)可疑的漏洞。
V.Benjamin Livshits 和Monica S.Lam[44]構(gòu)建了一個(gè)Eclipse 的 Java 應(yīng)用程序靜態(tài)分析插件工具。該工具向使用者提供基于PQL(Program Query Language,程序查詢(xún)語(yǔ)言)的分析接口,采用上下文敏感的指針?lè)治鰧?duì)污點(diǎn)對(duì)象的傳播進(jìn)行有效地建模,實(shí)現(xiàn)了對(duì)Java 應(yīng)用程序中存在漏洞的檢測(cè)。作者使用該工具在9 個(gè)開(kāi)源Java 應(yīng)用程序中發(fā)現(xiàn)了29 個(gè)安全漏洞。
針對(duì)RCE(Remote Code Execution,遠(yuǎn)程代碼執(zhí)行)漏洞,Yunhui Zheng 等[45]提出了一種基于路徑敏感的靜態(tài)分析方法。該方法對(duì)目標(biāo)PHP 代碼進(jìn)行切片,刪除與檢測(cè)目標(biāo)無(wú)關(guān)的語(yǔ)句;然后對(duì)切片中針對(duì)字符串和非字符串類(lèi)型處理的行為進(jìn)行抽象和建模,基于路徑敏感和上下文敏感的過(guò)程間分析對(duì)變量進(jìn)行跟蹤,進(jìn)而能夠跨多個(gè)腳本檢測(cè)RCE 漏洞。此外,該方法還能夠?qū)?dòng)態(tài)腳本包含進(jìn)行處理,進(jìn)一步提高了分析的準(zhǔn)確性。作者在10 個(gè)PHP 應(yīng)用程序上測(cè)試了該方法,成功發(fā)現(xiàn)了21 個(gè)真實(shí)的RCE 漏洞,其中有8 個(gè)是以前從未報(bào)告過(guò)的。
3.2.2 基于學(xué)習(xí)的靜態(tài)分析技術(shù)
基于學(xué)習(xí)的靜態(tài)分析基本流程如圖5 所示。無(wú)論是機(jī)器學(xué)習(xí)模型還是深度學(xué)習(xí)模型,都無(wú)法直接處理以源代碼作為輸入的情況,因此需要對(duì)源代碼進(jìn)行預(yù)處理。通常,源代碼都是以文本形式給出的,第一步是對(duì)其進(jìn)行解析或構(gòu)建程序切片以保留與漏洞檢測(cè)相關(guān)的信息;接著使用詞嵌入等技術(shù)將源代碼中間表示或切片映射到向量空間;最后借助機(jī)器學(xué)習(xí)或深度學(xué)習(xí)模型強(qiáng)大的大數(shù)據(jù)挖掘能力學(xué)習(xí)源代碼蘊(yùn)含的各類(lèi)信息(如:控制依賴(lài)和數(shù)據(jù)依賴(lài)信息),進(jìn)而實(shí)現(xiàn)漏洞檢測(cè)。同時(shí),可以利用傳統(tǒng)靜態(tài)分析方法提取源代碼污點(diǎn)變量的傳播情況、凈化函數(shù)的有效性等信息,豐富模型學(xué)習(xí)的知識(shí)空間,從而獲得性能更好的檢測(cè)模型。
VulDeePecker是Zhen Li等[46]提出的一種基于深度學(xué)習(xí)技術(shù)的C/C++漏洞檢測(cè)模型。該模型首先提取與library/API 函數(shù)相關(guān)的調(diào)用并獲取與這些調(diào)用相關(guān)的參數(shù)或變量的程序切片;然后將獲得的程序切片組裝成一系列在控制依賴(lài)或數(shù)據(jù)依賴(lài)上相關(guān)的語(yǔ)句集合(文中稱(chēng)為代碼gadget);接著將代碼gadget映射為長(zhǎng)度相等的向量并利用其訓(xùn)練BiLSTM(Bidirectional Long Short-Term Memory)模型以實(shí)現(xiàn)漏洞檢測(cè)。作者將 VulDeePecker 應(yīng)用在 Xen、Seamonkey 和Libav 這3 個(gè)軟件產(chǎn)品上,檢測(cè)到了4個(gè)未出現(xiàn)在NVD 中的漏洞。
Yuelong Wu 等[47]將CPG 進(jìn)行簡(jiǎ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)引入其中,通過(guò)過(guò)濾、刪除等操作對(duì)融入了額外信息的AST 進(jìn)行優(yōu)化,構(gòu)建了一個(gè)稱(chēng)為聯(lián)合圖(Joint Graph,JG)的代碼圖形表示;最終使用圖神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)源代碼綜合的語(yǔ)義信息進(jìn)而實(shí)現(xiàn)漏洞檢測(cè)。經(jīng)過(guò)測(cè)試,該模型相較現(xiàn)有技術(shù),平均準(zhǔn)確率提高了10.51%,平均F1 評(píng)分提高了8.68%。
FTCLNet 模型[49]創(chuàng)新性地將基于傅里葉變換的深度卷積LSTM(Long Short-Term Memory)神經(jīng)網(wǎng)絡(luò)引入到源代碼漏洞檢測(cè)中,通過(guò)代碼重寫(xiě)技術(shù)對(duì)源代碼進(jìn)行規(guī)范化,使其具有統(tǒng)一的代碼樣式和標(biāo)識(shí)符命名規(guī)范,并基于重寫(xiě)后的代碼提取前向切片和后向切片;接著,采用預(yù)定義的token 映射表對(duì)切片進(jìn)行編碼,將其映射到向量空間并進(jìn)行代碼嵌入操作。使用傅里葉變換將代碼映射到頻域,提取代碼的局部特征和全局特征,使用注意力機(jī)制確定代碼空間中每個(gè)元素的權(quán)重。實(shí)驗(yàn)表明,針對(duì)緩沖區(qū)溢出錯(cuò)誤(CWE-119),模型的F1 評(píng)分達(dá)到90.69%;針對(duì)資源管理錯(cuò)誤(CWE-399),模型的F1 評(píng)分達(dá)到95.69%。
Ibéria Medeiros 等[50]提出了一個(gè)以自然語(yǔ)言處理技術(shù)為主導(dǎo)的 PHP 源代碼漏洞檢測(cè)工具DEKANT。該工具首先收集一系列存在漏洞和不存在漏洞的PHP 代碼,然后對(duì)收集的代碼進(jìn)行過(guò)程內(nèi)和過(guò)程間分析,提取從程序入口點(diǎn)開(kāi)始到Sink 結(jié)束的切片;通過(guò)預(yù)定義的中間切片語(yǔ)言(Intermediate Slice Language,ISL)語(yǔ)法規(guī)則,將切片轉(zhuǎn)換為ISL 表示(即:將切片轉(zhuǎn)換為token 表示),并為每個(gè)token 分配對(duì)應(yīng)的狀態(tài)(token 和state(狀態(tài))組成的
Xin Li 等[51]認(rèn)為編程語(yǔ)言是人類(lèi)和計(jì)算機(jī)之間溝通的橋梁,與自然語(yǔ)言有著相同的功能,因此可以將自然語(yǔ)言處理領(lǐng)域的相關(guān)技術(shù)遷移到對(duì)代碼的處理中。通過(guò)對(duì)源代碼進(jìn)行依賴(lài)分析、安全切片、標(biāo)簽化(tokenization)和序列化(serialization),獲得一個(gè)名為最小中間表示的源代碼中間表示結(jié)構(gòu)。接著使用CBoW(Continuous Bag-of-Word)模型獲取源代碼的分布式向量表示;然后使用三個(gè)級(jí)聯(lián)的神經(jīng)網(wǎng)絡(luò)來(lái)學(xué)習(xí)源代碼的高級(jí)特征,最終使用卷積神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)漏洞檢測(cè)。作者在測(cè)試數(shù)據(jù)集上對(duì)模型進(jìn)行了全方位的評(píng)估,模型最終實(shí)現(xiàn)了1.5%的FPR(False Positive Rate)、9.6%的FNR(False Negative Rate)、95.7%的精確率、90.4%的召回率以及93.0%的F1 評(píng)分。
Huanting Wang 等[52]提出了一種基于GGNN(Gated Graph Neural Network)的、能夠跨編程語(yǔ)言遷移的漏洞檢測(cè)模型。模型以源代碼的函數(shù)為輸入單位生成對(duì)應(yīng)的AST。為了獲取源代碼的語(yǔ)法、數(shù)據(jù)流和控制流等信息,文章向AST 添加了八種類(lèi)型的邊以構(gòu)成擴(kuò)展的AST。接著使用Word2Vec 將擴(kuò)展的AST 節(jié)點(diǎn)和token 映射為向量,訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型實(shí)現(xiàn)漏洞檢測(cè)。作者使用該模型對(duì)與包括CWE-400、CWE-772 在內(nèi)的前30 種CWE 漏洞類(lèi)型相關(guān)的C 函數(shù)進(jìn)行了檢測(cè),平均準(zhǔn)確率達(dá)到92.0%。此外,作者還提出了一種名為專(zhuān)家混合的模型以解決訓(xùn)練樣本短缺的問(wèn)題。
DeepWuKong[53]是Xiao Cheng 等提出的一種基于深度圖神經(jīng)網(wǎng)絡(luò)的源代碼漏洞檢測(cè)模型。作者受到“易受攻擊代碼和安全代碼之間的代碼模式可能有很大的不同,這些不同主要表現(xiàn)在代碼的token、API、控制流和數(shù)據(jù)流這四個(gè)方面”這一觀(guān)點(diǎn)的啟發(fā),提出一種新的代碼切片算法以捕獲源代碼的高級(jí)語(yǔ)義特征。通過(guò)對(duì)輸入的源代碼構(gòu)建過(guò)程間控制流圖(Inter-procedural Control Flow Graph,ICFG)和值流圖(Value Flow Graph),在別名分析的配合下,對(duì)控制流信息和數(shù)據(jù)流信息進(jìn)行整合,進(jìn)而構(gòu)建PDG。接著采用提出的代碼切片算法對(duì)PDG 進(jìn)行遍歷,提取對(duì)應(yīng)的XFG(PDG 的子圖);然后基于XFG 提取結(jié)構(gòu)化信息(XFG 的邊)和非結(jié)構(gòu)化信息(使用Doc2Vec 將代碼轉(zhuǎn)換成的向量),最后訓(xùn)練GNN 模型實(shí)現(xiàn)漏洞檢測(cè)。作者將DeepWuKong 運(yùn)用到redis 和lua 兩個(gè)開(kāi)源應(yīng)用程序中,實(shí)現(xiàn)了5.0%的FPR、10.0%的FNR、93.0%的準(zhǔn)確率以及90.0%的F1 評(píng)分。
本文立足于源代碼漏洞靜態(tài)分析技術(shù),介紹了該領(lǐng)域典型研究的技術(shù)原理和方法特點(diǎn),并從源代碼分析方法、中間表示方法、檢測(cè)目標(biāo)、關(guān)鍵工具或技術(shù)4 個(gè)方面對(duì)上文中涉及的文獻(xiàn)進(jìn)行總結(jié)和歸納,如表2 所示。同時(shí),我們還對(duì)這些文獻(xiàn)中提到的開(kāi)源數(shù)據(jù)集或代碼進(jìn)行了總結(jié)和歸納,以支持后續(xù)對(duì)該領(lǐng)域的進(jìn)一步研究,結(jié)果如表3 所示。
表2 文獻(xiàn)關(guān)鍵信息總結(jié)與歸納Table 2 Summary and induction of key information in literatures
續(xù)表
表3 開(kāi)源數(shù)據(jù)集或代碼Table 3 Open source dataset or code
隨著計(jì)算機(jī)軟件領(lǐng)域的發(fā)展,軟件程序與我們生活的聯(lián)系越來(lái)越密切,對(duì)軟件源代碼漏洞靜態(tài)分析技術(shù)的需求也會(huì)隨之變大;因此,對(duì)源代碼漏洞靜態(tài)分析技術(shù)的研究勢(shì)必會(huì)成為今后軟件安全研究者們關(guān)注的重點(diǎn)。然而,在對(duì)該領(lǐng)域典型的研究進(jìn)行深入剖析后,我們認(rèn)為在進(jìn)行源代碼漏洞靜態(tài)分析時(shí),主要存在以下5 個(gè)難點(diǎn):
(1) 源代碼的表示:無(wú)論是傳統(tǒng)靜態(tài)分析還是基于學(xué)習(xí)的靜態(tài)分析,都需要將源代碼轉(zhuǎn)換為某種中間表示。不同的中間表示所包含的源代碼信息不同,如:AST 僅能夠表示源代碼的結(jié)構(gòu)信息,無(wú)法提供控制流和數(shù)據(jù)流信息;CFG 能夠給出源代碼語(yǔ)句之間的控制依賴(lài)關(guān)系,但無(wú)法提供數(shù)據(jù)依賴(lài)信息。如何選擇和構(gòu)建合理的源代碼中間表示方法以盡可能多地包含源代碼信息是當(dāng)前的一個(gè)難點(diǎn);此外,對(duì)于基于學(xué)習(xí)的靜態(tài)分析,由于學(xué)習(xí)模型的輸入是向量形式,所以如何有效地將源代碼映射到向量空間,同時(shí)盡可能減少源代碼原有信息的損失也尤為重要。
(2) 源代碼的建模:對(duì)于傳統(tǒng)靜態(tài)分析而言,如何對(duì)源代碼進(jìn)行有效建模十分重要,源代碼的建模方式直接決定了分析的準(zhǔn)確性。通常的做法是對(duì)程序的結(jié)構(gòu)和行為進(jìn)行抽象,如:對(duì)程序的順序、選擇和循環(huán)結(jié)構(gòu)進(jìn)行抽象,亦或是對(duì)字符串和非字符串處理例程進(jìn)行抽象,以此實(shí)現(xiàn)對(duì)程序中語(yǔ)句執(zhí)行邏輯的模擬。然而,僅通過(guò)對(duì)源代碼的結(jié)構(gòu)、執(zhí)行邏輯等進(jìn)行建模很難適應(yīng)當(dāng)前的軟件開(kāi)發(fā)環(huán)境。由于代碼對(duì)內(nèi)置函數(shù)和外部庫(kù)的引用越來(lái)越頻繁,各種動(dòng)態(tài)代碼的引入也越來(lái)越常見(jiàn);如何在缺乏源代碼支持的情況下,對(duì)內(nèi)置函數(shù)和外部引用庫(kù)的行為進(jìn)行建模、如何對(duì)程序的動(dòng)態(tài)行為進(jìn)行分析、如何針對(duì)大型項(xiàng)目進(jìn)行高效的過(guò)程間分析以保證程序數(shù)據(jù)流的完整性是當(dāng)前研究的難點(diǎn);同時(shí),如何自動(dòng)化地對(duì)Source 和Sink 進(jìn)行識(shí)別和推理,對(duì)代碼中出現(xiàn)的凈化例程進(jìn)行合理地評(píng)估也是具有挑戰(zhàn)的。
(3) 機(jī)器學(xué)習(xí)方法的選擇:機(jī)器學(xué)習(xí)技術(shù)在數(shù)據(jù)挖掘、自然語(yǔ)言處理、計(jì)算機(jī)視覺(jué)等領(lǐng)域有非常顯著的成果,如:Huang Chen 等[76]提出的利用機(jī)器學(xué)習(xí)技術(shù)自動(dòng)挖掘關(guān)鍵黑客的模型、Kaiming He 等[77]提出的深度殘差神經(jīng)網(wǎng)絡(luò)圖像識(shí)別框架等。將機(jī)器學(xué)習(xí)技術(shù)引入到靜態(tài)分析中是當(dāng)前的研究趨勢(shì),但并不是所有的機(jī)器學(xué)習(xí)方法都適用于程序分析。如何選擇和構(gòu)建合理的學(xué)習(xí)模型來(lái)理解和學(xué)習(xí)源代碼表示的信息是基于學(xué)習(xí)的靜態(tài)分析的關(guān)鍵問(wèn)題。
(4) 漏洞分析方法的普適性:當(dāng)前的研究大多針對(duì)用某一特定類(lèi)型語(yǔ)言(如:C 和Java)編寫(xiě)的軟件程序展開(kāi)。雖然已有的檢測(cè)方法在特定的應(yīng)用場(chǎng)景下表現(xiàn)不錯(cuò),但在對(duì)編程語(yǔ)言的多樣性和迭代更新快等特性的適應(yīng)性問(wèn)題處理上仍然存在不足。因此,改善漏洞分析方法的普適性,提高分析模型的適配能力是當(dāng)前靜態(tài)分析中的關(guān)鍵問(wèn)題。
(5) 數(shù)據(jù)集的匱乏:雖然網(wǎng)絡(luò)上有非常多與軟件漏洞相關(guān)的信息,但是不同于其他領(lǐng)域,能夠用于對(duì)漏洞分析模型進(jìn)行訓(xùn)練和評(píng)估的數(shù)據(jù)集很少;而且正如李韻等在其文章[78]中提到的,存在部分罕見(jiàn)類(lèi)型的漏洞,這類(lèi)漏洞出現(xiàn)的頻率非常低,但其危害性不容忽視;然而由于缺乏合適的數(shù)據(jù)集,導(dǎo)致現(xiàn)有靜態(tài)分析面臨罕見(jiàn)漏洞挖掘困難的問(wèn)題。因此,如何構(gòu)建統(tǒng)一規(guī)范的數(shù)據(jù)集,如何在數(shù)據(jù)稀缺的情況下對(duì)漏洞進(jìn)行有效挖掘是一大難題。
此外,依據(jù)目標(biāo)場(chǎng)景合理地選擇模型在漏報(bào)率和誤報(bào)率上的取向也是關(guān)鍵。無(wú)論是靜態(tài)分析還是動(dòng)態(tài)分析,我們都希望分析模型能夠檢測(cè)出目標(biāo)代碼中存在的所有漏洞,而且沒(méi)有誤報(bào);也就是說(shuō)分析模型既沒(méi)有漏報(bào),也沒(méi)有誤報(bào)。然而,根據(jù)Rice定理[79]和圖靈停機(jī)問(wèn)題[80]可知,這種情況是不存在的。如圖6 所示,粉色部分表示Soundness(可以簡(jiǎn)單理解為沒(méi)有漏報(bào)),藍(lán)色部分表示Completeness(可以簡(jiǎn)單理解為沒(méi)有誤報(bào)),綠色部分表示Truth(表示目標(biāo)程序存在漏洞的真實(shí)情況)。對(duì)于Soundness 而言,包含了目標(biāo)程序存在漏洞的真實(shí)情況,但是也包含了真實(shí)情況之外的結(jié)果,即存在誤報(bào)。對(duì)于Completeness 而言,所包含的結(jié)果都屬于真實(shí)情況,但是沒(méi)有包含全部的真實(shí)情況,即存在漏報(bào)。因此,在設(shè)計(jì)檢測(cè)模型時(shí),不管是基于靜態(tài)分析還是動(dòng)態(tài)分析,都需要根據(jù)具體場(chǎng)景確定模型是傾向于Soundness 還是Completeness,然后再優(yōu)化模型使其靠近Truth。
靜態(tài)分析作為軟件分析領(lǐng)域的關(guān)鍵技術(shù),被廣泛運(yùn)用于對(duì)各類(lèi)軟件的健壯性檢驗(yàn)和安全檢測(cè)中。靜態(tài)分析貫穿整個(gè)軟件的生命周期,能夠有效地幫助軟件開(kāi)發(fā)人員在開(kāi)發(fā)過(guò)程中及時(shí)發(fā)現(xiàn)程序存在的錯(cuò)誤和漏洞,降低軟件上線(xiàn)后被攻擊的風(fēng)險(xiǎn)。本文介紹了源代碼漏洞靜態(tài)分析技術(shù)的核心思想和基本原理,分析和總結(jié)了該領(lǐng)域典型的研究工作,闡述了我們認(rèn)為當(dāng)前靜態(tài)分析中存在的難點(diǎn)。
近年來(lái),機(jī)器學(xué)習(xí)技術(shù)取得了巨大的突破,為靜態(tài)分析注入了新的活力。構(gòu)建自動(dòng)化、智能化的靜態(tài)分析模型勢(shì)必會(huì)成為未來(lái)的發(fā)展趨勢(shì)。在這里我們提供了一些研究思路供同方向的研究人員參考。
(1) 使用直觀(guān)的圖形化結(jié)構(gòu)表示源代碼:使用直觀(guān)的圖形化結(jié)構(gòu)表示源代碼不僅便于人類(lèi)理解源代碼,也能夠幫助機(jī)器學(xué)習(xí)模型更好地挖掘源代碼中的信息。
(2) 合理的代碼嵌入:合理地將源代碼轉(zhuǎn)換為機(jī)器學(xué)習(xí)模型所需的向量表示,同時(shí)盡可能多地包含源代碼的各類(lèi)信息,降低代碼嵌入時(shí)的信息損失,能夠進(jìn)一步提高機(jī)器學(xué)習(xí)模型對(duì)源代碼含義的理解。
(3) 將源代碼的顯式特征和隱式特征相結(jié)合:使用傳統(tǒng)靜態(tài)分析對(duì)源代碼的顯式特征進(jìn)行挖掘,使用機(jī)器學(xué)習(xí)方法對(duì)源代碼圖結(jié)構(gòu)表示中的隱式特征進(jìn)行挖掘,將這兩種特征相結(jié)合,形成互補(bǔ),為源代碼漏洞的發(fā)現(xiàn)和挖掘提供更加有效地支撐。
(4) 合理、適度地使用深度學(xué)習(xí)技術(shù):從傳統(tǒng)機(jī)器學(xué)習(xí)到深度學(xué)習(xí),人工智能領(lǐng)域的發(fā)展取得了巨大的進(jìn)步;深度學(xué)習(xí)技術(shù)在計(jì)算機(jī)各個(gè)領(lǐng)域上的應(yīng)用也隨之越來(lái)越廣泛。雖然深度學(xué)習(xí)技術(shù)在解決某些問(wèn)題上表現(xiàn)出非常不錯(cuò)的性能,但是其對(duì)海量數(shù)據(jù)和計(jì)算機(jī)資源的高度需求也是不容忽視的。對(duì)于基于學(xué)習(xí)的靜態(tài)分析,由于漏洞數(shù)據(jù)集稀缺、數(shù)據(jù)集所包含漏洞樣本的覆蓋面不夠廣,導(dǎo)致訓(xùn)練出來(lái)的深度學(xué)習(xí)模型存在過(guò)擬合問(wèn)題;而且在面對(duì)代碼高速迭代更新的大環(huán)境時(shí),模型的性能往往與實(shí)驗(yàn)結(jié)果相差很大;因此不能盲目地追求使用深度學(xué)習(xí)技術(shù)。
(5) 從待檢測(cè)項(xiàng)目中學(xué)習(xí):“對(duì)于合理規(guī)模的軟件項(xiàng)目,通常包含許多功能相似的代碼片段集群,這些代碼片段集群通常由不同的開(kāi)發(fā)人員貢獻(xiàn),因此它們之間很可能都有相同的bug,所以可以通過(guò)識(shí)別同一代碼庫(kù)中功能相似但不一致的代碼片段來(lái)檢測(cè)bug”,這是文章[81]中提到的一種bug 檢測(cè)思路。文章創(chuàng)新性地提出了一種基于機(jī)器學(xué)習(xí)的bug 檢測(cè)技術(shù),它不需要任何外部代碼或樣本來(lái)進(jìn)行訓(xùn)練,僅通過(guò)對(duì)待檢測(cè)項(xiàng)目中的函數(shù)片段結(jié)構(gòu)進(jìn)行相似性聚類(lèi)實(shí)現(xiàn)檢測(cè)。這為我們提供了靈感。通過(guò)從待檢測(cè)項(xiàng)目中學(xué)習(xí),也許能夠避免第(4)點(diǎn)中提到的由于數(shù)據(jù)集稀缺導(dǎo)致模型過(guò)擬合的問(wèn)題,有助于我們?cè)谡鎸?shí)場(chǎng)景下構(gòu)建高性能的檢測(cè)模型。