A Deep Learning-Based System for Vulnerability Detection


本篇文獻作者提出了一種基於深度學習來檢測軟件漏洞的方案

      摘要:作者開始基於深度學習的漏洞檢測研究,是為了減輕專家手工定義特性的繁瑣任務,需要制定一些指導性原則來適用於深度學習去進行漏洞探測。出於這個目的,作者用代碼 gadgets 來代表程序,然后把它們轉化為向量,其中代碼gadget是一些彼此語義相關的代碼行。基於這設計了評估系統VulDeePecker,作者為深度學習方法提供了最初始的漏洞數據集,實驗結果表明:與其他方法相比,系統能夠實現更少的誤報,將系統用於Xen,Seamonkey和Libav這3個軟件產品檢測到了4個未報告的漏洞。

  現有的漏洞檢測的解決方案有兩個主要缺陷:強制執行繁重的體力勞動和導致較高的誤報率。在本文中作者針對以下漏洞檢測提出了一個解決方案,同時考慮到這些局限性:給定目標程序的源代碼,如何確定目標程序是否脆弱,如果是,漏洞在哪里。

  基於以上,作者做了三部分工作:(1)開始利用深度學習進行漏洞檢測的研究。這種方法具有很大的潛力,因為深度學習不需要人工定義特性,這意味着漏洞的檢測可以自動化。當然深度學習的有一些指導性的初步原則,包括使深度學習應用於漏洞檢測的軟件程序的表示,基於深度學習的漏洞檢測的粒度的確定以及漏洞檢測的特定神經網絡的選擇。建議使用代碼小部件來表示程序,代碼小部件是一些(不一定是連續的)代碼行,它們在語義上相互關聯,可以向量化為深度學習的輸入。(2)介紹了一種基於深度學習的漏洞檢測系統的設計與實現,該系統被稱為漏洞深度學習識別系統(VulDeePecker).有效性體現在能識別多種類型的漏洞,這就解釋了VulDeePecker使用漏洞模式(作為深度神經網絡學習)來檢測漏洞。(3)提供了第一個用於評估VulDeePecker和其他基於深度學習的漏洞檢測系統的數據集,該數據集來自美國國家標准與技術研究所(NIST)維護的兩個數據源NVD[10]和軟件保證參考數據集(SARD)項目[12]。數據集包含61638個代碼小部件,包括17725個易受攻擊的代碼小部件和43913個不易受攻擊的代碼小部件。在17725個易受攻擊的代碼小部件中,10440個代碼小部件對應於緩沖區錯誤漏洞(CWE-119),其余7285個代碼小部件對應於資源管理錯誤漏洞(CWE-399),作者已經在https://github.com/CGCL-codes/VulDeePecker上提供了數據集。

  接下來主要研究基於深度學習的漏洞檢測的一些初步指導原則和VulDeePecker的設計

一.深度學習檢測漏洞的初步原則,其核心是回答三個問題(1)如何表示基於深度學習的漏洞檢測程序?(2)深度學習漏洞檢測的適當粒度是多少?(3)如何選擇特定的神經網絡進行漏洞檢測?

如何表示軟件程序?

  由於深度學習或神經網絡以向量作為輸入,需要將程序表示為具有語義意義的向量,即需要將程序編碼成向量,這些向量是深度學習所需要的輸入。指導原則1.程序可以首先轉換成某種中間表示,稱為代碼gadget。術語“代碼小部件”的靈感來自代碼重用攻擊上下文中的術語"小部件"[18],代碼小部件是少量(不一定是連續的)代碼行。

什么是適當的粒度?

  由於不僅需要檢測程序是否易受攻擊,而且還需要確定漏洞的位置,因此需要更細的粒度來進行基於深度學習的漏洞檢測。這意味着漏洞檢測不應該在程序或函數級別進行,這是非常粗粒度的,因為程序或函數可能有很多行代碼,確定其漏洞位置本身就是一項困難的任務。指導原則2.為了幫助Pin定位漏洞位置,程序應該被表示為更細的粒度,而不是函數或者程序級別的。代碼小部件適用於指導原則2。

如何選擇神經網絡?

  神經網絡在圖像處理,語音識別,自然語言處理([21][30][40])等不同於漏洞檢測的領域非常成功。這意味着許多神經網絡可能不適合漏洞檢測,需要一些原則來指導選擇適合漏洞檢測的神經網絡。指導原則3.因為一行代碼是否包含漏洞可能取決於上下文,能夠處理上下文的神經網絡可能適用於漏洞檢測。這一原理表明,用於自然語言處理的神經網絡可能適用於漏洞檢測,因為上下文在自然語言處理[33]中很重要。將上下文的概念引入到本文的設置中,觀察到程序函數調用的參數經常是受到程序中較早操作的影響,也可能受到程序中較晚操作的影響。

  由於自然語言處理有許多神經網絡,首先從遞歸神經網絡(RNNs)[51][53]開始,這些神經網絡在處理順序數據方面是有效的,並且確實被用於程序分析(但不是漏洞檢測的目的)[20][48][56][57].然而RNNs存在消失梯度(VG)問題,導致模型訓練[16]失效。注意,VG問題是由RNNs的雙向變體(BRNNs[47])繼承的。

  VG問題可以通過將記憶細胞植入RNNs來解決,包括長期記憶(LSTM)細胞和門控循環單元(GRU)細胞[17][22]。由於GRU在語言建模[27]上沒有超過LSTM,所以作者選擇LSTM進行漏洞檢測。由於程序函數調用的參數可能受到程序中較早的語句影響,也有可能受到較晚的語句影響,這說明單向LSTM可能還不夠,應該使用雙向LSTM(BLSTM)進行漏洞檢測。BLSTM神經網絡圖如下:

有多個BLSTM層,一個Dense層和一個Softmax層。學習過程的輸入是一個確定的表示向量,BLSTM層有兩個方向,向前和向后。Dense層減少了從BLSTM層接收到的向量維數,Softmax層以Dense層接收到的低維向量作為輸入,負責表示和格式化結果,為學習階段更新神經網絡參數提供反饋。學習階段的輸出是一個調好模型參數的BLSTM神經網絡,檢測階段的輸出就是分類結果。

 二.VulDeePecker的設計

 A.定義代碼小部件

  為了用適合神經網絡輸入的向量表示程序,提出了將程序轉換為代碼小部件的表示,其定義如下:代碼小部件是由許多程序語句組成的(例如,這些代碼行),它們在數據依賴關系或控制關系方面在語義上彼此相關。為了生成代碼小部件,提出了從關鍵點的啟發式概念,來從特定的角度表示程序。關鍵點在緩沖區溢出漏洞中可以是:庫/API函數調用,數組和指針。本文中,將重點討論如何使用庫/API函數調用的特定關鍵點來證明它在基於深度學習的漏洞檢測中的有效性。

  與庫/API函數調用相同的關鍵點對應,代碼小部件可以通過數據流或者程序控制流分析的方式生成,其中著名的[23]算法,[50]算法和Checkmax[2]等易於使用的商業產品。

 B.VulDeePecker的概述

  系統有兩個階段:學習訓練階段和檢測階段。學習階段的輸入是帶有脆弱和不脆弱的大量訓練項目,所謂脆弱指的是包含已知的漏洞。學習階段的輸出為被編碼成BLSTM神經網絡的漏洞模式。

  學習階段有4個步驟:

Step 1:提取庫/API函數調用和相關的的程序片段

1.1從訓練程序中庫/API函數的調用,同時注意VulDeePecker有關庫/API函數調用的關鍵點。

1.2為在步驟1.1中提取的庫/API函數調用的每個參數(或者變量)提取一個或多個程序片段。

Step 2:生成訓練程序的代碼小部件及其標定好的真實數據

2.1將步驟2.2中獲得的程序片段組裝為代碼小片段,每一個庫/API函數調用對應一個代碼小部件。代碼小部件不一定對應某些連續的代碼行,相反,它是由多行語義相關的代碼組成。

2.2對代碼小部件標記真實數據。這個步驟將每個代碼小部件標記為1(或0不是脆弱的),代碼小部件的真實數據標簽是可用的,因為我們知道訓練程序是否脆弱,如果脆弱,我們就知道了脆弱的位置。

Step 3:將代碼小部件轉換為向量表示

3.1將代碼小部件轉換為特定的符號表示,稍后將對此進行詳細說明。這個步驟的目的在於保存一些訓練程序的語義信息。

3.2對3.1步驟中的符號表示的代碼小部件進行編碼為向量,這向量作為訓練BLSTM神經網絡的輸入。

Step 4:訓練BLSTM神經網絡

4.1將編碼小部件編碼成向量並獲得其標定好的真實數據后,這種訓練過程對於學習BLSTM神經網絡是標准的。

  檢測階段是給定一個或者多個目標程序,從它們中提取庫/API函數調用以及相應的程序片段,這些程序片段組裝成代碼小部件。這些代碼小部件被轉化成符號表示,然后編碼成向量作為訓練后的BLSTM神經網絡的輸入。網絡輸出哪些向量,因此哪些代碼小部件是脆弱的("1")或者是不脆弱的("0"),如果一個代碼小部件很脆弱,它會確定目標程序中漏洞的位置。如圖所示:

  檢測階段有2個步驟:

Step 5:將目標程序轉換為代碼小部件和向量

5.1從目標程序提取庫/API函數調用(類似步驟1.1)

5.2根據庫/API函數調用的參數提取程序片段(類似步驟1.2)

5.3將程序片段組成為代碼小部件(類似步驟2.1)

5.4將代碼小部件轉換為它們的符號表示(類似步驟3.1)

5.5將代碼小部件的符號表示編碼為向量(類似步驟3.2)

Step 6:檢測。這個使用學習到的BLSTM神經網絡對從目標程序中提取的代碼小部件相關的向量進行分類。當這個向量被分類為“1”,意味着相關的代碼小部件是脆弱的,並且確定了漏洞的位置。否則隊對應的相關代碼小部件不是脆弱的("0")。

 

具體每個步驟的實現,由於時間和篇幅關系,下一節進行探討。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM