王 劍,黃愷杰,張夢杰,劉星彤,楊 剛
(國防科技大學 電子科學學院, 湖南 長沙 410073)
數據執行保護(data execution prevention,DEP)、地址空間布局隨機化(address space layout randomization,ASLR)等內存防護機制的普遍應用,使得傳統的代碼注入攻擊難以奏效。Shacham[1]提出了面向返回編程(return oriented programming,ROP)的概念,打破了傳統注入攻擊需要注入外部可執行代碼的局限,通過選取并拼接目標系統軟件內存空間中的已有代碼片段(稱之為Gadget)來實現惡意功能。Gadget是目標程序內存空間已存在的以跳轉指令為結尾的代碼片段,可以實現內存讀寫、數據處理、系統調用和函數調用等功能。Gadget是構成ROP鏈的基本單元,ROP鏈通過拼接多個Gadget,完成惡意攻擊過程中的特定操作。由于ROP鏈中沒有顯性表示的惡意代碼,因此可以突破DEP的防護。ROP鏈在實際漏洞攻擊中通常作為攻擊代碼的重要組成部分,如在針對CVE-2014-0322、CVE-2016-10190、2021-22555、CVE-2022-0995等漏洞攻擊的代碼中均包含了ROP鏈[2]。
ROP鏈的檢測分為動態檢測與靜態檢測:
動態檢測通過建立蜜罐、沙箱等目標環境,對外部輸入數據進行動態執行監控,獲取其動態特征,如寄存器或內存狀態、指令執行狀態、控制流完整性等,采用行為規則匹配、執行特性統計分析、內存狀態推演等方法實現對ROP的檢測。DROP 基于動態二進制插樁對代碼指令的執行情況進行監控,通過檢查“ret”指令間隔的指令數,判斷是否存在ROP惡意代碼片段[3]。蔣廉[4]使用基于內核的虛擬機(kernel-based virtual machine,KVM),利用動態插樁,結合軟硬件分層過濾,嵌套檢測ROP攻擊。SCRAP在DROP的基礎上根據指令指針的跳轉行為定義攻擊行為簽名,利用簽名匹配檢測ROP攻擊[5]。Ropecker基于硬件輔助的最近分支記錄,通過識別間接分支跳轉的頻率實現對ROP攻擊的判定[6]。ROPdefender通過識別軟件控制流是否出現異常來檢測ROP攻擊[7]。CFIMon利用硬件輔助的方法監控CPU指令執行,檢測破壞控制流完整性的異常跳轉事件[8]。ROPDetector[9]和MIBChecker[10]利用硬件性能管理單元的事件觸發機制,針對預測失敗的分支進行實時ROP檢測。ROPStop通過對間接分支跳轉事件的統計分析,有效地捕獲控制流異常事件,進而識別ROP攻擊[11]。ROPscan推測性地驅動目標進程地址空間中已經存在的代碼的執行,并在運行時檢測ROP代碼的執行[12]。動態檢測方法能夠得到較為可靠的檢測結果,但其需要構建目標軟件動態環境并監控執行樣本的動態特征,存在環境構建困難、算法開銷大、應用部署復雜等缺點。
靜態檢測根據ROP在數據層面上的取值范圍和具體數值的排布順序,基于特征碼匹配、字節流統計分析、模擬執行推演等方法直接分析流量數據以實現對ROP攻擊的檢測。EavesROP利用滑動窗口篩選潛在的可疑數據段,并使用快速傅里葉變換匹配濾波的方式對網絡流量中的疑似地址值與已知庫文件中的Gadget地址值進行匹配,以發現ROP攻擊[13]。Strop根據Gadget地址的統計特征,如靜態地址數量、靜態地址距離、相同地址數量、地址范圍等,實現對ROP鏈的檢測[14]。DeepReturn采用反匯編的方法分析可疑ROP攻擊鏈,并將其編碼輸入到卷積神經網絡中進行分類檢測[15]。ROPminer通過在目標代碼段和動態鏈接庫中收集可能的Gadget,學習ROP組件的字節取值特性和組件次序,并運用隱性馬爾可夫模型實現對輸入數據流的檢測[16]。Code-Stop通過模擬執行數據中的可疑Gadget地址,對比其語義是否類似調用Windows特定函數時對寄存器的賦值模式,從而判斷是否存在ROP攻擊[17]。靜態檢測方法較之動態檢測方法具有開銷小、架構簡單、部署方便等優點,但是當前的靜態檢測方法一方面依賴程序內存地址的上下文信息,包括特殊的函數調用地址信息或是受保護進程的內存地址信息,方法的泛用性較差;另一方面存在檢測效率低、真實ROP攻擊檢測性能差等問題。
本文提出一種基于字節模式二維特征的ROP鏈檢測方法。該方法基于ROP鏈的字節波動特征,通過序列抽取、滑動分組、數值量化,將輸入的一維流量數據轉換為二維特征向量,保留了更多的數據信息,并采用卷積神經網絡實現對ROP鏈的檢測。該方法解決了現有方法地址內存信息依賴的問題,無須考慮目標系統環境,包括操作系統版本、目標軟件版本,且具有較高的檢測準確率、較低的時間開銷和系統開銷。
本文提出的模型適用于32位和64位操作系統。為便于理解,下面以4 B地址空間的32位操作系統為例進行闡述。檢測模型的總體方案如圖1所示,包含數據準備、數據預處理、模型訓練和模型檢測四個部分。數據準備主要是建立ROP流量數據集和非ROP流量數據集;數據預處理部分將流量數據包的有效載荷轉換為類灰度圖像的二維數值矩陣;模型訓練部分將經過預處理后的數值矩陣輸入到神經網絡模型中進行訓練;模型檢測部分將測試數據預處理后輸入到測試模型中,從而得到所屬類別。神經網絡模型相較于傳統數學模型以及機器學習模型具有更強的特征提取能力,能夠自動地、智能地提取類灰度圖像的二維數值矩陣特征。同時基于神經網絡的檢測模型具有優秀的魯棒性和泛化性,對于未出現在訓練集的新ROP鏈具有良好的檢測性能。因此,采用神經網絡模型對ROP鏈進行檢測。

