趙墨刊,李冬輝
(天津大學(xué) 電氣自動(dòng)化與信息工程學(xué)院,天津 300072)
軟件源代碼漏洞檢測(cè)始終是軟件安全領(lǐng)域的一個(gè)重要問題。目前,越來越多的項(xiàng)目使得軟件更加復(fù)雜和多樣化,從而導(dǎo)致很難管理。在一個(gè)巨大的軟件系統(tǒng)中,任何微小的漏洞都可能導(dǎo)致整個(gè)系統(tǒng)崩潰。盡管漏洞的危害性是眾所周知的,但要開發(fā)沒有漏洞的完美軟件是不可能的,軟件源代碼出現(xiàn)漏洞不可避免。因此,源代碼漏洞檢測(cè)在軟件開發(fā)和維護(hù)中起著不可或缺的作用。
在軟件安全領(lǐng)域,如何發(fā)現(xiàn)和減少軟件源代碼漏洞已經(jīng)成為一個(gè)根本性的問題,研究人員提出了各種各樣的方法來檢測(cè)軟件中潛在的漏洞問題。依據(jù)在檢測(cè)時(shí)程序是否正在運(yùn)行,漏洞檢測(cè)可分為靜態(tài)分析和動(dòng)態(tài)分析。靜態(tài)分析工具已被證明在特定的應(yīng)用領(lǐng)域非常有效,如嵌入式系統(tǒng)或航空應(yīng)用。然而,使用這些傳統(tǒng)的軟件技術(shù)往往非常費(fèi)時(shí)費(fèi)力。一些輕量級(jí)的靜態(tài)分析工具可以應(yīng)用到惡意代碼漏洞檢測(cè)中,但這些方法通常會(huì)導(dǎo)致某種特定的代碼漏洞誤報(bào)的可能性非常高。軟件程序員通常使用靜態(tài)分析技術(shù)并結(jié)合其他工具進(jìn)行信息預(yù)處理,如利用Concolic完成漏洞分析。在之前的研究中也對(duì)Android惡意軟件檢測(cè)進(jìn)行了靜態(tài)分析,F(xiàn)uzzing技術(shù)這樣的動(dòng)態(tài)分析方法被認(rèn)為是識(shí)別大型軟件漏洞的有效方法。然而,目前的分析工具僅限于檢測(cè)已公開的漏洞,漏洞的普遍發(fā)現(xiàn)仍然基于繁瑣的手工審計(jì),這需要大量的專業(yè)知識(shí)和資源。
隨著人工智能的發(fā)展,機(jī)器學(xué)習(xí)方法被廣泛地應(yīng)用于軟件源代碼漏洞檢測(cè)中,并且在軟件安全中扮演著重要的角色。深度學(xué)習(xí)技術(shù)為軟件源代碼漏洞檢測(cè)領(lǐng)域提供了新的潛力。一方面,深度學(xué)習(xí)模型的分層結(jié)構(gòu)有助于學(xué)習(xí)抽象和高度非線性的特征,能夠捕捉復(fù)雜數(shù)據(jù)的內(nèi)在結(jié)構(gòu);另一方面,深度學(xué)習(xí)模型允許對(duì)特征進(jìn)行自動(dòng)提取,具有多級(jí)抽象,并可能具有更高的通用性,從而將專家從勞動(dòng)密集型且可能容易出錯(cuò)的特征工程任務(wù)中解放出來。此外,深度學(xué)習(xí)方法能夠發(fā)現(xiàn)專家可能從未考慮的潛在特征,這大大擴(kuò)展了特征搜索空間。通過引入記憶單元,循環(huán)神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network,RNN)具備了一定的記憶性,能夠進(jìn)行代碼語義推理,但RNN存在梯度消失或爆炸的缺點(diǎn),GRU解決了這個(gè)問題。相比于RNN,GRU具有更強(qiáng)大的對(duì)軟件源代碼特征分析進(jìn)行處理的能力,僅通過學(xué)習(xí)復(fù)雜的模型和挖掘軟件源代碼語義的代碼的高級(jí)表示,就能實(shí)現(xiàn)對(duì)軟件源代碼潛在漏洞的識(shí)別。
本文主要針對(duì)軟件源代碼漏洞檢測(cè)誤報(bào)率和漏報(bào)率高的問題,提出一種基于雙向門控遞歸單元(Bidirectional Gated Recurrent Unit,BGRU)的軟件源代碼漏洞檢測(cè)方法,將軟件源代碼漏洞視為多分類問題,不同類型的漏洞對(duì)應(yīng)不同的標(biāo)簽。
通過采用基于Token的方法和Word2vec模型將軟件源代碼轉(zhuǎn)換為分布式向量并輸入到BGRU神經(jīng)網(wǎng)絡(luò)中,利用BGRU自動(dòng)從正反兩個(gè)方向生成深層次的高維特征表示,這樣可以有效學(xué)習(xí)軟件源代碼的規(guī)律和特性,以此來降低軟件源代碼漏洞檢測(cè)的誤報(bào)率和漏報(bào)率。
本文采用基于Token的表征方法。該方法是通過對(duì)軟件源代碼進(jìn)行詞法分析得到的,即在編譯過程中,創(chuàng)建一個(gè)自定義的C++/C#詞法分析器來構(gòu)建通用、簡(jiǎn)單的函數(shù)表示對(duì)軟件源代碼的字符流進(jìn)行掃描;然后根據(jù)程序語言的詞法規(guī)則,標(biāo)記軟件源代碼的標(biāo)識(shí)符、運(yùn)算符、函數(shù)名和關(guān)鍵字等重要信息,從而將軟件源代碼的字符流轉(zhuǎn)換為等價(jià)的Token序列;最后將Token序列按照類似于二進(jìn)制的形式表征為one?hot向量。
本文采用Word2vec向量轉(zhuǎn)換模型,該模型是自然語言處理領(lǐng)域的一種單詞轉(zhuǎn)換為向量的表示方法,在自然語言處理領(lǐng)域,單詞需要被向量化或數(shù)字化后才能被相關(guān)的算法或者模型進(jìn)行學(xué)習(xí)或利用。Word2vec模型的連續(xù)詞匯模型(Continuous Bag of Word Model,CBOW)結(jié)構(gòu)如圖1所示。
圖1 Word2vec模型的CBOW結(jié)構(gòu)
Word2vec模型是包含輸入層、隱含層和輸出層三層結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò)。輸入層中的s∈R是每個(gè)詞的one?hot向量表示,向量經(jīng)過輸入層到隱藏層的權(quán)重矩陣計(jì)算后得到一個(gè)中間層向量,用公式表示為:
式中:為輸入向量的個(gè)數(shù);∈R與∈R為權(quán)重矩陣。輸出層輸出公式為:
該神經(jīng)網(wǎng)絡(luò)的優(yōu)化函數(shù)為:
式中是損失函數(shù),用于計(jì)算s,x的偏離程度。
GRU網(wǎng)絡(luò)包括更新門和重置門兩個(gè)門結(jié)構(gòu),更新門決定哪些重要?dú)v史信息需要被保留下來,重置門決定哪些不重要的歷史信息需要被忘記。GRU具有長(zhǎng)短期記憶功能,能夠?qū)崿F(xiàn)對(duì)長(zhǎng)期語境等關(guān)系進(jìn)行建模。GRU網(wǎng)絡(luò)公式為:
式中:x為當(dāng)前輸入軟件源代碼向量;h和h表示隱藏層的狀態(tài)記憶變量;r,z分別為重置門狀態(tài)、更新門狀態(tài);?表示候選集狀態(tài),y的輸出狀態(tài);W,W,W表示可訓(xùn)練權(quán)重參數(shù)矩陣;表示單位矩陣;“·”表示矩陣點(diǎn)乘;[]表示向量連接;“×”表示矩陣乘積;表示sigmoid激活函數(shù)。
GRU基本結(jié)構(gòu)如圖2所示。
圖2 GRU隱含層結(jié)構(gòu)
sigmoid與tanh的表達(dá)式分別為:
傳統(tǒng)GRU神經(jīng)網(wǎng)絡(luò)所存在的一點(diǎn)缺陷是其僅能從單一方向讀取輸入的軟件源代碼信息。然而實(shí)際情況需要充分考慮前后軟件源代碼的特征表示,即正反兩方向的軟件源代碼特征均需要被考慮在內(nèi)。為了克服常規(guī)GRU神經(jīng)網(wǎng)絡(luò)的局限性,本文采用BGRU神經(jīng)網(wǎng)絡(luò)分別從正、反兩個(gè)不同的方向來捕獲輸入軟件源代碼向量的特征。
BGRU結(jié)構(gòu)原理圖如圖3所示。
圖3 BGRU結(jié)構(gòu)原理圖
在BGRU神經(jīng)網(wǎng)絡(luò)的前向?qū)又?,GRU的?按照正向順序依次讀取輸入的向量(從到x),并計(jì)算對(duì)應(yīng)于每個(gè)向量的前向隱藏層狀態(tài),即(?,…,?,…,?)。類似地,在BGRU神經(jīng)網(wǎng)絡(luò)的反向?qū)又校珿RU的?按照倒序的方式依次讀取輸入向量(從x到),并計(jì)算對(duì)應(yīng)于每個(gè)向量的反向隱藏層狀態(tài),即(?,…,?,…,?)。通過參考式(7)和式(8)提供的隱藏層狀態(tài)計(jì)算過程,第個(gè)輸入向量的前向、反向隱藏層狀態(tài)可具體表示為:
隨后,將BGRU的前向、反向隱藏層狀態(tài)級(jí)聯(lián)在一起,構(gòu)成BGRU的隱藏層狀態(tài)h,即:
由于軟件源代碼無法直接輸入到BGRU網(wǎng)絡(luò)實(shí)現(xiàn)軟件源代碼的漏洞檢測(cè),所以本文首先利用基于Token的表征方法將軟件源代碼按順序表征為one?hot形式的向量。one?hot形式的軟件源代碼表征向量具有如下弊端:
1)稀疏性強(qiáng),當(dāng)維度過多時(shí),one?hot形式向量具有非常多的0,使得整個(gè)向量中有用的信息過少,造成計(jì)算機(jī)幾乎無法計(jì)算的后果。
2)不能刻畫相關(guān)軟件源代碼背后的語義。Word2vec算法是使用三層結(jié)構(gòu)的神經(jīng)網(wǎng)絡(luò)將one?hot形式的軟件源代碼表征向量變換為分布式的表征向量,又能把相關(guān)軟件源代碼之間背后的語義用作模型的特征。因此,本文利用Word2vec使one?hot形式的向量轉(zhuǎn)化為分布式向量以便深度學(xué)習(xí)網(wǎng)絡(luò)自動(dòng)挖掘和提取特征。
BGRU層:將經(jīng)Word2vec輸出的分布式向量作為BGRU的輸入,利用BGRU神經(jīng)網(wǎng)絡(luò)來分別從正、反兩個(gè)不同的方向捕獲輸入分布式向量的特征。
輸出層:輸出層的輸入為BGRU層的輸出h,輸出通過全連接層和softmax計(jì)算輸出的概率值。softmax公式為:
式中:y表示全連接層第個(gè)節(jié)點(diǎn)的輸出值;為輸出節(jié)點(diǎn)個(gè)數(shù);(y)表示第個(gè)元素表示屬于第個(gè)類別的概率值,1≤≤。
圖4所示為白酒質(zhì)量監(jiān)控系統(tǒng)的架構(gòu)圖,其包含6大功能模塊。本系統(tǒng)是基于Microsoft的NET架構(gòu)開發(fā)實(shí)現(xiàn)的,軟件源代碼是由C#語言編寫的,數(shù)據(jù)庫軟件為MySQL?8.0.23。
圖4 白酒質(zhì)量監(jiān)控系統(tǒng)架構(gòu)圖
軟件源代碼漏洞檢測(cè)流程如圖5所示。
圖5 漏洞檢測(cè)流程
軟件源代碼漏洞檢測(cè)具體步驟如下:
1)本文樣本來源于白酒質(zhì)量監(jiān)控系統(tǒng)軟件,選取70%和30%的樣本分別作為訓(xùn)練樣本和測(cè)試樣本,針對(duì)10種開放式Web應(yīng)用程序安全項(xiàng)目(Open Web Application Security Project,OWASP)(2017年)漏洞進(jìn)行檢測(cè)。
表1為10種OWASP漏洞的名稱以及對(duì)應(yīng)的英文全稱和英文縮寫。
表1 10種OWASP漏洞的名稱以及對(duì)應(yīng)的英文全稱和英文縮寫
2)設(shè)置主要參數(shù)的初始值。本實(shí)驗(yàn)采取手動(dòng)遍歷的方式進(jìn)行參數(shù)選取,選取的參數(shù)為:BGRU的輸入向量維數(shù)為20,輸入向量個(gè)數(shù)為20,學(xué)習(xí)率設(shè)為0.001,batch大小設(shè)為64。
3)將訓(xùn)練樣本利用基于Token的方法和Word2vec神經(jīng)網(wǎng)絡(luò)轉(zhuǎn)換為分布式向量后輸入到模型中進(jìn)行模型訓(xùn)練。選用交叉熵?fù)p失函數(shù)和自適應(yīng)矩估計(jì)算法進(jìn)行反向傳播,優(yōu)化權(quán)重和偏置項(xiàng)。損失函數(shù)表達(dá)式為:
4)當(dāng)>,終止訓(xùn)練并保存模型;否則返回步驟3)。其中=5,表示當(dāng)前輸出準(zhǔn)確率連續(xù)高于歷史輸出最高準(zhǔn)確率的次數(shù)。
5)采用與步驟3)訓(xùn)練樣本相同的處理方法將測(cè)試樣本轉(zhuǎn)換為分布式向量后,輸入到訓(xùn)練好的模型中進(jìn)行源代碼故障檢測(cè)。
本實(shí)驗(yàn)將測(cè)試集樣本輸入到訓(xùn)練好的模型中測(cè)試模型性能,并且將雙向循環(huán)神經(jīng)網(wǎng)絡(luò)(Bidirectional Recurrent Neural Network,BRNN)、卷 積 神 經(jīng) 網(wǎng) 絡(luò)(Convolutional Neural Network,CNN)與本文所提方法進(jìn)行對(duì)比。兩種方法的設(shè)置參數(shù)如下:BRNN方法與BGRU方法所選參數(shù)相同,CNN采用3層卷積?池化網(wǎng)絡(luò);輸入維度為20×20,三層卷積核和三層池化核尺寸大小分別設(shè)為3×3和2×2;三層卷積核的數(shù)量分別為64,128,128;卷積步長(zhǎng)和池化步長(zhǎng)分別設(shè)為1,其他參數(shù)與BGRU所提方法所選參數(shù)相同。本文將軟件源代碼漏洞視為陽性,無漏洞為陰性,誤報(bào)率為無漏洞的軟件源代碼樣本中被檢測(cè)為漏洞的軟件源代碼樣本所占的比例,漏報(bào)率為在有漏洞軟件源代碼樣本中被檢測(cè)為無漏洞軟件源代碼樣本所占的比例。三種方法針對(duì)OWASP檢測(cè)的實(shí)驗(yàn)結(jié)果如圖6和圖7所示。
圖6 三種方法對(duì)于OWASP的漏洞檢測(cè)誤報(bào)率對(duì)比
圖7 三種方法對(duì)于OWASP的漏洞檢測(cè)漏報(bào)率對(duì)比
由圖6和圖7可知,BGRU方法對(duì)于不同類型的漏洞具有不同的漏洞檢測(cè)誤報(bào)率和漏洞檢測(cè)漏報(bào)率,整體上能夠保持較低的誤報(bào)率和漏報(bào)率。對(duì)于BA、SDE和XSS,采用BRNN方法的漏洞誤報(bào)率均超過15%;對(duì)于I、XSS和UKVC,采用CNN方法的誤報(bào)率也均超過15%;對(duì)于XEE、BAC、SM、XSS和ID,采用BRNN方法的漏洞漏報(bào)率均在8%以上;對(duì)于BA、XEE、BAC、ID和UKVC,采用CNN方法的漏報(bào)率也均在12%以上。
由此得出,在其他兩種方法檢測(cè)軟件源代碼漏洞出現(xiàn)了很大的誤報(bào)率或漏報(bào)率時(shí),BGRU方法依然具有較低的漏洞檢測(cè)誤報(bào)率和漏報(bào)率,驗(yàn)證了文中方法具有非常好的檢測(cè)效果。本文給出了采用BGRU方法識(shí)別XEE漏洞的截圖,如圖8所示,標(biāo)記為黑色部分為漏洞追蹤到軟件源代碼的位置。
圖8 采用BGRU方法檢測(cè)XEE漏洞所追蹤到軟件源代碼的位置
針對(duì)軟件源代碼漏洞檢測(cè)誤報(bào)率和漏報(bào)率高的問題,本文提出一種BGRU深度學(xué)習(xí)方法,用于降低白酒質(zhì)量監(jiān)控系統(tǒng)軟件源代碼漏洞檢測(cè)誤報(bào)率和漏報(bào)率。本文采用基于Token的方法和Word2vec模型將軟件源代碼轉(zhuǎn)換為分布式向量并輸入到BGRU神經(jīng)網(wǎng)絡(luò),以實(shí)現(xiàn)對(duì)軟件源代碼規(guī)律和特性的有效學(xué)習(xí)。實(shí)驗(yàn)結(jié)果表明:BGRU方法對(duì)于OWASP(2017年)不同類型的漏洞具有不同的漏洞檢測(cè)誤報(bào)率和漏報(bào)率,整體上能夠保持較低的誤報(bào)率和漏報(bào)率;在其他兩種方法檢測(cè)軟件源代碼漏洞出現(xiàn)了很大的誤報(bào)率或漏報(bào)率時(shí),BGRU方法依然具有較低的漏洞檢測(cè)誤報(bào)率和漏報(bào)率。綜上,本文提出的BGRU檢測(cè)方法能夠有效降低軟件源代碼漏洞檢測(cè)誤報(bào)率和漏報(bào)率。