您所在的位置: 首頁 >
新聞資訊 >
技術前沿 >
基于圖神經網絡的源碼漏洞檢測方法研究
摘? 要:
針對現(xiàn)有的靜態(tài)代碼分析工具有較高的誤報率與漏報率,提出一種基于切片依賴圖(Slice Dependency Graph,SDG)的自動化漏洞檢測方法,將程序源代碼解析為包含數據依賴和控制依賴信息的切片依賴圖,然后使用圖神經網絡對切片依賴圖的結構進行表征學習,最后使用訓練的神經網絡模型預測待測程序源代碼中的漏洞。在 5 類常見缺陷分類(Common Weakness Enumeration,CWE)樣本構成的數據集上開展了實驗,結果表明誤報率和漏報率均低于作為對比的其他方法,準確率和 F1 得分兩個指標均有提高,因此所提方法能有效提高漏洞檢測能力。
內容目錄:
1 方法介紹
1.1 生成程序依賴圖
1.2 切? 片
1.3 符號化和向量化
1.4 訓練圖神經網絡
2 實驗設計和結果分析
2.1 實驗數據集
2.2 實驗設計與評價指標
2.3 實驗結果分析
3 結 語
導致軟件漏洞的原因有軟件設計錯誤、編碼質量不高、安全測試不充分等。攻擊者可以利用漏洞進行惡意操作,竊取或更改敏感信息,破壞或控制計算機系統(tǒng),對信息安全產生極大的威脅。在提高軟件安全性方面,漏洞檢測是基本手段。傳統(tǒng)的靜態(tài)漏洞檢測方法估計程序運行時的行為而不需要執(zhí)行它,常用于在軟件開發(fā)過程中發(fā)現(xiàn)潛在的漏洞。典型的靜態(tài)分析工具包括 Coverity、FlawFinder、RATS、Fortify 等。這些工具在檢測內存崩潰漏洞方面效果較好,但在檢測大量漏洞方面有所不足。靜態(tài)分析工具往往依賴于基于專家知識人工構造的漏洞模式庫。隨著軟件復雜性持續(xù)增加,人工構造漏洞模式庫的成本越發(fā)高昂,且人的主觀性會影響漏洞檢測的誤報率和漏報率。
軟件的長期運行積累了大量的歷史數據,因此可以利用機器學習方法學習并挖掘與軟件漏洞相關的歷史數據。與靜態(tài)分析檢測漏洞方法相比,基于機器學習的漏洞檢測方法能有效降低漏洞的漏報率。隨著人工智能技術的快速發(fā)展和開源倉庫的發(fā)展,研究者開始使用深度學習技術檢測漏洞。華中科技大學團隊的一系列工作 VulDeePecker、SySeVR、VulDeeLocator等使用雙向長短期記憶 網 絡(Bi-directional Long Short-Term Memory,BiLSTM) 和 雙 向 門 控 循 環(huán) 單 元(Bi-directional Gated Recurrent Unit,BiGRU)模型學習漏洞特征。目前流行的方法是將代碼的各種表示形式如抽象語法樹、程序依賴圖等轉換成一個平鋪的一維序列,然后使用深度學習模型,一般是卷積神經網絡(Convolutional Neural Network,CNN)或循環(huán)神經網絡(Recurrent Neural Network,RNN),來學習代碼的表示。然而,程序中包含復雜的上下文關系,將程序表示成一維序列很難學習程序中的結構和上下文信息。
鑒于已有的基于靜態(tài)分析的漏洞檢測方法存在準確率不高的問題,以及普通 RNN 或 CNN 模型無法學習程序中復雜上下文的缺點,本文提出一種基于切片依賴圖的源碼自動化漏洞檢測方法,使用圖神經網絡(Graph Neural Network,GNN)從切片依賴圖中學習代碼的節(jié)點表示和拓撲結構信息。本文選擇使用基于線性特征調制的圖神經網絡(GraphNeural Networks with Feature-wise Linear Modulation,GNN-FiLM) 結 構 來 學 習 圖 的 特 征, 有 三 點 原因:一是切片依賴圖是一個有向圖,圖中的邊有方向,無向 GNN 模型不能利用切片依賴圖中邊的方向信息;二是切片依賴圖中存在兩種類型的邊,即數據流邊和控制流邊,GNN-FiLM 網絡可以更好地利用切片依賴圖中邊的類型信息;三是 GNN-FiLM網 絡 的 性 能 優(yōu) 于 圖 注 意 力 網 絡(Graph Attention Network,GAT)等網絡模型。
本文首先使用 Joern 工具將源代碼轉換成程序依賴圖;其次通過切片技術獲取漏洞相關的子圖,本文稱之為切片依賴圖;再次使用 GNN-FiLM網絡對切片屬性圖進行表示學習后進行漏洞預測;最后,在軟件保證引用數據集(Software Assurance Reference Dataset,SARD)上做實驗驗證,并比較了 4 種基線方法。實驗結果表明,相較于基線方法,所提方法能進一步提高漏洞檢測能力。
1 方法介紹
本文方法的框架如圖 1 所示。該方法主要包括以下 4 個階段:
(1)提取程序源代碼中的語法和語義信息,解析程序中的數據流和控制流信息,得到程序依賴圖;(2)根據選擇的切點類型將代碼中的相應語句設置為切點,對程序依賴圖做切片,獲取子圖,即切片依賴圖;(3)對切片依賴圖進行嵌入(embedding)操作,生成圖的初始向量表示,作為圖神經網絡的輸入;(4) 使 用 GNN-FiLM 網 絡 學 習 圖 特 征, 在經過卷積和池化進一步提取節(jié)點特征后,聚合所有節(jié)點的特征并輸入到多層感知器(Multi-layer Perceptron,MLP)網絡,經過激活函數分類獲得最終的預測結果,0 表示無漏洞,1 表示有漏洞。
1.1 生成程序依賴圖
本文使用 Joern v0.3.1 工具 生成源代碼的程序依賴圖(Program Dependency Graph,PDG)。生成的程序依賴圖中包含“REACHES”和“CONTROLS”2 種 類 型 的 邊, 以 及 與 這 些 邊 相 連 的 節(jié) 點。“REACHES”類型的邊連接具有數據依賴關系的語句節(jié)點,“CONTROLS”類型的邊表示代碼中的控制依賴關系。
1.2 切? 片
漏洞代碼中通常會有與漏洞無關的語句,因此使用切片技術,盡可能多地去掉與漏洞無關的代碼。切片時需要選擇感興趣的切點,VulDeePecker使用系統(tǒng) API 調用作為興趣點,因為錯誤使用這些API 容易引發(fā)漏洞。SySeVR 除使用系統(tǒng) API 調用作為切點外,還使用了數組使用(array usage)、指 針 使 用(pointer usage)、 算 術 操 作(arithmetic operation)3 種類型的切點作為補充,這 4 種切點類型都涉及常見的安全漏洞。通過分析開源項目中經常出現(xiàn)的安全修復(security patch)類型 ,本文在考慮這 4 種類型切點的基礎上,添加返回語句(return expression)、條件語句(condition expression)作為感興趣的切點類型,增加切片對源代碼的覆蓋。
圖 1 本文方法流程
點類型執(zhí)行不同的切片流程。對所有選擇的切點類型,本文執(zhí)行正常的后向切片,獲取影響切點的所有語句;而針對不同的切點類型,執(zhí)行不同的前向切片方法,具體如下文所述。
(1)針對系統(tǒng) API 調用(其返回值被使用的情況)、數組使用、指針使用、算數操作語句,正常執(zhí)行前向切片,即對該行代碼所有變量做前向切片。(2)返回語句。返回語句已經是程序執(zhí)行流中最后執(zhí)行的語句,與該語句后面剩余的代碼執(zhí)行不存在依賴關系,因此不需要執(zhí)行前向切片。(3)條件語句。條件語句會影響程序的執(zhí)行流。因此針對條件語句,對其中參與條件計算的變量都做后向切片,找出條件語句所有的數據依賴,并對所有被數據依賴的變量都執(zhí)行前向切片,最后將所有結果合并為一個完整的切片依賴圖。(4)返回值未被使用的函數調用語句。對函數的參數采用和條件語句相同的切片方法,從而得到一個更完整的切片依賴圖。
得到程序依賴圖后,本文從程序敏感點出發(fā)做切片生成對應的切片依賴圖(Slice DependencyGraph,SDG),SDG 的節(jié)點可以通過從程序敏感點出發(fā)做前向和后向切片得到。源程序的控制依賴和數據依賴關系都體現(xiàn)在程序依賴圖中,因此將源程序的切片問題轉換成對程序依賴圖的遍歷問題,從本文選擇的程序敏感點所對應的節(jié)點出發(fā)沿著數據依賴邊和控制依賴邊進行圖遍歷,生成切片依賴圖。
本文使用有監(jiān)督方式訓練模型,訓練時對每個測試數據都需要知道它的標簽即漏洞數據或正常數據。訓練數據中,切片依賴圖的標簽依賴于該圖對應的程序敏感點所在行是否是漏洞行。如果原始漏洞代碼數據集中某代碼行被標注為有漏洞,則從該行代碼出發(fā)得到的切片其標簽為“1”,表示有漏洞;否則為“0”,表示沒有漏洞。
1.3 符號化和向量化
對生成的切片依賴圖,首先將代碼 tokens 重命名為統(tǒng)一的形式,將函數名和變量名分別重命名為“FUN_”和“VAR_”的形式,其中下劃線“_”表示數字,從數字 0 開始遞增表示每個切片依賴圖中的函數或變量,降低自定義的函數和變量名稱對訓練 Doc2Vec 模型的影響。
本文使用 Doc2Vec 模型生成切片依賴圖中每個節(jié)點的初始向量。Doc2Vec 模型是一個無監(jiān)督模型,可以將一整句代碼轉換成一個固定長度的向量,是Mikolov 基于 Word2Vec 模型提出的,其具有一些優(yōu)點,比如不用固定句子長度,接受不同長度的句子作訓練樣本等。
1.4 訓練圖神經網絡
本文使用 PyTorch Geometric 框架實現(xiàn)圖神經網絡;使用其中的 Data 數據結構保存向量化后的切片依賴圖,并輸入到圖神經網絡進行學習;使用FiLM 網絡學習切片依賴圖中的信息。
本文的漏洞檢測目標是進行圖級(graph-level)分類,在不同關系下執(zhí)行鄰域聚合過程后,將為每個節(jié)點學習到一組新的 embedding,再進一步經過卷積和池化提取節(jié)點特征,聚合所有節(jié)點特征輸入MLP,經激活函數分類輸出最終預測的標簽,其中,0 為無漏洞,1 為有漏洞。
2 實驗設計和結果分析
本文實驗運行在 Ubuntu 18.04 環(huán)境中。語言環(huán)境為 Python 3.8,深度學習環(huán)境為 PyTorch 1.10.1,CUDA 10.2,Gensim 4.0,PyTorch Geometric 2.0.3。使 用 的 CPU 為 Intel Xeon E52673 v3,GPU 為NVIDIA Tesla K80(12 GB)。
2.1 實驗數據集
本文使用 SARD 數據集 [11] 作為訓練和測試數據集。SARD 數據集包含很多來自真實軟件工程項目的安全漏洞,這些漏洞已經被相關軟件開發(fā)者確認并修復。SARD 數據集中包含了漏洞所在的行信息,適用于本文使用的按照切點代碼行對切片依賴圖打標簽的方法。
綜 合 考 慮 常 見 缺 陷 分 類(Common WeaknessEnumeration,CWE) 2021 top 25 榜單 [12] 中的 CWE類型和 SARD 數據集中各種類型 CWE 的測試樣例數 量, 本 文 選 擇 了 5 種 CWE(CWE-787、CWE-125、CWE-20、CWE-78、CWE-22)完成對比實驗,驗證本文提出方法的有效性。
在對源代碼處理獲得切片依賴圖后,以切點所在的行是否為漏洞行作為打標簽的判定標準。如果切點所在代碼行被 SARD 數據集標為“bad”或者“mixed”,則基于該行得到的切片依賴圖其標簽為“1”,表示該樣本有漏洞;否則標為“0”,表示無漏洞。
因為不同的程序可能有代碼克隆的情況,所以可能會存在切片結果中包含重復的程序依賴圖。這些重復的樣本可能會導致神經網絡過擬合,且有可能讓本文的結果虛高,因為可能出現(xiàn)重復樣本同時出現(xiàn)在訓練集和測試集中的情況。為了保證實驗結果的真實性,本文首先刪除重復的樣本,只保留重復樣本中的一個。本文通過對比節(jié)點以及邊來去重,即節(jié)點和邊都相同的樣本視作重復樣本。同時,SARD 數據集中存在很小一部分的數據誤標情況,導致切片結果中可能出現(xiàn)同時被標記成“0”和“1”的樣本,為了消除數據集標簽錯誤問題對實驗結果的影響,本文直接刪除這些樣本。
通過切片,本文使用的切片數據集統(tǒng)計如表 1所示。
表 1? 切片數據集統(tǒng)計
2.2 實驗設計與評價指標
按照 8 ∶ 1 ∶ 1 的大小將樣本劃分成訓練集、驗證集和測試集。學習率設置為 0.001;dropout 設置為 0.5,防止過擬合;batch size 設置為 128;最大 epoch 次數為 50;patience 設置為 10,即如果連續(xù) 10 次訓練迭代中驗證集上的 F1 分數都沒有增加,則停止訓練過程。選用 Adam 優(yōu)化器和交叉熵損失函數進行有監(jiān)督學習訓練模型。
采 用 誤 報 率(False Positive Rate,F(xiàn)PR)、 漏報率(False Negative Rate,F(xiàn)NR)、準確率(Accuracy,ACC)和 F1 得分 4 個評價指標評價最終模型在測試集上的效果。其中含有漏洞的樣本表示為正類,不含漏洞的樣本表示為負類。準確率表示正確分類的概率,F(xiàn)1 得分是精度和召回率的加權平均值。
2.3 實驗結果分析
為驗證本文方法的有效性,選用 FlawFinder 和RATS 兩 個 靜 態(tài) 分 析 器 和 VulDeePecker 及 SySeVR兩種基于深度學習的漏洞檢測方法,在切片粒度下比較這些工具,如果切片中包含這些工具掃描出存在問題的代碼行,則視為靜態(tài)檢測工具檢測該切片為有漏洞。實驗結果如表 2、表 3、表 4、表 5、表 6 所示。
表 2? FlawFinder 實驗結果
表 3? RATS 實驗結果
表 4? VulDeePecker 實驗結果
表 5? SySeVR 實驗結果
表 6? 本文方法實驗結果
從實驗結果中可以看出,基于深度學習的漏洞檢測方法的效果都明顯好于 RATS 和 Flawfinder 這兩個靜態(tài)分析工具。這兩個靜態(tài)分析工具的誤報率和漏報率較高,主要原因是這兩個工具都是依靠專家定義規(guī)則,根據詞法分析對測試代碼做模式匹配來挖掘漏洞,在搜索潛在漏洞時沒有使用相關控制流和數據流信息。而真實世界的漏洞邏輯通常比這些規(guī)則要復雜得多,這一點極大地限制了這些檢測工具。而本文方法由于能自動學習漏洞特征,所以無須安全專家制定規(guī)則,并且取得了不錯的效果。
本 文 方 法 的 誤 報 率 和 漏 報 率 均 低 于 VulDee Pecker 和 SySeVR,同時準確率和 F1 分數持平或優(yōu)于這兩種基于深度學習的方法。雖然 VulDeePecker和 SySeVR 使用了程序切片來定位漏洞,考慮了數據流和控制流信息,但都是使用 token 序列的方式表征源代碼,將代碼當作文本來處理,沒有直接體現(xiàn)出程序中的數據流和控制流信息,而且它們對嵌入向量進行了截斷,丟失了一些關鍵的代碼信息。
本文使用圖數據結構表示程序中的數據依賴和控制依賴關系,使用圖神經網絡學習區(qū)分漏洞代碼和非漏洞代碼,提高了自動檢測能力。圖神經網絡模型的性能和網絡結構與超參數有關,訓練模型是一個經驗性的任務,需要進一步優(yōu)化,以改善模型的泛化能力。同時圖神經網絡的可解釋性問題需要進一步研究。
3 結 語
為了檢測源代碼中的漏洞,本文提出一種基于切片依賴圖的漏洞檢測方法。該方法通過將程序源代碼轉換成保留數據依賴和控制依賴的切片依賴圖,對節(jié)點和邊進行編碼后,使用圖神經網絡對圖結構進行表示學習,最后使用圖神經網絡進行漏洞預測。在 SARD 漏洞數據集上進行了測試驗證,并與 4 種漏洞檢測方法進行了實驗對比。實驗結果體現(xiàn)了本文所提方法在源代碼漏洞檢測方面的有效性。未來將研究構建更高質量的漏洞數據集用于模型訓練,以及構建更有效的學習模型,預測更豐富的輔助信息,如漏洞定位等。
引用格式:宋子韜 , 胡勇 . 基于圖神經網絡的源碼漏洞檢測方法研究 [J]. 通信技術 ,2022,55(5):640-645.
作者簡介 >>>
宋子韜,男,碩士研究生,主要研究方向為漏洞挖掘;
胡? 勇,男,博士,研究員,主要研究方向為信息系統(tǒng)安全、網絡內容安全、物聯(lián)網安全。
選自《通信技術》2022年第5期(為便于排版,已省去參考文獻)
來源:信息安全與通信保密雜志社