圖1 模型設計總體方案Fig.1 General design program of the model
當前,ROP鏈的檢測還沒有可用的公開數據集。ROPgadget[18]、Ropper[19]等工具能自動生成ROP鏈。但是一方面這些工具生成ROP鏈的方法過于標準化,使得生成的不同ROP鏈所包含的Gadget數量區別不大;另一方面用于生成ROP鏈的Gadget通常選自同一代碼段,功能較為單一。因此采用這些工具生成的ROP鏈并不能很好地反映真實ROP鏈的特點,不適合神經網絡模型的學習訓練。
由于構成ROP鏈的Gadget的第一字節與其他字節的分布差異大,因此本文基于ROP鏈所在區域的字節波動特征實現對ROP攻擊的檢測,并通過對真實ROP鏈進行分析,依據真實ROP鏈的結構特點來構建數據集。ROP鏈數據的生成方式是將真實Gadget的首字節與三個隨機的字節組合形成擴展的Gadget,并將若干個擴展Gadget拼接組成ROP鏈。通過從CVE和Expliot Database等收集并分析大量真實攻擊樣本,發現ROP鏈中Gadget的選擇來源往往小于6個不同的代碼區域。為提高模型檢測能力,本數據集提取了10個不同首字節的代碼地址段,每個代碼段有64 MB的地址空間。研究表明,在x86架構下,攻擊者實現簡單的條件轉移邏輯也需要串接11個不同的 Gadget[20],因此本數據集設定ROP鏈包含Gadget的數量在10~50個不等。ROP鏈數據集的構建如表1所示,ROP鏈的長度表示其包含的Gadget數量,地址段數表示ROP鏈包含的Gadget的地址段數量,如:地址段數為1表示Gadget都處于相同的地址段,其對應的首字節相同;地址段數為2表示ROP鏈中的Gadget有2個不同的首字節。該數據集既考慮了ROP鏈的長度,又考慮了Gadget的地址范圍,總樣本量在12 000以上,能滿足神經網絡訓練需求。

表1 ROP鏈數據集Tab.1 ROP chains data set
正常流量數據由USTC-TFC數據集構建[21]。USTC-TFC數據集包含異常流量和正常流量兩部分,本文選用其中的正常流量部分進行實驗,包含點對點(peer-to-peer,P2P)流量、多媒體流量、文件傳輸流量、電子郵件流量等。
ROP鏈包含Gadget內存地址和填充數據兩種數據,均為4 B,因此ROP鏈在流量中表現為多個4 B數據組成的代碼串。ROP鏈的核心單元是Gadget,它的字節數值表示所調用的代碼段在內存空間的具體位置。ROP鏈具有明顯的字節模式特征,即當Gadget是從同一個代碼段或相鄰代碼段中選取時,Gadget的第一個字節數值大小相同或相近,且Gadget后三個字節的數值是隨機的[17]。基于ROP鏈的字節模式特征,本文采用順序抽取的方法將流量數據分成四組,并采用滑動窗口進行數值量化,最后將一維流量數據轉化為二維矩陣,共4個步驟,如圖2所示。

圖2 二維特征數據預處理Fig.2 Preprocessing of two-dimensional feature data
Step1:對待測流量數據進行標準化清洗。去除數據包協議頭部,保留有效負載,輸出流量序列T。假定序列T總長4n,舍棄多余的字節。
Step2:將ROP鏈中所有Gadget字節有序分離并組合。將流量序列T從首字節開始,以0、1、2、3順序依次標號,并將同一標號數據組合為一組,共輸出4組數據T1、T2、T3、T4。經過第二步操作,ROP鏈中的Gadget的首字節一定屬于這4組數據中的某一組,這組數據的數值變化較小,波動平穩。另外3組數據分別包含Gadget的后3 B,其數值波動較大。
Step3:在T1、T2、T3、T4上選取窗長為L、步長為1的滑動窗口,對滑動窗口內的字節波動大小進行量化,量化方式有類化、熵化、擬熵化等。類化是統計滑動窗口內不同字節數值的個數,熵化是計算滑動窗口內字節的熵值,擬熵化是對熵化的改進。H1(x)、H2(x)、H3(x)分別表示采用類化、熵化、擬熵化的滑動窗口內的波動量化值。
H1(x)=n
(1)
(2)
(3)
其中,n表示滑動窗口內不同字節數值的個數,p(xi)表示滑動窗口內不同字節出現的次數。
Step4:單步滑動窗口,輸出4組數據S1、S2、S3、S4,輸出序列長度為365,長度不足則補零,疊加組合輸出矩陣S。這一步是得到神經網絡所用的標準數據,對數據進行疊加組合可以提取數據邊緣信息。
本文所提數據預處理方法,是在分析ROP鏈中Gadget不同字節波動特征的基礎上,通過序列抽取的方式,并結合滑動窗口對數據進行量化,從而實現數據特征的有效提取。該方法將一維流量數據轉為類灰度圖像的二維數值矩陣,包含了更為豐富的數據信息,且不需要預知目標軟件的地址信息。
ROP鏈在網絡流量中的局部特征明顯,且ROP鏈的檢測結果與其在流量中的位置無關。卷積神經網絡具有很強的局部上下文特征提取能力,并具有平移不變性的特點。經實驗驗證,卷積神經網絡在ROP鏈檢測任務中的準確率優于深度神經網絡以及循環神經網絡。因此,將卷積神經網絡作為檢測模型。
ROP鏈的檢測有實時性要求。本文設計了簡單且輕量級的卷積神經網絡結構,交替使用卷積層和池化層提取局部特征并減少模型參數,同時應用Dropout正則化增強模型對噪聲的魯棒性。檢測模型的結構如圖3所示。輸入8×365的定長二維數值矩陣,在第1個二維卷積層中先對輸入進行卷積,卷積核為3×3,共16個通道,生成16個長為6×363的特征圖。然后通過二維池化核2×2的最大池化層生成16個長為3×181的特征圖。在第2個二維卷積層中,卷積核為3×3,共32個通道,生成32個長為2×181的特征圖,然后通過二維池化核2×2的最大池化層,生成32個長為1×90的特征圖。完成上述操作后,將特征序列展平,通過兩個全連接層將序列依次轉換為128和1。模型使用的超參數如下:使用參數為0.6的Dropout正則化,輸出層采用Sigmoid函數作為激活函數,其他層使用ReLU函數作為激活函數,ReLU函數沒有復雜的指數運算,計算簡單、運算效率高。學習率設為1×10-4,訓練輪次為30,訓練總參數為37萬余個,損失函數采用二分類交叉熵損失函數。

