• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

      基于配件加權(quán)標(biāo)記的代碼重用攻擊防御框架

      2018-10-16 12:15:38馬夢雨陳李維
      信息安全學(xué)報 2018年5期
      關(guān)鍵詞:粗粒度控制流配件

      馬夢雨 , 陳李維 , 史 崗 , 孟 丹

      1中國科學(xué)院信息工程研究所 北京 中國 100093

      2中國科學(xué)院大學(xué) 網(wǎng)絡(luò)空間安全學(xué)院 北京 中國 100049

      1 前言

      攻擊者利用軟件漏洞控制應(yīng)用程序的行為和邏輯, 進而通過提權(quán)威脅計算機系統(tǒng)的安全。傳統(tǒng)的代碼注入攻擊通過外部輸入的方式在程序內(nèi)存中存儲惡意代碼, 同時利用軟件漏洞劫持程序控制流轉(zhuǎn)向惡意代碼。但是研究者提出的數(shù)據(jù)執(zhí)行保護(Data Execution Prevention, DEP)能夠從本質(zhì)上緩解代碼注入攻擊, DEP規(guī)定所有可寫的內(nèi)存頁不可執(zhí)行, 因此用戶輸入的惡意代碼僅僅被當(dāng)作數(shù)據(jù), 即使程序指針跳轉(zhuǎn)到惡意代碼所在的內(nèi)存頁, 攻擊也無法繼續(xù)執(zhí)行。隨后, 研究者提出了代碼重用攻擊(Code Reuse attack, CRA), 它使用程序中原有的指令片段替代外部輸入的指令, 從而繞過 DEP的防御。根據(jù)重用指令的不同可分為返回導(dǎo)向編程(Return-oriented Programming, ROP)[1]和跳轉(zhuǎn)導(dǎo)向編程(Jump-oriented Programming, JOP)[2]兩種主流攻擊方式。如今, CRA逐漸取代代碼注入成為主要的攻擊手段。

      CRA的核心思想是重用程序中已經(jīng)存在的指令,這些指令能夠完成一定的計算或賦值等功能, 然后以ret指令或jmp指令結(jié)尾構(gòu)成一段指令片段, 稱之為配件(Gadget), 多個配件相連構(gòu)成惡意的shellcode。攻擊者通過軟件漏洞劫持程序控制流轉(zhuǎn)向第一個配件的地址, 系統(tǒng)就會自動地執(zhí)行配件鏈完成攻擊。CRA被證明是圖靈完備的[2], 且能夠通過固定的模式形成自動化的攻擊工具[3], 因此 CRA具備容易使用、難以防御、圖靈完備的特性。隨后, 研究者提出的控制流完整性(Control Flow Integrity,CFI)[4-5]理論上能夠完全防御ROP和JOP兩種主流攻擊方式, CFI首先分析程序中的所有合法執(zhí)行路徑并生成控制流圖(Control Flow Graph, CFG), 其次在CFG路徑上添加標(biāo)記信息, 最后嚴格按照CFG執(zhí)行程序, 因此攻擊者無法隨意更改控制流, 也就打斷了配件鏈的執(zhí)行過程。但是 CFI有兩個主要的缺點,第一, 較高的復(fù)雜性造成近百分之五十的系統(tǒng)開銷[4];第二, 構(gòu)建完善且精確的CFG幾乎不可能實現(xiàn)。

      為了解決 CFI的兩個主要問題, 研究者提出了很多實際的解決方案[6-9]。制定更為寬松的CFI策略來降低系統(tǒng)的性能開銷, 首先, 通過分析普通程序的合法控制流轉(zhuǎn)移, 總結(jié)出一些控制流轉(zhuǎn)移規(guī)律,例如call指令應(yīng)該指向一個函數(shù)入口的地址等; 其次,不依賴完整的 CFG, 而是利用這些規(guī)律識別目標(biāo)程序中合法與非法的執(zhí)行路徑。這些寬松的 CFI策略被稱之為粗粒度CFI, 它并沒有構(gòu)建程序的CFG, 而是從中抽取控制流轉(zhuǎn)移的規(guī)律來制定相應(yīng)的規(guī)則,雖然降低了系統(tǒng)性能開銷, 但其安全保障要低于基于 CFG的原始 CFI, 最近也有很多學(xué)者提出使用特殊配件繞過粗粒度CFI的方案[10-13]。

      我們分析現(xiàn)有能夠被CRA利用的配件, 發(fā)現(xiàn)配件的幾個特征如下: 僅僅占據(jù)整個代碼空間的很小一部分; 在普通程序中很少出現(xiàn)且不連續(xù); 在 CRA中連續(xù)出現(xiàn)并形成配件鏈。因此, 我們能夠通過監(jiān)控程序運行時的配件特征來區(qū)分普通和惡意程序, 如圖1所示。

      本文提出配件加權(quán)標(biāo)記(Gadget Weighted Tagging, GWT)的思想, 一種靈活地檢測并防御CRAs的防御機制。首先, 我們根據(jù)配件在CRA中發(fā)揮的作

      圖1 普通程序和CRA的配件分布規(guī)律Figure 1 The Gadget Distribution in Normal Programs and CRAs

      用, 把所有可能的配件分成三種主要類型: 功能配件, NOP配件和普通代碼; 其次, 我們?yōu)椴煌愋偷呐浼峙洳煌臋?quán)值, 并在二進制文件中附加對應(yīng)的權(quán)值標(biāo)記; 最后, 在程序運行時監(jiān)控各類配件權(quán)值的累加值, 當(dāng)這個值超過設(shè)定的閾值時, GWT判斷為發(fā)生CRA。除此之外, 我們還提出了GWT結(jié)合粗粒度CFI的思想, 因為我們發(fā)現(xiàn)粗粒度CFI對控制流轉(zhuǎn)移的策略是對 GWT很好的補充, 采用GWT+CFI可以更精準(zhǔn)的識別配件并且完善框架的安全策略。

      GWT的實現(xiàn)依賴一些重要的參數(shù), 如不同配件類型對應(yīng)的權(quán)值, 用戶可根據(jù)實際需求對這些參數(shù)進行調(diào)整并重新配置。同時如果用戶需要添加一些新的特殊配件, 也可以在GWT中添加相應(yīng)的配件類型并分配權(quán)值。正是因為GWT具備靈活的可擴展性,所以 GWT能夠檢測 CRA的多種利用方式, 而且GWT的安全性也能夠隨著配件類型的不斷完善而逐漸加強。當(dāng)研究者提出一種新的CRA方式或配件類型時, 通常會介紹攻擊的構(gòu)建方法或配件的尋找算法, 所以GWT可以重用這些方法或算法找到程序中可能存在的配件, 完善其配件類型和安全策略。我們基于軟件和硬件模擬的設(shè)計框架實現(xiàn) GWT以及GWT+CFI系統(tǒng), 結(jié)果表明其性能開銷分別為2.31%和3.55%, 并且GWT理論上能夠檢測使用自動化工具 Q[3]生成配件鏈的 CRA, 以及使用特殊配件的新型CRA。

      這篇論文的主要貢獻如下:

      1) 我們提出一種防御代碼重用攻擊(Code Reuse Attack, CRA)的新型系統(tǒng)化框架: 配件加權(quán)標(biāo)記(Gadget Weighted Tagging, GWT), 具備靈活可配置、高安全性、低開銷、易用的特點。

      2) 我們提出GWT結(jié)合粗粒度CFI的防御思想,相比基礎(chǔ)的GWT, GWT+CFI尋找配件更加精確。

      3) 我們基于軟件和硬件模擬的設(shè)計框架實現(xiàn)GWT和GWT+CFI系統(tǒng), 并且評估了其安全性和性能開銷。

      本文內(nèi)容組織如下: 第二章節(jié)介紹相關(guān)研究背景, 包括CRA、CFI、合法配件以及威脅模型; 第三和第四章節(jié)分別闡述GWT以及GWT+CFI的基本原理和實現(xiàn)細節(jié); 第五章節(jié)為實驗評估, 包括GWT的安全性分析和性能分析; 第六章節(jié)對配件分類和GWT框架的靈活性進行討論; 第七章節(jié)介紹防御CRA的研究現(xiàn)狀; 第八章節(jié)對全文進行總結(jié)。

      2 背景

      2.1 代碼重用攻擊CRA

      CRA本質(zhì)就是在已有的代碼空間中尋找具備一定功能的指令片段, 稱之為配件(Gadget), 然后串連配件形成圖靈完備的配件鏈執(zhí)行惡意功能, 比如打開一個非法 Shell。配件通常由幾條具備計算功能的普通指令加上一條間接轉(zhuǎn)移指令組成, 普通指令完成惡意功能, 間接轉(zhuǎn)移指令劫持程序控制流并串連多個配件。通過上述分析, CRA的核心在于配件, 而配件的特征在于結(jié)尾的間接跳轉(zhuǎn)指令, 所以本文關(guān)注三類通用的間接轉(zhuǎn)移指令: call, return, indirect-jmp。除此之外, 多數(shù) CRAs中使用的配件還具備以下兩點重要特征:

      1) 稀疏的配件分布

      配件都是以間接轉(zhuǎn)移指令為結(jié)尾, 然而間接轉(zhuǎn)移指令僅僅占整個代碼空間的很小一部分, 因此CRA使用的配件在普通程序中的分布應(yīng)該是非常稀少的。

      2) 短小的指令片段

      通常配件中包含的指令條數(shù)越多, 完成的功能也就越多, 但同時也不可避免的造成一些副作用,比如寄存器的依賴沖突將會導(dǎo)致相關(guān)數(shù)據(jù)被覆寫。因此攻擊者會使用簡單且指令條數(shù)較少的配件來消除這些副作用[3], 而不是為了完成更多的操作, 選擇冗長且復(fù)雜的配件。實際上, 在真實的 CRA中, 配件的指令數(shù)大約為2~6條[8]。

      根據(jù)配件中間接轉(zhuǎn)移指令的不同可以把傳統(tǒng)CRA分為ROP攻擊和JOP攻擊。ROP攻擊依賴棧指針的返回機制完成控制流的劫持, 多個配件通過ret指令跳轉(zhuǎn)相連。JOP攻擊相比ROP要復(fù)雜一些, 因為它引入一種新的配件, 稱之為調(diào)度配件(dispatcher gadget), 所以 JOP并不依賴于棧的返回機制完成攻擊, 而是使用一種調(diào)度表(dispatch table)或具有連接各個配件功能的結(jié)構(gòu)保存所有配件的地址, 通過調(diào)度配件劫持程序控制流, 然后驅(qū)動調(diào)度表或同等結(jié)構(gòu)中的各個配件完成攻擊[14]。調(diào)度配件是構(gòu)造 JOP攻擊的關(guān)鍵, 它通常包含一些自修改跳轉(zhuǎn)地址的操作, 并且以indirect-jmp指令結(jié)尾, 相當(dāng)于程序eip指針的作用, 可用過程1簡單描述調(diào)度配件的功能[14]。

      過程1. 調(diào)度配件的功能描述PC <—f(PC);GOTO*PC;

      2.2 控制流完整性CFI

      CFI作為對抗CRA的主流防御方法之一, 自然備受研究者關(guān)注, 近年來也提出了很多實際的實施方案[5-9,15]。本文把這些CFI方案大體分類兩類: 基于CFG的CFI和基于策略的CFI。

      2.2.1 基于CFG的CFI

      基于CFG的CFI, 也稱之為細粒度CFI, 通過靜態(tài)分析生成 CFG, 并嚴格按照 CFG執(zhí)行程序, 具備很高的安全性, 理論上能夠檢測任何非法的控制流劫持。但是, 僅僅通過靜態(tài)分析幾乎不可能生成包含所有可達路徑的理想 CFG, 且細粒度 CFI的性能開銷很大[4]。正因為上述不足, 近幾年一些研究者提出了針對基于保守CFG的CFI的繞過方法[16,17], 更有研究者表明即使能夠生成理想的 CFG, 也可以通過污染非控制數(shù)據(jù)使得控制流合法轉(zhuǎn)移, 繞過基于理想CFG的CFI[18]。

      2.2.2 基于策略的CFI

      基于策略的 CFI, 也稱之為粗粒度 CFI, 它并不依賴靜態(tài)生成的 CFG, 而是通過制定一些控制流轉(zhuǎn)移的規(guī)則來防御多數(shù)CRAs, 即依據(jù)普通程序的合法控制流轉(zhuǎn)移規(guī)律來制定安全策略, 因此粗粒度 CFI具備低開銷, 易部署的優(yōu)勢。這些規(guī)則大體上可分為以下兩類:

      1) 控制流轉(zhuǎn)移策略: 這些策略主要規(guī)定不同間接轉(zhuǎn)移指令的合法目的地址[7,19]。

      RETURN指令 一條return指令應(yīng)當(dāng)指向call指令的下一條指令(call-preceded指令)。

      CALL指令 一條 call指令應(yīng)當(dāng)指向一個函數(shù)開始執(zhí)行的第一條指令(函數(shù)入口指令)。

      Indirect-JUMP指令 一條indirect-jmp指令要么指向所在函數(shù)地址范圍內(nèi)的任意一條指令, 那么指向其他函數(shù)開始執(zhí)行的第一條指令(函數(shù)入口指令)。

      2) 代碼長度策略: 這些策略規(guī)定單一配件的長度, 以及完成CRA使用的配件鏈長度[8,9]。

      配件長度 考慮單一配件, 除了指令片段應(yīng)當(dāng)以間接轉(zhuǎn)移指令為結(jié)尾, 還應(yīng)當(dāng)滿足包含的指令條數(shù)大致在 2~6的數(shù)量范圍之內(nèi), 更長的指令片段不再認為是配件。

      配件鏈長度 考慮配件鏈中配件數(shù)量的統(tǒng)計規(guī)律, 通常完成多數(shù)CRAs至少需要六個配件, 因此更短的配件鏈長度不再認為是CRA。

      2.3 合法配件

      粗粒度CFI通過定義一些規(guī)則(如2.2節(jié)中提到的控制流轉(zhuǎn)移和代碼長度策略)來識別程序中哪些代碼片段是合法的指令, 哪些是攻擊者利用的配件。但是, 攻擊者能夠找到繞過這些規(guī)則的特殊配件(Special Gadgets), 本文稱之為合法配件。因此在CRA中使用合法配件就可以繞過粗粒度CFI的防御,下面介紹三類合法配件的概念:

      1) Call-Preceded配件

      Call-Preceded指令是指代碼空間中 call指令緊鄰的下一條指令[13]。Call-Preceded配件表示以一條Call-Preceded指令開頭的配件類型, 因此它能夠符合粗粒度 CFI的控制流轉(zhuǎn)移策略, 作為任何一條return指令的目的地址。

      2) Entry-Point配件

      Entry-Point配件是指以函數(shù)入口指令為開頭的配件類型, 因此它能夠符合粗粒度 CFI的控制流轉(zhuǎn)移策略, 作為任何一條call指令或indirect-jmp指令的目的地址。

      3) Long-NOP配件

      Long-NOP配件是指包含足夠指令數(shù)量的配件類型, 且不能和普通配件依賴的數(shù)據(jù)產(chǎn)生沖突。通常Long-NOP配件包含一些如NOP等不修改寄存器的指令, 或者包含一些寫內(nèi)存指令(修改無關(guān)緊要的內(nèi)存地址), 這些指令不會影響配件鏈的正常功能。因此攻擊者可以使用 Long-NOP配件構(gòu)建更長的指令片段作為攻擊配件, 以此繞過粗粒度 CFI中基于代碼長度的策略。

      2.4 威脅模型

      本文提出的防御機制主要針對于各類CRAs, 因此我們假設(shè)攻擊者擁有對數(shù)據(jù)和堆棧的控制權(quán), 同時能夠修改處理器中通用寄存器的值。對于攻擊手段, 我們假設(shè)系統(tǒng)中已經(jīng)部署DEP, 因此攻擊者不能夠使用代碼注入攻擊而不得不選擇使用代碼重用的攻擊方式。對于攻擊目的, 我們假設(shè)主要是為了獲得系統(tǒng)權(quán)限。另外我們假設(shè)攻擊者不使用非對齊配件,所謂非對齊配件, 是由不定長指令集(例如x86平臺)導(dǎo)致對于相同一段機器碼, 從不同位置開始讀取,得到的指令是不一樣的。而這種情況很容易被 CFI的控制流轉(zhuǎn)移策略檢測[19], 因此本文不考慮非對齊配件的情況。原因有兩點, 第一, GWT框架要求所有的間接跳轉(zhuǎn)指令之前都接一條預(yù)取指令, 增加了攻擊者尋找非對齊配件的難度, 如果一個間接跳轉(zhuǎn)指令之前沒有預(yù)取指令, 或者預(yù)取指令包含的信息有誤, 我們就可以認為這是一個非對齊配件; 第二,GWT和粗粒度CFI結(jié)合使用, 規(guī)定了間接跳轉(zhuǎn)指令的目標(biāo)地址(如函數(shù)頭, call指令的下一條指令), 也就避免了非對齊配件地出現(xiàn)。

      為了更好地介紹我們提出的防御方法 GWT, 本文提出了以下兩種不同的系統(tǒng)環(huán)境:

      1) 基礎(chǔ)環(huán)境

      基礎(chǔ)環(huán)境是指系統(tǒng)中不包含任何其他特殊的防御機制, 僅僅部署DEP技術(shù)。

      2) 保護環(huán)境

      保護環(huán)境是指系統(tǒng)中除了部署 DEP, 還添加了如2.2節(jié)描述的粗粒度CFI技術(shù), 對控制流轉(zhuǎn)移進行保護。

      3 配件加權(quán)標(biāo)記

      本章節(jié)包括兩個部分, 第一部分在3.1~3.3節(jié)介紹基礎(chǔ)環(huán)境中配件加權(quán)標(biāo)記(Gadget Weighted tagging, GWT)的整體框架, 主要包含三個步驟: 尋找所有可能被CRA利用的配件; 根據(jù)權(quán)值信息標(biāo)記第一步找到的配件; 程序運行時監(jiān)控權(quán)值標(biāo)記的變化情況, 判斷是否發(fā)生CRA。

      第二部分作為對第一部分的補充, 在3.4節(jié)介紹保護環(huán)境中 GWT結(jié)合粗粒度 CFI的框架(GWT+CFI)。粗粒度 CFI包含控制流轉(zhuǎn)移策略和代碼長度策略, 但是GWT中已經(jīng)考慮了配件的長度和類型, 也就是說GWT已經(jīng)包含了代碼長度策略, 所以 GWT要比單獨考慮代碼長度策略的防御機制更加精確[8,9], 因此我們添加控制流轉(zhuǎn)移策略作為GWT的補充即可。

      3.1 配件尋找過程

      3.1.1 尋找配件的結(jié)尾

      因為配件的主要特征是以間接轉(zhuǎn)移指令(return,call, indirect-jmp)為結(jié)尾, 所以理論上所有以間接轉(zhuǎn)移指令結(jié)尾的代碼片段都有可能作為配件。因此, 我們首先搜索程序代碼空間中所有的間接轉(zhuǎn)移指令,并把這些指令定義為配件的結(jié)尾。

      3.1.2 定義配件類型

      著名的ROP攻擊框架Q[3]開源了一種支持多種架構(gòu)的ROP編譯器, 它能夠根據(jù)Q中定義的配件類型判斷一段指令是否屬于配件以及配件的具體類型。Q依據(jù)指令片段表示的功能定義不同的配件類型,包括NoOp, Jump, MoveReg, LoadConst, Arithmetic,LoadMem, StoreMem, ArithmeticLoad, Arithmetic-Store共九種基本配件類型[3], 并提出了一種算法來識別每個配件的類型, 且每個配件應(yīng)當(dāng)僅僅符合定義中的一種功能。

      在GWT中, 我們定義四種配件類型, 如圖2所示。其中, 功能配件和Q定義的配件類型一致, 但不包括NoOp, 調(diào)度配件(Dispatcher Gadget)和系統(tǒng)調(diào)用配件(Syscall Gadget)是功能配件(Functional Gadget)中的兩類特殊配件, 并且這兩類特殊配件在CRA中具備至關(guān)重要的功能。下面對具體的配件類型進行介紹:

      圖2 GWT中配件類型的分類Figure 2 The Gadget Types in GWT

      1) 功能配件

      在CRA中, 功能配件是穩(wěn)定完成某些實際操作且不產(chǎn)生任何副作用的指令片段, 例如算數(shù)邏輯運算、分支轉(zhuǎn)移、從內(nèi)存讀取數(shù)據(jù)等。GWT中功能配件的定義與Q基本一致, 但不包括NoOp配件。

      2) 調(diào)度配件

      調(diào)度配件是一種特殊的功能配件, 它在 JOP中扮演重要的角色[14], 包含一些自修改跳轉(zhuǎn)地址的操作, 并且以 indirect-jmp指令結(jié)尾。調(diào)度配件的本質(zhì)就是模擬了一個虛擬的PC指針, 驅(qū)動JOP攻擊的可持續(xù)過程, 連接一個又一個功能配件。

      3) 系統(tǒng)調(diào)用配件

      系統(tǒng)調(diào)用配件是一種以syscall指令結(jié)尾的特殊功能配件, 攻擊者首先污染rax填充任意系統(tǒng)調(diào)用號,然后結(jié)合系統(tǒng)調(diào)用配件實現(xiàn)惡意的系統(tǒng)調(diào)用劫持。例如, 為了使 CRA更加簡單, 攻擊者通過系統(tǒng)調(diào)用配件陷入內(nèi)核, 強行關(guān)閉一部分內(nèi)存頁的不可執(zhí)行位(使得 DEP防御失效), 然后向這部分內(nèi)存注入惡意代碼, 最后劫持控制流轉(zhuǎn)向惡意代碼完成攻擊[10]。

      4) NOP配件

      NOP配件指那些既不產(chǎn)生功能也不產(chǎn)生副作用的配件類型, 它包括Q提出的NoOp配件和本文第二章提到的Long-NOP配件。為了確保添加NOP配件不改變CRA配件鏈的原始語義, NOP配件通常只使用很少一部分寄存器[13], 這樣可以避免和功能配件使用的寄存器產(chǎn)生沖突。攻擊者使用NOP配件的目的往往是繞過一些防御機制, 例如基于策略的粗粒度CFI[8-9]。

      3.1.3 尋找配件的開端(最大配件長度)

      根據(jù)配件的組成特點, 很容易找到它的結(jié)尾(間接轉(zhuǎn)移指令), 但尋找配件的開端相對困難。根據(jù)之前研究者的工作, 往往通過代碼的長度去識別配件,因為配件的長度具有一定的規(guī)律, 過長的代碼片段會產(chǎn)生副作用, 也有可能會和其他配件相互沖突。通常配件的長度在2~6條指令之間[8], 但是不排除攻擊者為了躲避一些防御機制, 使用幾乎對CRA沒有副作用的特殊配件(例如Long-NOP配件), 將其插入常規(guī)配件鏈中以躲避基于規(guī)則的防御。

      在GWT框架中, 隨著配件長度的增加, 包含過多的指令將產(chǎn)生無法避免的副作用, 所以NOP配件終將變成普通代碼。普通代碼就是無法被任何CRAs利用的配件, 本文假設(shè)所有不是功能配件和NOP配件的代碼都是普通代碼。類似, 若配件包含過多的指令, 功能配件也終將變成NOP配件或普通代碼。因此, GWT使用每種配件類型的最大長度來識別配件的開端。下面分析功能配件和NOP配件的最大長度:

      1) 功能配件的最大長度

      尋找到配件的結(jié)尾以后, 采用回溯的方法尋找配件的最大長度, 每次向前增加一條指令, 并結(jié)合Q[3]中識別配件的模塊(ROP編譯器)判斷該指令片段是否屬于配件, 屬于什么類型的配件。如果屬于功能配件, 則繼續(xù)回溯指令, 直到該指令片段不再屬于功能配件為止, 此時前一狀態(tài)下的指令數(shù)就是該功能配件的最大長度, 指令片段的第一條指令就是該功能配件的開端。對于調(diào)度配件和系統(tǒng)調(diào)用配件, 因為它們屬于功能配件的特殊情況, 所以它們最大長度的尋找過程同普通功能配件一致。

      2) NOP配件的最大長度

      類似功能配件, 當(dāng) Q判斷出該指令片段屬于NOP配件時, 繼續(xù)回溯, 直到該指令片段不再能夠被 CRA利用為止(例如普通代碼), 此時前一狀態(tài)下的指令數(shù)就是該NOP配件的最大長度, 指令片段的第一條指令就是該NOP配件的開端。

      3.2 標(biāo)記權(quán)值信息

      GWT框架需要為找到的所有配件附加權(quán)值標(biāo)記信息, 權(quán)值標(biāo)記的結(jié)構(gòu)包含三個部分: 配件類型, 功能配件的最大長度, 以及 NOP配件的最大長度。這里的配件類型除了 3.1.2節(jié)中定義的四種之外,還包括普通代碼, 表示無法被任何CRAs利用的配件類型。

      其中功能配件最大長度的概念涵蓋了特殊配件的情況, 即包括普通的功能配件和調(diào)度配件以及系統(tǒng)調(diào)用配件的最大長度。隨著配件長度的增加, 功能配件可能先變?yōu)镹OP配件再變?yōu)槠胀ùa, 所以存在同一條配件結(jié)尾指令(間接轉(zhuǎn)移指令)在不同狀態(tài)下對應(yīng)兩種配件類型的最大長度。因此我們假設(shè)如果同一條配件結(jié)尾指令對應(yīng)不同的配件類型, 依據(jù)NOP配件的最大長度不小于功能配件的最大長度進行進一步判斷。

      不同的配件類型在 CRA中扮演著不同的角色,產(chǎn)生不同的效果, 因此我們依據(jù)對系統(tǒng)的威脅程度為不同配件類型分配不同的權(quán)值, 權(quán)值越高, 則表示對應(yīng)的配件類型對系統(tǒng)威脅越大, 同時在CRA中也越可能被使用。

      每一種配件類型的具體權(quán)值分配如表 1所示,不同配件類型的權(quán)值可以由用戶根據(jù)安全需求自行配置, 而且也可以添加新的配件類型和新的權(quán)值。對于NOP配件, 因為它對CRA并無實質(zhì)性的幫助, 只是為了稀釋配件鏈的長度而存在, 所以分配給它的權(quán)值為 0。對于功能配件, 因為它包含了 CRA中一系列的具體功能操作, 所以分配給它的權(quán)值為1。對于調(diào)度配件, 因為它是 JOP攻擊中的核心配件且管理其他配件的運行, 所以分配給它的權(quán)值為2。對于系統(tǒng)調(diào)用配件, 因為它是操作系統(tǒng)內(nèi)核函數(shù)的入口,并且多數(shù) CRAs的最終目的是通過系統(tǒng)調(diào)用提權(quán)或禁用系統(tǒng)安全機制, 它比其他類型的配件都重要,所以分配給它的權(quán)值為4。對于普通代碼, 因為CRA中配件鏈的執(zhí)行是連續(xù)無間斷的, 另外本文假設(shè)普通代碼包含過多實際的功能操作, 對CRA具有很強的干擾, 會破壞配件之間的數(shù)據(jù)傳遞, 不可能被當(dāng)作配件使用, 攻擊者不可能把普通代碼插入到任何的配件鏈中, 所以當(dāng)遇到普通代碼時, 則可判斷此時不會發(fā)生惡意攻擊, 對權(quán)值進行清零操作。

      表1 不同配件類型的權(quán)值分配Table 1 Weighted Scores of Different Gadget Types

      3.3 監(jiān)控配件標(biāo)記

      因為CRA由一系列連續(xù)的配件組成, 且每個配件以一條間接轉(zhuǎn)移指令為結(jié)尾, 基于這兩點特性,GWT截取程序運行時每兩條間接轉(zhuǎn)移指令之間的代碼片段(包含后執(zhí)行的那條間接轉(zhuǎn)移指令)組成不同長度的可能配件, 本文稱之為候選配件。另外我們在靜態(tài)分析階段為每條間接轉(zhuǎn)移指令附加了權(quán)值標(biāo)記,且 GWT又能夠在動態(tài)分析階段識別當(dāng)前的候選配件, 因此可以通過動靜結(jié)合的方式判斷運行時候選配件的真實類型: 如果當(dāng)前候選配件的長度大于NOP配件的最大長度, 則候選配件可判斷為普通代碼; 如果當(dāng)前候選配件的長度小于功能配件的最大長度, 則候選配件可判斷為功能配件; 如果以上兩種情況都不滿足, 則可判斷候選配件為NOP配件。

      通過上述過程, GWT對當(dāng)前程序運行狀態(tài)下的候選配件進行判斷, 若識別為普通代碼, 則表示當(dāng)前程序并無CRA發(fā)生。相反, 若GWT識別多個候選配件為功能配件時, 則表示當(dāng)前程序很有可能發(fā)生了CRA。GWT通過動態(tài)監(jiān)控當(dāng)前程序候選配件的真實類型, 依據(jù)表1中不同配件類型的權(quán)值分配, 累加候選配件對應(yīng)的權(quán)值, 最終得出一個數(shù)值, GWT根據(jù)這個數(shù)值得出發(fā)生CRA的概率。

      3.4 GWT+CFI框架

      3.4.1 GWT+CFI框架的動機

      GWT的主要不足之處在于無法準(zhǔn)確識別配件的開端, 僅僅是通過尋找配件的最大長度來確定, 這并不是十分精確, 因此我們提出 GWT結(jié)合粗粒度CFI的思想, GWT+CFI能夠帶來以下兩點好處:

      1) 識別配件開端

      攻擊者為了能夠繞過粗粒度 CFI的防御, 常見的思路就是使用特殊配件, 例如 Call-Preceded配件和Entry-Point配件。正因為如此, 特殊配件也帶來了無法避免的特征, 那就是攻擊者必須要求配件的第一條指令, Call-Preceded配件需要以Call-Preceded指令為開端, Entry-Point配件需要以函數(shù)入口指令為開端。因此, 我們能夠使用GWT+CFI的思想更精確地識別配件的開端。

      2) 減少配件數(shù)量

      除了合法配件, 粗粒度 CFI能夠檢測出其他非法的配件, 所以我們能夠使用GWT+CFI的思想減少能夠被CRA利用的配件數(shù)量, 因此我們能夠更加精確定位代碼空間中可能被CRA利用的配件。

      3.4.2 尋找合法配件

      GWT和GWT+CFI的最大區(qū)別在于尋找配件的過程。GWT+CFI只需去尋找合法的配件即可, 對于配件的權(quán)值標(biāo)記和動態(tài)監(jiān)控都和基礎(chǔ)的 GWT框架一致。

      GWT+CFI尋找配件的過程大致如下: 首先, 需要找到所有的間接轉(zhuǎn)移指令, 即配件的結(jié)尾; 其次,需要找到所有合法配件的開端, Call-Preceded配件的開端就是Call-Preceded指令, Entry-Point配件的開端就是函數(shù)的入口指令; 然后, 根據(jù)配件的結(jié)尾和開端識別所有的合法配件; 最后, 應(yīng)當(dāng)從合法配件中選擇能夠被CRA利用的配件, 選擇過程和3.1節(jié)中介紹的基本一致, 區(qū)別在于對配件類型的劃分。GWT+CFI包含的配件類型有功能配件、調(diào)度配件、系統(tǒng)調(diào)用配件、NOP配件、普通代碼, 同時引入了合法配件和非法配件的概念, 如圖3所示。

      圖3 GWT+CFI中配件類型的分類Figure 3 The Gadget Types in GWT+CFI

      需要注意的是間接 jmp指令在相同的函數(shù)內(nèi)部能夠任意位置跳轉(zhuǎn), 且并不違背粗粒度 CFI中關(guān)于控制流轉(zhuǎn)移的策略。攻擊者能夠利用這一點在函數(shù)內(nèi)部找到除Call-Preceded或Entry-Point配件之外的合法配件, 因此對于包含 jmp指令函數(shù)內(nèi)部的配件尋找過程應(yīng)當(dāng)按照 GWT框架中的算法, 而不是GWT+CFI框架中合法配件的尋找算法。

      4 實現(xiàn)細節(jié)

      4.1 配件尋找過程

      本節(jié)內(nèi)容主要介紹GWT和GWT+CFI的配件尋找過程, 此過程能夠找到并確定所有可能配件的類型和長度, 分為四步, 可用過程2描述如下:

      過程2. 配件尋找過程

      步驟一: 利用二進制分析工具IDA pro編寫腳本找到程序中所有的間接轉(zhuǎn)移指令(配件的結(jié)尾), 另外在GWT+CFI框架中, 還要找到所有的Call-Preceded指令和函數(shù)入口指令(配件的開端)。

      FOR EACH(間接轉(zhuǎn)移指令){

      步驟二: 通過回溯的思想篩選出每一個可能的配件, 直到找到功能配件的最大長度為止。

      步驟三: 對步驟二中得到的每一個可能配件,利用Q[3]進一步得到配件的類型。

      步驟四: 獲取 NOP配件的最大長度, 這個值不能夠小于功能配件的最大長度。

      }

      END EACH

      我們基于Q[3]提出的算法判斷每個配件的類型。對于功能配件, 它往往包含一系列具有目的性的操作, 并且應(yīng)當(dāng)只完成 Q中定義的一種操作, 例如MoveReg, 算術(shù)邏輯運算等。識別功能函數(shù)的算法細節(jié)可以參考文獻[3], 核心思想是提取指令片段執(zhí)行前后的狀態(tài)變化(相關(guān)寄存器和內(nèi)存值的變化), 用先決條件公式判斷這些變化是否滿足某個配件類型的特征條件, 從而得出功能配件的具體類型。但是 Q中的原始算法僅僅能夠用來尋找以 ret指令結(jié)尾的ROP配件(Q開源的 ROP編譯器框架更新了對indirect-jmp、indirect-call, 和syscall的支持, 通過間接跳轉(zhuǎn)指令之前的代碼片段判斷該配件的類型), 因此我們需要添加新的特征模塊去尋找 GWT中定義的合法配件。

      如果一個配件被判斷是功能配件, 我們還需要進一步識別它是否屬于特殊的功能配件。如果它以syscall指令結(jié)尾, 則屬于系統(tǒng)調(diào)用配件。如果它以indirect-jmp指令結(jié)尾, 且配件中包含修改indirect-jmp目標(biāo)寄存器的指令操作, 則屬于調(diào)度配件。其他情況則屬于普通的功能配件。

      如果一個配件不屬于功能配件, 則它可能屬于NOP配件或者普通代碼。為了不改變CRA中配件鏈的原始語義, NOP配件應(yīng)該盡可能少的包含操作寄存器的指令。例如, 對于超長的配件, 如果該配件內(nèi)部操作簡單, 則該配件仍然會被當(dāng)作 NOP配件, 如果該配件的操作很復(fù)雜, 對寄存器的操作很多, 則認為該配件無法被攻擊者利用, 所以被認為是普通代碼。因此我們定義一個重要的變量MaxRegMod,表示NOP配件中修改寄存器的最大個數(shù)。如果一個配件修改寄存器的個數(shù)不超過我們定義的MaxRegMod, 則這個配件就屬于 NOP配件, 否則不屬于。需要注意的是, 在GWT中功能配件的優(yōu)先級要高于NOP配件, 即如果同一個配件同時屬于兩種類型, 那么應(yīng)當(dāng)首先考慮它屬于功能配件的情況。另外NOP配件和普通代碼的區(qū)分是比較模糊的, 使用MaxRegMod也只是一種折中的辦法, 并不能徹底將這兩類配件完全分開。但是對于當(dāng)前實際的攻擊, 我們認為GWT已經(jīng)基本滿足需求, 并且優(yōu)于其他基于配件長度的檢測[8-9]方法。

      GWT尋找功能配件和 NOP配件的方法不是一成不變的, 而是隨著配件分類地不斷完善, 尋找算法也會不斷優(yōu)化。例如, 文獻[21]提出了一種基于函數(shù)的 CRA, 使用整個函數(shù)作為一個配件, 這種思想能夠繞過許多防御機制, 包括基于 CFG的理想CFI[18]。因此, 我們能夠依據(jù)攻擊者使用新型配件的定義在GWT中構(gòu)建對應(yīng)的配件尋找算法, 以此來可能防御基于函數(shù)的CRAs。

      圖4表示GWT在程序中尋找配件的整個過程。第一, 找到一個間接轉(zhuǎn)移指令, 例如 ret指令; 第二,判斷配件的類型, 例如配件1包含兩條指令(push和ret指令), 因此它屬于一個普通功能配件(StoreMem),在添加標(biāo)記信息時則注明為功能配件。同樣, 配件2也是一個功能配件(ArithmeticStore)。配件3和配件2相比多了一條 pop指令, 但這條指令會改變當(dāng)前函數(shù)的棧布局, 對CRA產(chǎn)生一定的副作用, 因此配件3不屬于功能配件。但是, 配件3修改寄存器的數(shù)量為2, 如果我們設(shè)定變量MaxRegMod的值為6, 根據(jù)前兩段的描述, 則它屬于 NOP配件, 此時功能配件的最大長度就是3(配件2包含的指令數(shù))。隨著更多指令的回溯, 我們假設(shè)配件4和配件5修改寄存器的數(shù)量分別為6和7, 變量MaxRegMod的值依舊為6, 則配件4屬于NOP配件, 它的最大長度就是配件4包含的指令數(shù), 而配件 5因為修改寄存的數(shù)量大于我們設(shè)定的MaxRedMod, 所以它不屬于任何配件類型,可判斷為普通代碼。

      圖4 配件尋找示例Figure 4 An Example of Gadget Search

      在 GWT+CFI框架中, 除了考慮配件的結(jié)尾,我們還應(yīng)該找到配件的開端(例如圖4中的mov指令)。因此, 在GWT+CFI中, 只有配件5可能屬于某種類型配件。如果按照前面的假設(shè), 配件5不屬于功能配件也不是 NOP配件, 僅僅為普通代碼,則對應(yīng)的功能配件和NOP配件的最大長度就是無效的。

      4.2 程序標(biāo)記結(jié)構(gòu)

      權(quán)值標(biāo)記的結(jié)構(gòu)如圖 5所示, 使用 32位結(jié)構(gòu),包含 3個參數(shù): 配件類型、功能配件的最大長度、NOP配件的最大長度。其中, 配件類型占用 3個比特, 具體表示的含義和表1一致, 功能配件的最大長度占用14個比特, NOP配件的最大長度占用剩下 15個比特。

      圖5 權(quán)值標(biāo)記的結(jié)構(gòu)示意圖Figure 5 The Structure of Weighted Tagging for Gadget End

      我們利用圖 5中的標(biāo)記結(jié)構(gòu), 在可執(zhí)行程序的二進制文件中添加每個配件的標(biāo)記信息。如圖 4所示, 在每個間接轉(zhuǎn)移指令前添加一個32位的權(quán)值標(biāo)記, 包含以該間接轉(zhuǎn)移指令結(jié)尾的所有可能配件類型和相應(yīng)配件類型的最大長度。為了保證二進制文件的兼容性, 標(biāo)記結(jié)構(gòu)以一條預(yù)取指令為開端, 預(yù)取指令之后是加權(quán)配件的信息, 這和文獻[4,19]中的方法類似。因為我們假設(shè)系統(tǒng)支持 DEP技術(shù), 所以攻擊者無法篡改權(quán)值標(biāo)記的結(jié)構(gòu), 同時預(yù)取指令和標(biāo)記信息相鄰, 所以攻擊者也無法偽造虛假的權(quán)值標(biāo)記結(jié)構(gòu)。

      4.3 CRA檢測算法

      在程序運行時, 每執(zhí)行一條指令, 將配件的長度加一, 當(dāng)執(zhí)行一條間接跳轉(zhuǎn)指令時, 讀取對應(yīng)的配件標(biāo)記信息, 包括配件的類型和最大長度, 判斷當(dāng)前候選配件的真實類型。另外, 我們定義四個中間變量來計算CRA發(fā)生的概率, 分別是當(dāng)前配件的類型(Current Gadget Type, CGT), 當(dāng)前配件的長度(Current Gadget Length, CGL), 當(dāng)前配件的真實類型(Real Gadget Type, RGT), 以及CRA發(fā)生的概率因子(CRA Occurrence Index, COI)。

      運行時配件的真實類型RGT需要依據(jù)CGT和CGL來做出判斷。有關(guān)RGT的實現(xiàn)過程由算法1描述如下,MaxFunc表示功能配件的最大長度,Max-NOP表示NOP配件的最大長度。

      算法1. RGT的判斷

      輸入: CGT, CGL,MaxFunc, MaxNOP

      輸出: RGT

      IF (CGT = = Normal Code){

      RGT = Normal Code;

      }

      ELSEIF (CGT = = NOP Gadget){

      IF (CGL <=MaxNOP){

      RGT = NOP Gadget;

      }

      ELSE{

      RGT = Normal Code;

      }

      }

      //CGT=Functional/Dispatcher/Syscall Gadget

      ELSE{

      IF (CGL <=MaxFunc){

      RGT = CGT;

      }

      ELSEIF (CGL <=MaxNOP){

      RGT = NOP gadget;

      }

      ELSE{

      RGT = Normal Code;

      }

      }

      我們使用COI表示CRA發(fā)生的概率, COI越大意味著發(fā)生 CRA的概率就越大。COI的值由 RGT和配件對應(yīng)的權(quán)值決定, 詳細的過程如算法 2描述如下。除此之外, 我們定義變量MaxCOI, 表示 COI的最大值, 也是預(yù)先設(shè)定的閾值, 如果COI的值大于MaxCOI, 則我們認為發(fā)生了 CRA, 否則程序沒有異常行為。

      算法2. COI的判斷

      輸入: RGT,MaxCOI, RGT對應(yīng)的權(quán)值

      輸出: COI

      COI = 0; //initialization

      FOR EACH (間接轉(zhuǎn)移指令){

      IF (COI <=MaxCOI){

      IF (RGT = = Normal Code){

      COI = 0;

      }

      ELSE{

      COI = COI + RGT相應(yīng)權(quán)值;

      }

      }

      //COI >MaxCOI

      ELSE {

      exit(); // CRA發(fā)生

      }

      }

      4.4 硬件架構(gòu)

      關(guān)于GWT和GWT+CFI的硬件執(zhí)行架構(gòu)如圖6所示, 包含三個重要的硬件模塊: 控制流監(jiān)控器(Control-flow Monitor, CFM), 權(quán)值標(biāo)記配置(Weighted Tag Configuration, WTC), 以及CRA檢測模塊(CRA Detection Module, CDM)。另外, 我們假設(shè)基于策略的粗粒度CFI已經(jīng)集成在這個系統(tǒng)環(huán)境中。

      圖6 GWT和GWT+CFI的硬件執(zhí)行架構(gòu)Figure 6 The Hardware Implementation of GWT and GWT+CFI

      CFM 是監(jiān)控配件權(quán)值信息的主要模塊, 它記錄了程序運行時系統(tǒng)執(zhí)行的指令數(shù)(CGL)和當(dāng)前配件的類型(CGT)。當(dāng)一條間接轉(zhuǎn)移指令被執(zhí)行時, CFM根據(jù)算法1判斷RGT的內(nèi)容, 把RGT作為輸出結(jié)果的同時輸入CDM。CDM根據(jù)算法2計算COI的值,并比較COI和閾值MaxCOI的大小關(guān)系, 如果 COI的值大于MaxCOI, 則判定為發(fā)生了CRA, 發(fā)送一個例外并記錄攻擊日志。

      WTC主要負責(zé)存貯CFM和CDM使用的相關(guān)參數(shù), 例如MaxCOI和表 1中不同配件類型對應(yīng)的權(quán)值。由于這些參數(shù)具有靈活可配置的特性, 因此用戶能夠根據(jù)自身需求修改這些參數(shù), 例如, 若用戶要提高系統(tǒng)的安全性, 他們可以降低閾值MaxCOI, 或者提高配件的權(quán)值。相反, 若用戶要緩解GWT的限制, 他們可以增加閾值MaxCOI, 或者減少配件的權(quán)值。當(dāng)然, 攻擊者無法直接篡改存貯在WTC中的參數(shù), 因為我們規(guī)定參數(shù)的初始值設(shè)定之后無法在GWT運行時更改。

      5 實驗評估

      5.1 安全性分析

      因為GWT的硬件架構(gòu)非常簡單, 僅僅需要記錄配件的信息和計算 COI的值。因此, 為了簡化分析,我們利用著名的動態(tài)插樁工具Pin[22]來分析GWT框架的安全性。Pin是動態(tài)程序分析工具, 能夠?qū)γ織l指令的執(zhí)行進行監(jiān)控, 通過編寫 PinTools來模擬GWT硬件執(zhí)行的功能。關(guān)于測試樣例, 我們選擇Ubuntu系統(tǒng)目錄/bin和/usr/bin/下被用戶廣泛使用的程序。為了維護GWT框架的安全性和穩(wěn)定性, 我們設(shè)置重要參數(shù)MaxRegMod的值為6,MaxCOI的值為8, 不同配件類型對應(yīng)的權(quán)值和表1一致。

      因為GWT和GWT+CFI框架的主要不同在于配件的尋找過程, 而兩者對于CRA的檢測過程是一致的, 因此我們主要關(guān)注GWT框架的安全性分析, 而GWT+CFI和它是一致的。

      5.1.1 配件尋找過程

      在GWT框架中, 每個測試程序40KB的代碼空間中平均存在 1072個可能屬于配件的代碼片段(候選配件)。進一步分析不同配件類型的數(shù)量關(guān)系得出,功能配件、調(diào)度配件、系統(tǒng)調(diào)用配件, 以及NOP配件的平均數(shù)量分別為452、7、1.5, 以及612, 如圖7所示。另外, 每個程序中包含的所有候選配件的平均長度為9.9, 其中功能配件(包括調(diào)度配件和系統(tǒng)調(diào)用配件)的平均長度為5.3, NOP配件的平均長度為13.3,如圖8所示。

      在GWT+CFI框架中, 每個測試程序40KB的代碼空間中, 合法配件的平均數(shù)量是 471個, 相比較GWT基礎(chǔ)框架中候選配件的數(shù)量, 合法配件的數(shù)量大幅減少, 尤其是合法的功能配件。其中, 功能配件、調(diào)度配件、系統(tǒng)調(diào)用配件, 以及NOP配件的平均數(shù)量分別為45、0.9、0.15, 以及425, 如圖7所示。相反, 合法配件的平均長度為13.5, 要大于GWT中配件的平均長度。其中功能配件和NOP配件的平均長度分別為7.7和14.1, 如圖8所示。

      圖7 GWT和GWT+CFI中不同配件的平均數(shù)量Figure 7 The Average Number of Different Gadgets in GWT and GWT+CFI

      圖8 GWT和GWT+CFI中不同配件的平均長度Figure 8 The Average Lengths of Different Gadgets in GWT and GWT+CFI

      對于 GWT中的重要參數(shù)MaxRegMod, 即配件修改寄存器的最大數(shù)量, 同時也是劃分NOP配件和普通代碼的邊界閾值。顯而易見, 如果增加MaxRegMod的值, 候選NOP配件的最大長度也會隨之增加, 造成更多的普通代碼轉(zhuǎn)變?yōu)?NOP配件, 因此會一定程度上增加GWT的誤報率。我們改變參數(shù)MaxRegMod的初始化值, 重復(fù)前文過程2的配件尋找過程, 對測試集合中的程序進行靜態(tài)分析, 統(tǒng)計不同MaxRegMod值對應(yīng)的NOP配件的平均長度。實驗表明, 隨著MaxRegMod的增加, GWT和GWT+CFI中NOP配件平均長度的變化情況如圖9所示。盡管處理器中有很多寄存器, 但多數(shù)都有特定的用途, 僅僅只有 8個通用目標(biāo)寄存器(32位系統(tǒng))常常被使用, 因此當(dāng)MaxRegMod的值大于8時, NOP配件的平均長度幾乎不再改變, 這和圖 9顯示的實驗結(jié)果一致。另外由于NOP配件對CRA的貢獻不是很大, 也就是說 NOP配件并不具備實際的功能價值, 所以我們分配給它的權(quán)值為0, 因此適當(dāng)?shù)脑黾覯axReg Mod的值并不會影響GWT對CRA的檢測效果。

      圖9 GWT和GWT+CFI中NOP配件的平均長度Figure 9 The Average Lengths of NOP Gadgets in GWT and GWT+CFI

      5.1.2 實際的攻擊

      首先, 我們使用自動化工具Q[3]生成實際可被攻擊者利用的配件鏈, 然后針對已知的漏洞程序構(gòu)造CRA來檢測GWT框架的安全性。因為我們已經(jīng)提前標(biāo)記了目標(biāo)程序中所有的可能配件, 所以GWT能夠輕易檢測出由連續(xù)配件組成的 shellcode, 并記錄配件鏈中配件的權(quán)值信息。對于配件權(quán)值, 因為 Q主要生成以ret指令結(jié)尾的配件, 且配件類型都屬于GWT中的普通功能配件, 所以分配的權(quán)值均為 1。針對構(gòu)造的攻擊樣本和 Linux系統(tǒng)目錄 /bin 和/usr/bin/ 下一百多個常用程序進行實驗, GWT能夠成功檢測所有由Q生成的惡意配件鏈。

      其次, 我們使用手動構(gòu)造一些特殊的CRAs來試圖繞過GWT的防御, 以此檢測GWT的安全性。在GWT框架中, 識別功能配件的標(biāo)準(zhǔn)非常嚴格, 而識別NOP配件的標(biāo)準(zhǔn)則相對寬松, 因此我們精心選擇一些特殊的NOP配件(替代功能配件)構(gòu)造CRA。但是這些NOP配件可能會包含一些額外的操作, 因此構(gòu)造一個長的NOP配件鏈去做一些復(fù)雜的操作是非常困難的, 原因在于NOP配件可能會產(chǎn)生副作用。一個實際可行的攻擊方法是通過構(gòu)建簡單短小的配件鏈去關(guān)閉 DEP, 然后通過注入惡意代碼的方式完成復(fù)雜的攻擊目的。

      配件類型對應(yīng)的權(quán)值和變量MaxCOI是CRA檢測模塊的兩個關(guān)鍵參數(shù), 更大的權(quán)值分配和更小的MaxCOI能夠提供更高的安全性, 但同時也會造成系統(tǒng)高的誤報率, 因此我們應(yīng)當(dāng)選擇合適的參數(shù)值來平衡安全性和穩(wěn)定性的關(guān)系。我們改變參數(shù)MaxCOI的初始化值, 重復(fù) PinTools的插樁模塊, 依據(jù)第 4.3節(jié)CRA的檢測算法對測試集合中的程序進行動態(tài)分析, 統(tǒng)計不同MaxCOI值對應(yīng)的實驗數(shù)據(jù)。如圖 10和圖11描述了隨著MaxCOI值的變化, GWT中CRA檢測模塊查全率和誤報率的變化情況。MaxCOI的值變大, GWT判定發(fā)生CRA則需要更多的配件, 一方面, 因為由 Q 編譯器生成的配件鏈通常包含 20~40個配件, 所以我們設(shè)置MaxCOI的值小于20才能檢測由 Q編譯器生成的大部分配件鏈; 另一方面, 隨著MaxCOI的減小, GWT可能會誤判普通程序發(fā)生了 CRA, 例如一個普通程序陷入一個系統(tǒng)調(diào)用, 這個系統(tǒng)調(diào)用可能被識別為系統(tǒng)調(diào)用配件, 如果我們設(shè)置MaxCOI的值小于4, GWT則判定這個普通程序陷入系統(tǒng)調(diào)用的行為是惡意的CRA。

      5.1.3 檢測不同的CRAs

      圖10 GWT中CRA檢測模塊的查全率Figure 10 The Recall Rate of CRA Detection Module in GWT

      圖11 GWT中CRA檢測模塊的誤報率Figure 11 The False Positive Rate of CRA Detection Module in GWT

      我們提出的 GWT框架理想情況下能夠檢測多種不同的CRAs, 包括: 普通的ROP攻擊[1], 普通的JOP攻擊[14], 特殊配件構(gòu)造的各種 CRAs[13,16], 基于函數(shù)的 CRA[21], 非控制數(shù)據(jù)攻擊[18]。本文在理論的支持下探討GWT對多種CRAs的防御效果, 對前三種CRAs進行真實的實現(xiàn)和測試, 未來工作中會進一步尋找新型CRAs(基于函數(shù)的CRA和非控制數(shù)據(jù)攻擊)的特征, 測試GWT的防御效果和性能損耗:

      1) 普通的ROP攻擊

      普通的ROP攻擊是指以 ret指令為結(jié)尾的配件構(gòu)成的 CRA, 例如攻擊者使用自動化工具 Q生成ROP配件鏈, 因為我們已經(jīng)標(biāo)記了這些配件, 所以一旦ROP配件的權(quán)值總和大于MaxCOI, GWT就能夠輕松檢測。

      2) 普通的JOP攻擊

      普通的JOP攻擊是指使用indirect-jmp指令為結(jié)尾的配件構(gòu)成的 CRA, 它包含了普通的功能配件和調(diào)度配件, 而調(diào)度配件在GWT中會被分配很高的權(quán)值, 因此相比較ROP攻擊, GWT更容易檢測和防御JOP攻擊。

      3) 特殊配件的CRAs

      NOP配件 通常 NOP配件被用來繞過基于策略的粗粒度CFI[13,20]。在GWT中, 我們識別NOP配件, 并分配給它的權(quán)值為 0, 一方面, 在配件鏈插入NOP配件并不會減少功能配件的數(shù)量, GWT能夠檢測插入任何數(shù)量NOP配件的CRA。另一方面, GWT無法檢測全部由NOP配件組成的CRA, 但是全部使用NOP配件幾乎不可能構(gòu)造出復(fù)雜的攻擊過程, 也無法被自動化的工具生成。因此, GWT能夠檢測使用NOP配件來稀釋功能配件鏈的CRA, 同時不會受到NOP配件的誤導(dǎo)。

      系統(tǒng)調(diào)用配件 系統(tǒng)調(diào)用配件主要被CRA用來減少配件鏈的長度。如果我們設(shè)置MaxCOI的值為8, 系統(tǒng)調(diào)用配件的權(quán)值為4, GWT能夠檢測出執(zhí)行系統(tǒng)調(diào)用之前包含不少于4條功能配件的CRA。當(dāng)然我們也可以減小MaxCOI的值并增大系統(tǒng)調(diào)用的權(quán)值來檢測包含更少配件數(shù)量的CRA。

      其他特殊配件 如果攻擊者提出了一些新的配件類型來繞過現(xiàn)有的防御機制, 我們可以在GWT中添加這些特殊的配件并分配它們合適的權(quán)值, 例如文獻[16]提出了一種新的配件類型, 它能夠繞過基于不精確 CFG的細粒度 CFI, 稱之為間接函數(shù)調(diào)用的參數(shù)污染配件(Argument Corruptible Indirect Call Sites, ACICS), 包含一個間接調(diào)用指令和一個目標(biāo)函數(shù), 且目標(biāo)函數(shù)能夠在符合CFG的情況下執(zhí)行遠程代碼[16]。我們可以根據(jù)文獻中關(guān)于ACICS配件的描述, 在目標(biāo)程序中找到并標(biāo)記這類配件, 這樣 GWT就能夠檢測并防御使用ACICS配件的CRA。

      4) 基于函數(shù)的CRA

      基于函數(shù)的 CRA使用整個函數(shù)作為配件[18,21],它能夠繞過大多數(shù)的CFI方案。如圖12所示, 基于函數(shù)的CRA也需要調(diào)度配件來管理程序中能夠被利用的函數(shù)配件, 如果我們能夠找到并標(biāo)記這些調(diào)度配件, GWT就能夠檢測基于函數(shù)的CRA。不過要準(zhǔn)確區(qū)分普通程序和基于函數(shù)的CRA在調(diào)用函數(shù)時的不同特征, 正如圖 12所示, 如果程序僅僅調(diào)用單一目標(biāo)函數(shù), 則它屬于普通程序, 若連續(xù)調(diào)用許多不同函數(shù), 則它可能屬于 CRA, 例如我們應(yīng)當(dāng)標(biāo)記圖12中的test()函數(shù)為普通代碼而不是調(diào)度配件。

      圖12 基于函數(shù)的CRA和普通程序的對比Figure 12 The Comparison of Function-based CRAs and Normal Programs

      5) 非控制數(shù)據(jù)攻擊

      文獻[18]提出了一種控制流彎曲的新型 CRA,它結(jié)合了非控制數(shù)據(jù)攻擊的思想, 通過中轉(zhuǎn)函數(shù)繞過基于精確CFG的細粒度CFI。但是在GWT框架中, 我們可以標(biāo)記所有能夠被控制流彎曲利用的漏洞函數(shù), 這些函數(shù)中存在可被利用的功能配件, 例如printf(), fputs()。如果這些庫函數(shù)連續(xù)執(zhí)行的數(shù)量超過了MaxCOI, GWT就能夠檢測控制流彎曲攻擊。相反, 普通程序通常很少連續(xù)多次執(zhí)行這些庫函數(shù),另外, 控制流彎曲的攻擊也需要調(diào)度配件來管理這些中轉(zhuǎn)函數(shù), 所以我們標(biāo)記和監(jiān)控調(diào)度配件理論上也可以成功防御控制流彎曲攻擊, 方法類似基于函數(shù)的CRA。

      5.2 性能分析

      我們在配置為 CPU Intel x/E7-4820, 頻率2.5GHz,內(nèi)存類型 DDR3-1600, 大小 8G, 共享緩存16MB的服務(wù)器上安裝Ubuntu 16.04, 系統(tǒng)內(nèi)核版本4.4(x86)。我們通過運行硬件模擬器SimpleScalar, 實現(xiàn)了GWT和GWT+CFI的硬件架構(gòu), 如圖6所示。

      因為GWT和GWT+CFI框架的主要不同在于配件的尋找過程, 而兩者對于CRA的檢測過程是一致的, 因此它們在SimpleScalar中的功能實現(xiàn)可由過程3描述如下, 共添加代碼310余行。另外, 關(guān)于處理器參數(shù)的具體配置細節(jié)總結(jié)于表 2。我們從標(biāo)準(zhǔn)的SPEC CPU2006[23]中選取性能測試套件, 這些標(biāo)準(zhǔn)測試程序均通過GCC編譯器進行O3級優(yōu)化編譯。

      表2 處理器配置信息Table 2 The Configuration of Processor

      過程3. GWT和GWT+CFI在SimpleScalar中的邏輯實現(xiàn)

      sim-safe.c main():

      INITWTC()

      MD_FETCH_INST()

      IF(Indirect-Branch):

      THEN:

      INPUTstatic_result

      IF(EXIST):

      THEN:

      EXECUTECFM()

      ELSE:

      CONTINUE

      FI

      EXECUTECDM()

      IF(CRA):

      THEN:

      Exception()

      ELSE:

      CONTINUE

      FI

      ELSE:

      CONTINUE

      FI

      MD_SET_OPCODE()

      基于所有的測試套件, 比較程序在不同架構(gòu)(基本架構(gòu)和粗粒度CFI/GWT架構(gòu))上的運行時間, 從而得到性能開銷的具體數(shù)據(jù)。我們比較了 GWT, 粗粒度CFI, 以及GWT+CFI的性能開銷, 如圖13所示。因為 GWT已經(jīng)考慮了代碼長度策略, 所以粗粒度CFI只需要添加三條控制流轉(zhuǎn)移策略即可。實驗結(jié)果表明GWT的平均性能開銷只有2.31%, 最大不超過6%。GWT+CFI的平均性能開銷為3.55%, 最大不超過9%, 因為GWT+CFI不僅僅包含了GWT的性能開銷, 而且包括粗粒度CFI的開銷。由于GWT和粗粒度CFI的實現(xiàn)具有可以復(fù)用的部分, 例如GWT和粗粒度CFI都需要監(jiān)控和追蹤間接跳轉(zhuǎn)指令的運行,因此GWT+CFI的性能損耗要小于單獨GWT的性能損耗加上單獨粗粒度CFI的性能損耗。

      圖13 不同方法的性能開銷(歸一化為基礎(chǔ)環(huán)境)Figure 13 Performance Overheads of Different Methods(Normalized to the Baseline System)

      6 討論

      6.1 配件分類

      本文把配件主要分為三種類型: 普通代碼(無法被CRA利用的代碼片段)、NOP配件, 以及功能配件(包括調(diào)度配件和系統(tǒng)調(diào)用配件)。CRA使用功能配件完成穩(wěn)定且有用的操作, 使用NOP配件來繞過防御機制。配件的分類雖然簡單明了, 但準(zhǔn)確識別這些配件類型并不容易。

      我們使用基于Q的配件尋找算法來識別功能配件, 但Q識別配件的規(guī)則過于嚴格, 這使得攻擊者人工找到一些額外的功能配件成為可能。另外我們通過設(shè)置變量MaxRegMod來識別NOP配件, 但是攻擊者可能會構(gòu)造出只需要修改少量寄存器的特殊 NOP配件來繞過GWT。因此精確識別各種配件類型并不是很容易, 僅僅使用Q或MaxRegMod還無法做到精確識別各種配件類型。

      我們未來的工作會尋找更準(zhǔn)確識別功能配件、NOP配件, 以及普通代碼的方法。例如我們可用把NOP配件再進行細分, 分為短NOP配件, 中等NOP配件和長NOP配件。其中短NOP配件幾乎沒有額外的副作用, 不會影響功能配件的操作, 而長 NOP配件可能會帶來更多的副作用, 很難被 CRA利用,因此可以分別分配短NOP配件, 中等NOP配件和長NOP配件的權(quán)值為0.5, 0和–0.5, 通過對配件權(quán)值的調(diào)整增加GWT的安全性。

      6.2 靈活性分析

      GWT具有良好的靈活性和穩(wěn)定性, 因此未來我們可以對該框架進一步優(yōu)化和完善。

      1) 可擴展的配件尋找模塊

      隨著CRA技術(shù)的不斷發(fā)展, 新的攻擊方法和新的配件被研究者提出。例如, 最早的return-to-libc首先被提出, 接著新的方法 ROP[1], JOP[2]和基于函數(shù)的CRA[21]相繼被提出。配件也由基于ret指令的傳統(tǒng)配件發(fā)展為基于jmp指令, Call-Preceded指令和基于函數(shù)的新型配件。

      因為每提出一種新的CRA方法或配件類型都需要詳細描述如何使用或構(gòu)建它們, 所以我們能夠根據(jù)描述的細節(jié)在GWT中完善配件的尋找算法, 因此GWT能夠在程序運行時監(jiān)控新的配件并檢測新的CRA。本文已經(jīng)在GWT和GWT+CFI中添加了基于ret和jmp指令的配件, 以及合法配件的尋找算法。未來我們可以添加更多的配件(例如基于函數(shù)的配件)尋找算法以提高GWT的安全性。

      如今攻擊者廣泛使用自動化工具去尋找配件,因此在 GWT中也能夠重用自動化工具幫助我們尋找配件, 例如本文就是使用 Q的自動化框架去識別功能配件。同時所有被自動化工具生成的配件都可以通過GWT進行標(biāo)記, 也就是說, 我們的方法理論上能夠防御所有使用自動化工具生成配件鏈的CRAs。

      2) 可配置的初始化參數(shù)

      GWT使用到的參數(shù)例如MaxCOI,MaxRegMod以及配件對應(yīng)的權(quán)值, 都是可以重新配置的, 因此用戶能夠根據(jù)實際需求修改這些參數(shù)。參數(shù)配置對GWT的影響極大, 尋找合適的參數(shù)需要大量的實驗數(shù)據(jù), 而且根據(jù)現(xiàn)實環(huán)境的不同, 攻擊特征也會改變, 參數(shù)也應(yīng)該隨之調(diào)整。例如本文根據(jù)GWT的基本原理、前人工作和實際經(jīng)驗, 給出了參數(shù)配置的參考值, 并通過實驗驗證了參數(shù)配置的實際效果, 探討了參數(shù)配置對漏報率和誤報率的影響。另外, 如果我們發(fā)現(xiàn)新的配件類型, 可以在GWT中添加這些新配件, 并分配新的權(quán)值, 因此GWT能夠檢測多種CRAs使用的不同配件, 通過添加更多的配件類型可以提高GWT的安全性。例如本文在Q的基礎(chǔ)上添加了調(diào)度配件和系統(tǒng)調(diào)用配件, 這是兩種特殊的新型功能配件, 并為這兩類配件分配新的權(quán)值, GWT就能夠檢測和防御相應(yīng)的CRA。

      7 相關(guān)工作

      總結(jié)相關(guān)研究工作, 防御CRA的方法主要有兩種[42]: 基于隨機化思想的防御機制和基于控制流的指令檢查機制。

      基于隨機化的防御思想通過隨機化程序的代碼布局, 使得攻擊者無法找到配件, 也無法連接配件。地址空間布局重排(Address Space Layout Permutation,ASLP)[24]在函數(shù)級隨機化代碼布局, 指令布局隨機化(Instruction Layout Randomization, ISR)[25]在指令級隨機化代碼布局。但這些基于隨機化思想的防御方案都受到內(nèi)存泄露攻擊的威脅[26], 例如BlindROP[27]利用內(nèi)存泄露繞過細粒度的代碼隨機化。隨后, 也有文獻[28-29]進一步提高隨機化的熵值和粒度來抵御內(nèi)存泄露攻擊。

      Abadi等人[4,15]提出基于控制流完整性的防御思想, 即CFI。原始CFI具有較大的性能開銷, 因此研究者提出犧牲部分安全性來換取良好性能的實際方案, 主要分為兩類: 基于策略的CFI和基于CFG的CFI。

      相比原始CFI, 基于策略的CFI并沒有根據(jù)CFG驗證控制流的完整性。文獻[6-7]通過二進制重寫技術(shù)標(biāo)記所有間接轉(zhuǎn)移指令的可能目標(biāo)地址, 其實這些可能的目標(biāo)地址就是本文介紹的函數(shù)入口指令或call-preceded指令, 控制流轉(zhuǎn)移只能跳轉(zhuǎn)到這些可能的目標(biāo)地址, 否則中斷程序執(zhí)行。kBouncer[9]和ROPecker[8]利用 x86處理器中最近分支記錄(Last Branch Record, LBR)寄存器檢測程序中異常的控制流轉(zhuǎn)移, 但是這些方案都僅僅根據(jù)代碼片段的長度和控制流轉(zhuǎn)移策略去識別配件, 在GWT中, 我們同時使用配件類型, 轉(zhuǎn)移策略, 以及代碼長度來識別配件?;谂浼L度的檢測[8- 9]方法的最大缺點是安全性不夠, 配件長度和配件鏈的長度特征過于簡單, 攻擊者能夠比較容易地尋找特定配件來繞過防御。GWT增加配件類型和配件內(nèi)容作為配件的判斷依據(jù), 利用已有工具(如 Q)來判斷是否為功能配件,利用MaxRegMod來區(qū)分NOP配件和普通代碼, 比上述粗粒度CFI識別配件更加精確, 安全性更高。例如,一個配件包含多條NOP指令、一條運算指令和一條間接跳轉(zhuǎn)指令, 如果 NOP指令的數(shù)量較多, 則基于配件長度的檢測方法認為這不是一個配件。而GWT根據(jù)指令的具體內(nèi)容, 能夠判斷這是一個功能配件。粗粒度CFI的方案雖然容易實施, 但也容易繞過。先前的一些研究[10-13]通過使用合法配件的CRA對抗粗粒度 CFI, 但是在 GWT中, 我們已經(jīng)標(biāo)記了這些合法配件, 例如 call-preceded配件, entry-point配件和NOP配件, 所以GWT能夠檢測利用合法配件的攻擊手段。

      細粒度CFI則強調(diào)CFG的重要性, 基于編譯器的 CFI方案[30-33]能夠解決間接控制轉(zhuǎn)移的問題, 因為有源碼信息的支持, 所以能夠生成精確的 CFGs。SafeDispatch[34]通過插樁所有虛函數(shù), 嚴格檢查調(diào)用目標(biāo)是否合法, 以此防御虛函數(shù)調(diào)用的劫持攻擊[21]。前向(Forward-edge)CFI[35]不僅僅保護虛函數(shù), 它通過函數(shù)指針分析維護了一個可信代碼指針的列表,如果間接轉(zhuǎn)移目標(biāo)不在這個表中, 則中斷程序執(zhí)行。

      模塊化的CFI方案[36-37]則關(guān)注CFG的一部分。CCFI[38]利用消息認證編碼(Message Authentication Codes, MACs)加密控制流相關(guān)的返回地址, 函數(shù)指針和虛表指針。Per-InputCFI[39]根據(jù)每次具體的輸入內(nèi)容來完善CFG。上下文敏感的CFI方案[40]提出在二進制級別通過前向和后向的靜態(tài)分析加強上下文敏感的CFI策略。CFIMon[41]提出基于硬件支持的細粒度 CFI方案, 增加性能的同時也引出了高的檢測延遲。

      細粒度 CFI的安全性就在于如何構(gòu)造出精確且完善的 CFG, 但是幾乎不可能生成包含所有有效控制流路徑的理想CFG。文獻[17]提出由于上述細粒度CFI的缺陷, 導(dǎo)致基于 CFG的防御機制出現(xiàn)漏洞。Control Jujustu[16]提出的新型 CRA攻擊便是利用細粒度CFI無法生成理想CFG的缺陷, 構(gòu)造基于中轉(zhuǎn)函數(shù)的 ACICS配件, 在不違背 CFG的前提下完成CRA。然而, 如果把ACICS配件添加到GWT框架中, 我們的方法理論上能夠防御這類攻擊??刂屏鲝澢鶾18]表明理想的 CFI方案也存在一些問題, 利用內(nèi)存泄露漏洞和非控制數(shù)據(jù)攻擊思想就能夠合法調(diào)用標(biāo)準(zhǔn)庫中的函數(shù), 完成圖靈完備的攻擊。如果把這種基于函數(shù)的特殊配件類型添加到GWT框架中, 我們的方法理論上存在檢測控制流彎曲攻擊的可能。

      8 總結(jié)

      為了防御各式各樣的CRAs, 我們提出GWT的方法, 它是一種靈活, 低開銷且安全的防御框架。GWT通過靜態(tài)分析搜索并標(biāo)記程序中存在的所有可用配件, 然后在程序運行時動態(tài)監(jiān)控配件的權(quán)值標(biāo)記, 以此計算 CRA發(fā)生的概率。另外我們還提出GWT結(jié)合粗粒度 CFI的方法, 相比較基礎(chǔ)的 GWT而言, GWT+CFI能夠更精確發(fā)現(xiàn)代碼空間中存在的可用配件。我們基于軟件和硬件模擬的設(shè)計框架來實現(xiàn)GWT以及GWT+CFI系統(tǒng), 結(jié)果表明其平均性能開銷分別為2.31%和3.55%。GWT理論上能夠抵御使用各種配件的CRAs, 特別是使用自動化工具生成配件鏈的CRA。另外, GWT能夠添加更多的特殊配件類型, 設(shè)計更好的配件識別算法, 來進一步完善和優(yōu)化該防御框架。

      GWT識別功能配件、NOP配件和普通代碼的方法并不是完美的, 因此攻擊者可能會精心構(gòu)造出被GWT識別為 NOP配件但實際具有一定功能的特殊配件, 或者識別為普通代碼但實際屬于NOP配件的情況, 從而繞過GWT的防御。因此, 我們未來會提高GWT識配件類型的精準(zhǔn)性, 并且完善其它特殊配件(例如基于函數(shù)的配件)的尋找算法, 從這兩個方面進一步提高GWT的安全性。此外, 本文在攻擊威脅中存在過多的假設(shè), 主要是因為基于粗粒度 CFI的思想而不再考慮攻擊者使用非對齊配件的情況, 因此導(dǎo)致了完備性方面的不足。未來工作中, 我們會測試非對齊配件對GWT的威脅, 完善配件的尋找和識別算法。

      致 謝 在此向?qū)Ρ疚墓ぷ魈岢鲋笇?dǎo)的各位同門以及提出建議的評審專家表示感謝。

      猜你喜歡
      粗粒度控制流配件
      一種端到端的加密流量多分類粗粒度融合算法*
      原材配件
      抵御控制流分析的Python 程序混淆算法
      工控系統(tǒng)中PLC安全漏洞及控制流完整性研究
      電子科技(2021年2期)2021-01-08 02:25:58
      抵御控制流分析的程序混淆算法
      基于卷積神經(jīng)網(wǎng)絡(luò)的粗粒度數(shù)據(jù)分布式算法
      在線評論情感分析研究綜述
      基于公共池自適應(yīng)遷移策略的并行遺傳算法
      妝發(fā)與配件缺一不可
      Coco薇(2015年11期)2015-11-09 00:52:20
      基于控制流隱藏的代碼迷惑
      卢龙县| 札达县| 土默特右旗| 杂多县| 新昌县| 佳木斯市| 滕州市| 萨嘎县| 灵丘县| 凤阳县| 广丰县| 钟祥市| 蓬安县| 陕西省| 托里县| 肃南| 二连浩特市| 满洲里市| 津南区| 定西市| 兰州市| 建水县| 合山市| 安乡县| 文登市| 永嘉县| 元江| 水富县| 金溪县| 宣化县| 万山特区| 襄樊市| 原平市| 靖远县| 玉林市| 乌拉特前旗| 陇西县| 葫芦岛市| 长宁县| 二连浩特市| 陆河县|