圖3 卷積神經網絡結構Fig.3 Structure of convolutional neural network
滑動窗口長度L以及量化邊界D是影響模型數據預處理效果的兩個關鍵特征。為探究這兩個變量對算法性能的影響,依據相鄰代碼段首字節數值大小相近的特點,設置了長度范圍為5~24和量化邊界為0~3的循環實驗,共80個訓練模型進行性能對比,對比結果如圖4~6所示。

圖4 窗口長度與量化邊界對準確率的影響Fig.4 Influence of window length and quantization boundary on accuracy rate

圖5 窗口長度與量化邊界對誤報率的影響Fig.5 Influence of window length and quantization boundary on false alarm rate

圖6 窗口長度與量化邊界對漏報率的影響Fig.6 Influence of window length and quantization boundary on miss alarm rate
總體來講,采用不同窗長和量化邊界均能有效區分ROP鏈,準確率在94%以上,最高可達99.4%。通過對不同窗長和量化邊界的模型性能進行分析,可以發現:當窗長大于15時,模型的準確率下降較快,且量化邊界越大準確率越低;當窗長大于12時,模型的漏報率上升明顯,且量化邊界越大漏報率越高;模型的誤報率受窗口長度和量化邊界的影響較小;當窗長大于18時,模型性能波動劇烈,因為窗長過長容易涵蓋ROP鏈區域外的正常流量字節,造成模型性能不穩定。模擬訓練時的損失函數收斂曲線如圖7所示,隨著訓練輪次的增加,檢測準確率穩定上升,誤差損失值平穩下降。

圖7 損失函數收斂曲線Fig.7 Loss function convergence curve
實驗使用的神經網絡框架為TensorFlow。實驗硬件GPU為GeForce RTX 3060 Laptop,CPU為11th Gen Intel(R) Core(TM) i7-11800H@2.30 GHz,內存為16 GB。
實驗選取長度在150~1 550范圍內的數據包,滑動窗口長度設為12。為驗證不同預處理方法模型的檢測效率,將數據包分別輸入采用不同量化方法的二維特征檢測模型中,測算從數據輸入到檢測結果輸出的時間開銷,實驗結果如圖8所示,圖中散點表示對于單個數據包檢測的時間開銷,而直線是對這些單個數據包檢測開銷的擬合結果。三種量化方式的時間開銷均在0.14 s以內,類化方式所用時間開銷明顯低于熵化和擬熵化,類化方式大部分數據包的檢測時間在0.1 s以內,擬熵化模型次之,熵化模型時間開銷最大。

圖8 不同量化方法的時間開銷Fig.8 Time costs of different quantization methods
為驗證數據預處理的有效性,開展了未經數據預處理的源數據和數據預處理后數據的模型性能對比實驗,如圖9所示。實驗結果表明:經過數據預處理后,模型的準確率提升9.9%,誤報率降低5.7%,漏報率降低14.1%,充分驗證了數據預處理方法和檢測模型的有效性。

(a) 準確率對比(a) Accuracy rate comparison

(c) 漏報率對比(c) Miss alarm rate comparison圖9 二維特征預處理前后模型性能對比Fig.9 Comparison of model performance before and after two-dimensional feature preprocessing
為驗證模型對真實ROP鏈的檢測性能,分別選取ROPgadget、Exploit Database、CVE中的ROP鏈進行檢測實驗。通過ROPgadget生成的ROP鏈188個,分別模擬10次攻擊。Exploit Database漏洞庫中漏洞利用程序的ROP鏈共計445個,分別模擬10次攻擊。在Github中收集的CVE漏洞利用程序的ROP鏈49個,分別模擬100次攻擊。實驗表明,經過數據預處理后的模型具有較強的泛化性能,能夠以極低的漏報率實現對真實ROP鏈的有效檢出,而未經數據預處理的模型漏報率非常高,如表2所示。實驗發現一個有趣的結果,兩種模型檢測由ROPgadget工具產生的ROP鏈的漏報率均為0,因為ROP鏈自動生成工具的生成邏輯往往會遵循某些固定范式,產生的ROP鏈也非常規范,容易被檢測。如果采用此類工具產生的ROP鏈來訓練神經網絡模型,模型的訓練性能非常好,但是實際檢測性能往往非常差。

表2 不同來源真實ROP鏈檢測的漏報率Tab.2 False negative rate of real-world ROP chains
ROP鏈的長度決定了目標區域的長度,其長度越長,特征也越明顯。以往的研究很少關注ROP鏈的長度對模型性能的影響。實驗分析二維特征檢測模型對6個分組(每個分組的地址段數不同,如表1所示)中不同長度(10~30)ROP鏈的檢測能力(用漏報率衡量)。模型類別采用L-D表示,L為窗長,D為量化邊界。選用最高準確率模型12-0、最短窗長模型5-0和較長窗長模型17-0進行實驗。由于量化邊界為0時,模型性能較優,因此模型的量化邊界統一選擇為0。
實驗表明窗長和地址段數對模型的檢出性能影響較大,如圖10所示,隨著ROP鏈長度的增加,漏報率均可降低至1%以下。在窗長相同的情況下,地址段數越多,則模型漏報率越高、波動越大,因為地址段數越多,ROP鏈的字節特征與正常流量字節特征更接近。窗長越短,模型對于不同地址段數的漏報率的波動越大,因為短窗口對連續區域的波動量化能力有限,無法很好地規避波動干擾。窗長越長,模型對于不同地址段數的漏報率變化趨勢越相似,因為長的窗口可以抵消地址段數增加帶來的負面影響。

(a) 5-0模型(a) 5-0 model

(c) 17-0模型(c) 17-0 model圖10 模型漏報率Fig.10 Miss alarm rate of model
ROPminer、SPRT[22]、DeepReturn等模型雖然具有較高的準確率,但這些方法都依賴程序的內存地址信息。本文提出的方法與已有方法最關鍵的區別在于不依賴程序的內存地址信息,具有更低的復雜度和更廣泛的應用場景,對比數據如表3所示。雖然Strop方法也不依賴內存地址信息,但該方法對于68個ROP樣本僅檢測到51個,漏報率高達25%。本文方法、SPRT和ROPminer都是完全靜態的方法,僅根據網絡數據流就可實現ROP鏈的檢測。DeepReturn需要對流量字節進行反匯編,雖然其誤報率較低,但該方法需要結合內存地址信息,通用性較差。SPRT和本文方法探索了ROP鏈長度對算法性能的影響。在SPRT中,當訓練數據集ROP鏈長度為10~50時,準確率僅為93.2%;當訓練數據集ROP鏈長度為20~100時,準確率才達到99.0%。本文方法在訓練數據集ROP鏈長度為10~50時,準確率可達99.4%。因此本文方法在檢測較短長度的ROP鏈時具有更高的準確率。Strop、ROPminer、DeepReturn等方法均采用真實ROP樣本驗證方法的有效性,但本文用于實驗驗證的真實樣本數量遠多于其他方法。以上方法中,ROPminer進行了時間開銷實驗,單文件的時間開銷為0.9 s,本文方法的時間開銷在0.1 s以內。

表3 與現有方法的對比分析Tab.3 Comparison with existing methods
本文提出了一種基于字節模式二維特征的ROP鏈檢測方法,首先對原始流量數據包進行數據清洗,然后對清洗后的數據進行序列抽取,經滑動窗口采樣后對數據進行量化處理,將輸入的一維數據轉換為二維特征向量,并采用卷積神經網絡模型實現對ROP鏈的檢測。該方法能自動從樣本中提取ROP鏈字節模式二維特征,并具有良好的泛化能力,能檢測訓練集中未出現過的新ROP鏈。模型的檢測準確率達到99.4%,單數據包的時間開銷在0.1 s以內,且模型對真實ROP樣本的測試漏報率接近于0,相較于Strop、ROPminer、SPRT等傳統方法,在檢測性能上具有明顯優勢。同時,該方法可直接對流量數據進行檢測,不需要預知代碼段加載內存地址,部署方便并具有良好的可解釋性。下一步將深入分析不同類型漏洞樣本的特征,建立更為豐富的漏洞攻擊樣本庫,并研究基于語義分析的檢測模型,進一步提高模型的泛化性能,以及模型對不同類型漏洞攻擊的檢測能力。