那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

CFI的基本概念

Linux閱碼場 ? 來源:Linux閱碼場 ? 作者:Linux閱碼場 ? 2022-03-17 13:36 ? 次閱讀

偉林,中年碼農,從事過電信、手機、安全、芯片等行業,目前依舊從事Linux方向開發工作,個人愛好Linux相關知識分享,個人微博CSDN pwl999,歡迎大家關注!

目錄

1. 簡介

1.1 控制流攻擊歷史 1.2 CFI的基本概念 1.3 CFI發展歷史

2. Orig CFI

2.1 Windows CFG的實現

3. CCFIR

4. VTV

5. Kernel CFI

5.1 forward-edge protection CFI(Control-Flow Integrity) 5.2 backward-edge protection SCS(Shadow Call Stack) 5.3 Shared library support(Cross-DSO)

6. 利用硬件來提升CFI的效率

01 簡介

? CFI: Control-Flow Integrity(控制流完整性)

? CFG: Control Flow Guard(Windows的CFI實現)

? CFG: Control-Flow Graph(控制流圖)

? LTO: Link Time Optimization(鏈接時優化)

1.1 控制流攻擊歷史

控制流劫持是一種危害性極大的攻擊方式,攻擊者能夠通過它來獲取目標機器的控制權,甚至進行提權操作,對目標機器進行全面控制。當攻擊者掌握了被攻擊程序的內存錯誤漏洞后,一般會考慮發起控制流劫持攻擊。

●shellcode

早期的攻擊通常采用代碼注入(shellcode)的方式,通過上載一段代碼,將控制轉向這段代碼執行。

1fa4ebb0-8f13-11ec-952b-dac502259ad0.png

為了阻止這類攻擊,后來的計算機系統中都基本上都部署了NX/DEP(Data Execution Prevention)機制,通過限定內存頁不能同時具備寫權限和執行權限,來阻止攻擊者所上載的代碼的執行。

●Return2libc/ROP

為了突破DEP的防御,攻擊者又探索出了代碼重用攻擊方式,他們利用被攻擊程序中的代碼片段,進行拼接以形成攻擊邏輯。代碼重用攻擊包括Return-to-libc、ROP(Return Oriented Programming)、JOP(Jump Oriented Programming)等。研究表明,當被攻擊程序的代碼量達到一定規模后,一般能夠從被攻擊程序中找到圖靈完備的代碼片段。

1fba7020-8f13-11ec-952b-dac502259ad0.png

1fe772a0-8f13-11ec-952b-dac502259ad0.png

Return2libc/ROP利用return間接訪問,繞過了NX/DEP訪問。因為代碼并不會直接在堆棧上執行,而只是根據堆棧中的地址,間接跳轉到對應正常代碼段執行。

● DOP

DOP(Data Oriented Programming)攻擊。隨著防護技術的發展,針對控制流的攻擊變得愈發困難。而不通過劫持控制流,而是針對數據流來進行攻擊的方式,如Non-control data(非控制數據)攻擊雖然顯示出了其潛在的危害性,但目前對針對數據流的攻擊還知之甚少,長久以來該攻擊手段可實現的攻擊目標一直被認為是有限的。實際上,非控制數據攻擊可以是圖靈完備的,這就是DOP攻擊。

類似于ROP,DOP攻擊的實現也依賴于gadgets。但二者有以下兩點不同:

1、DOP的gadgets只能使用內存來傳遞操作的結果,而ROP的gadgets可以使用寄存器

2、DOP的gadgets必須符合控制流圖(CFG),不能發生非法的控制流轉移,而且無需一個接一個的執行。而ROP的gadgets必須成鏈,順序執行。

● CFI

為了應對這些新型的控制流劫持攻擊,加州大學和微軟公司于2005年提出了控制流完整性(Control Flow Integrity, CFI)的防御機制。其核心思想是限制程序運行中的控制轉移,使之始終處于原有的控制流圖所限定的范圍內。具體做法是通過分析程序的控制流圖,獲取間接轉移指令(包括間接跳轉、間接調用、和函數返回指令)目標的白名單,并在運行過程中,核對間接轉移指令的目標是否在白名單中。控制流劫持攻擊往往會違背原有的控制流圖,CFI使得這種攻擊行為難以實現,從而保障軟件系統的安全。

CFI從實現角度上,被分為細粒度和粗粒度兩種。細粒度CFI嚴格控制每一個間接轉移指令的轉移目標,這種精細的檢查,在現有的系統環境中,通常會引入很大的開銷。而粗粒度CFI則是將一組類似或相近類型的目標歸到一起進行檢查,以降低開銷,但這種方法會導致安全性的下降。

CFI對非控制數據的攻擊無能為力,但是這不妨礙我們詳細研究CFI的實現原理。

1.2 CFI的基本概念

了解CFI(Control-Flow Integrity),需要從CFG(Control-Flow Graph)講起。這里的CFG是基于靜態分析的用圖的方式表達程序的執行路徑(函數級別,非指令級別?):

2012f560-8f13-11ec-952b-dac502259ad0.png

CFI并不會檢測CFG中所有的邊,為了降低開銷受檢測的邊應該越少越好。因此在CFG中只考慮將可能受到攻擊的間接call、間接jmp和ret指令作為邊。

203a21e4-8f13-11ec-952b-dac502259ad0.jpg

如上圖,綠色的靜態控制流路徑并不易受到攻擊,紅色的動態控制流路徑容易受到攻擊。靜態路徑就是直接跳轉,動態路徑就是間接跳轉的路徑。

●直接跳轉和間接跳轉

直接跳轉指令的示例如下所示:

1| CALL 0x1060000F

在程序執行到這條語句時,就會將指令寄存器的值替換為0x1060000F。這種在指令中直接給出跳轉地址的尋址方式就叫做直接轉移。在高級語言中, 像if-else,靜態函數調用這種跳轉目標往往可以確定的語句就會被轉換為直接跳轉指令。

間接跳轉指令則是使用數據尋址方式間接的指出轉移地址,比如:

1| JMP EBX

執行完這條指令之后, 指令寄存器的值就被替換為EBX寄存器的值。它的轉換對象為作為回調參數的函數指針等動態決定目標地址的語句。

●前向轉移(forward)和后向轉移(backward)

204f6c84-8f13-11ec-952b-dac502259ad0.png

將控制權定向到程序中一個新位置的轉移方式, 就叫做前向轉移, 比如jmp和call指令。

而將控制權返回到先前位置的就叫做后向轉移, 最常見的就是ret指令。

將以上兩種分類方式結合起來:

前向轉移指令call和jmp根據尋址方式不同, 又可以分為直接jmp, 間接jmp,直接call,間接call四種。

后向轉移指令ret沒有操作數,它的目標地址計算是通過從棧中彈出的數來決定的。正因為ret指令的特性,引發了一系列針對返回地址的攻擊。

CFI(Control-Flow Integrity)關注的就是間接jmp、間接call、ret這幾種指令控制流的完整性。

1.3 CFI發展歷史

Control-Flow-Integrity這篇文章詳細的描述了CFI的發展歷史。

208daed6-8f13-11ec-952b-dac502259ad0.png

上圖是CFI技術發展的歷史路線圖,其中代表性的有四種CFI技術,下圖是這四種技術在各個維度的一個比較:

20a19716-8f13-11ec-952b-dac502259ad0.png

上圖,是各個CFI技術在安全性能四個維度的得分:

●一個是支持的控制流傳輸方案,比如前向后向、間接返回等等,用CF表示。

●二是性能數值,用1-10來區別,10為最高分,用RP來表示。

●SAP.F是對前向控制流的靜態分析精度,

●SAP.B是對后向控制流的分析精度。

02 Orig CFI

原始CFI技術都來源于這篇文章:Control-Flow Integrity Principles, Implementations, and Applications。

這種技術的思想就是在就是間接jmp、間接call、ret這幾種指令的控制流中插樁,在間接跳轉之前判斷跳轉地址是否合法。

20d03008-8f13-11ec-952b-dac502259ad0.png

用上圖來解釋,利用左側的代碼生成了右側的CFG控制流圖。其中的直接call路徑是不用關注的,針對間接call和ret指令的控制流路徑,插入代碼進行判斷:

1、在間接call和ret的目標地址插入一個獨有的label id。

2、在間接call和ret指令之前插入一段樁代碼,來檢查目的地址的id是否合法。合法才能間接跳轉,不合法則出錯返回。

3、還約定如果指向兩個目標地址的邊擁有相同的源集合的話,那么這兩個目標地址就是等價的,等價的目標用同一label表示。所以我們看到兩個相同的label 55和兩個相同的label 17。這就是一種粗粒度的CFI,它將多個不同的目標地址合在一起減少需要檢測目標地址的數量。為了降低性能開銷,是以犧牲安全性為前提的。

下圖是上述理論在x86上的一個具體實現:

20e084b2-8f13-11ec-952b-dac502259ad0.png

●原始狀態:ecx保存了目的地址,jmp ecx間接跳轉到目的地址執行

●插樁方式(a):首先在目的地址插入一個4字節ID 12345678h,然后在jmp跳轉前插入一段樁函數判斷,判斷目的地址的值是否為12345678h。不合法則出錯處理,合法則間接跳轉到[ecx + 4]地址執行原來的目的指令。

●插樁方式(b):在方式(a)的基礎上做了優化,首先在目的地址插入一個4字節的lable指令prefetchnta + 4字節ID 12345678h,然后在jmp跳轉前插入一段樁函數判斷,判斷[ecx + 4]地址的值是否為12345678h。不合法則出錯處理,合法則間接跳轉到[ecx]地址執行label ID指令。注意這里的技巧是判斷合法后,還是跳轉到ecx原地址,但是這時這個地址上存儲的是label ID指令,這條命令沒啥副作用,緊接著才會繼續執行原有的命令。

下圖是間接jmp、ret指令路徑,都被cfi插樁的情況:

20f3f736-8f13-11ec-952b-dac502259ad0.png

CFI確保運行時執行沿著給定的CFG進行,例如,保證典型功能的執行始終從頭開始,并從頭到尾進行。因此,CFI可以提高任何基于CFG的技術的可靠性(例如,增強現有技術以防止緩沖區溢出和入侵檢測[32,58])。下面介紹基于CFI的其他應用,內聯參考監視器IRM(Inlined Reference Monitors)、SFI(Software Fault Isolation)、軟件內存訪問控制SMAC(Software Memory Access Control),我們在此介紹它們。它還顯示了如何依靠SMAC或標準x86硬件支持來加強CFI實施。

下圖還展示了一個影子調用堆棧(shadow call stack)的原理,這是ret路徑上的另一種cfi保護形式:

210de268-8f13-11ec-952b-dac502259ad0.png

●shadow call stack 在 ret路徑上不再使用判斷id是否正確的方式,而是把返回地址在另外一個堆棧另存了一份,這樣棧溢出漏洞無法覆蓋,就算堆棧溢出但是函數還是返回到原來的調用位置。

●在函數調用前的時候,把返回地址備份到shadow call stack。

●在函數返回前,從shadow call stack中彈出備份的返回地址,廢棄掉原堆棧中的返回地址,這樣ret返回地址的安全性多了一層保障。

實現CFI,三個假設成立至關重要。這三個假設是:

● UNQ. 唯一ID:在CFI檢測之后,除了ID和ID檢查之外,選擇為ID的位模式不得出現在代碼存儲器中的任何位置。通過使ID足夠大(例如32位,對于合理大小的軟件)并且通過選擇ID使得它們不與軟件的其余部分中的操作碼字節沖突,可以容易地實現該屬性。

● NWC. 不可寫代碼:程序必須無法在運行時修改代碼內存。否則,攻擊者可能能夠繞過CFI,例如通過覆蓋ID檢查。除了在加載動態庫和運行時代碼生成期間,NWC在大多數當前系統中已經是正確的。

● NXD. 不可執行數據:程序必須不能像執行代碼那樣執行數據。否則,攻擊者可能會導致執行標有預期ID的數據。最新的x86處理器上的硬件支持NXD,Windows XP SP2使用此支持來強制分離代碼和數據[Microsoft Corporation 2004]。NXD也可以用軟件實現[PaX Project 2004]。NXD本身(沒有CFI)阻止了一些攻擊,但不適于那些利用預先存在的代碼的攻擊,例如“jump-to-libc”攻擊。

2.1 Windows CFG的實現

Windows利用以上思想建立了自己的CFI防護機制CFG(Control Flow Guard)。在Win10安全特性之執行流保護、繞過Windows Control Flow Guard思路分享等文章中有對CFG的實現原理進行過描述。

以win10 preview 9926中IE11的Spartan html解析模塊為例,看一下CFG的具體情況:

215ca8d0-8f13-11ec-952b-dac502259ad0.png

最終實際運行的CFG檢查函數為ntdll!LdrpValidateUserCallTarget(),其檢測過程如下:

1、首先從LdrSystemDllInitBlock+0x60處讀取一個位圖(bitmap),這個位圖表明了哪些函數地址是有效的。通過間接調用的函數地址的高3個字節作為一個索引,獲取該函數地址所在的位圖的一個DWORD值,一共32位,證明1位代表了8個字節,但一般來說間接調用的函數地址都是0x10對齊的,因此一般奇數位是不使用的。

2、通過函數地址的高3個字節作為索引拿到了一個所在的位圖的DWORD值,然后檢查低1字節的0-3位是否為0,如果為0,證明函數是0x10對齊的,則用3-7bit共5個bit就作為這個DWORD值的索引,這樣通過一個函數地址就能找到位圖中所對應的位了。如果置位了,表明函數地址有效,反之則會觸發異常。

對win CFG的防護思路沒有完全理解透徹,反正原理就是根據跳轉的目的地址去查bitmap表來確定是否合法。

03 CCFIR

在CFI被提出后過了很長時間都沒有被廣泛應用到實際生產中去,主要原因還是插樁引起的開銷過大。因此在2013年又提出了CCFIR,在同一年提出的還有binCFI,ModularCFI等等,但CCFIR是非常典型的一個實現。

與上面我們所講的機制將目標集合按照指向邊的源集合是否相同來劃分不一樣,CCFIR更加簡潔的將目標集合劃分為了三類:

所有的間接call和jmp指令的目標被歸為一類,稱為函數指針;

ret指令的目標被歸為兩類,一類是敏感庫函數(比如libc中的額system函數),另一類是普通函數。

下面我們以下圖中的例子來說明CCFIR的工作原理:

2195f2f2-8f13-11ec-952b-dac502259ad0.jpg

左邊是原始的控制流,右邊是CCFIR機制下的控制流。CCFIR提出了通過Springboard段(下方灰色部分)存放有效間接轉移目標的地址,在這段控制流中,5和3節點節點分別是call eax指令和ret指令這兩個間接轉移指令的目標地址,因此都會被存在Springboard段中。在程序執行到節點2’時,會檢測接下來的跳轉地址是否在Springboard段中,是則跳轉,否則出錯,從節點6跳轉到3也是一樣。

21ad8b56-8f13-11ec-952b-dac502259ad0.png

Springboard段的內存布局如上圖所示,通過將某一位設置成0/1來區分普通段和Springboard段。這樣在跳轉檢測時檢查某一個目標是否在Springboard段,只要檢測某一位的值就可以了。

再進一步擴展,由于目標地址主要被分為三類,那么這三類又可以通過幾位的不同來區分,如下圖。第27bit為0則表示是Springboard段,第3位為1則屬于函數指針,為0屬于ret地址,并通過26位區分是敏感函數地址還是普通函數地址。

21c675b2-8f13-11ec-952b-dac502259ad0.jpg

CCFIR的主要貢獻在于它降低了CFI機制的開銷,希望能將CFI投入實際使用中去。

04 VTV

2014年 Google 間接函數調用檢查(第6篇文章)。隨著對堆棧的保護越來越完善,出現了很多基于非堆棧的前向轉移攻擊,尤其是call指令。例如利用UAF漏洞覆蓋vtable指針等等。這篇文章的主要貢獻不是提出了什么新的機制,而是將CFI真正用到了生產編譯器中,僅針對于前向轉移。以下是主要工作:

Vtable Verification (VTV), in GCC 4.9,主要是對vtable調用進行檢測,VTV在每個調用點驗證用于虛擬調用的vtable指針的有效性。

Indirect Function Call Checker (IFCC), in LLVM。它通過為間接調用目標生成跳轉表并在間接調用點添加代碼來轉換函數指針來保護間接調用,從而確保它們指向跳轉表條目。任何未指向相應表的函數指針都被視為CFI違規。- - Indirect Function Call Sanitizer (FSan), in LLVM是一個可選的間接調用檢查器。

LLVM Clang Control Flow Integrity Design Documentation一文詳細的描述了Forward-Edge CFI for Virtual Calls的實現原理。

05 Kernel CFI

Linux 內核的代碼量比較少但是內核權限更大,一旦被攻擊會更加致命,所以kernel也需要擁有自己CFI防護方案。

在Andriod上google投入了大量精力來防止代碼重用攻擊(ROP),主要的防護思路是通過基于編譯器的安全緩解措施:

● 代碼重用攻擊(ROP)利用內核的常用方法是使用錯誤來覆蓋存儲在內存中的函數指針,例如存儲了回調函數的指針,或已被推送到堆棧的返回地址。這允許攻擊者執行任意內核代碼來完成利用,即使他們不能注入自己的可執行代碼。這種獲取代碼執行能力的方法在內核中特別受歡迎,因為它使用了大量的函數指針,以及使代碼注入更具挑戰性的現有內存保護機制。

●CFI 嘗試通過添加額外的檢查來確認內核控制流停留在預先設計的版圖中,以便緩解這類攻擊。盡管這無法阻止攻擊者利用一個已存在的 bug 獲取寫入權限,從而更改函數指針,但它會嚴格限制可被其有效調用的目標,這使得攻擊者在實踐中利用漏洞的過程變得更加困難。

Google 的 Pixel 3 將是第一款在內核中實施 LLVM 前端控制流完整性(CFI)的設備,已經實現了 Android 內核版本 4.9 和 4.14 中對 CFI 的支持。

Android 內核控制流完整性和CFI in Android Kernel Security介紹了Android下實現kernel CFI的大概情況。

Control Flow Integrity (CFI) in the Linux kernel和LLVM Clang Control Flow Integrity Design Documentation介紹了Kernel CFI的詳細實現原理。

5.1forward-edge protection

CFI(Control-Flow Integrity)

Kernel CFI 前向邊沿的防護。

1、將前向間接跳轉的目的地址搜集到一起組成一張表,在跳轉前判斷目的地址的合法性。因為合法的目的地址都是實際存在的函數,所以表的大小是有限的。當然也不會把所有的目的函數都集中到一張表里,會根據函數的原型把原型相同的函數搜集到同一張表中。

函數原型一致:

1| int do_fast_path(unsigned long, struct file *file)
2| int do_slow_path(unsigned long, struct file *file)

函數原型不一致:

1| void foo(unsigned long)
2| int bar(unsigned long)

220dfc5c-8f13-11ec-952b-dac502259ad0.png

如上圖根據google的研究統計,使用原型法來分類函數。LLVM 的 CFI 將 55% 的間接調用限制為最多 5 個可能的目標,80% 限制為最多 20 個目標。

因為linux kernel有時并未嚴格遵守函數指針和函數原型絕對一致的約定,所以在開啟CFI特性時需要修復這類問題。

2、在鏈接時進行間接調用目的函數表的分類和創建,以及調用前的插樁。這要求連接器具有LTO功能。

llvm的CFI模塊會用LTO來決定所有valid call targets,必須使用llvm的整體的匯編器來進行inline匯編,必須使用LTO-aware的鏈接器,比如說 GNU gold linker或者是llvm的ld。

下圖為LLVM的LTO原理簡介:

222588fe-8f13-11ec-952b-dac502259ad0.png

為了確定每個間接分支的所有有效調用目標,編譯器需要立即查看所有內核代碼。傳統上,編譯器一次處理單個編譯單元(源代文件),并將目標文件合并到鏈接器。LLVM 的 CFI 要求使用 LTO,其編譯器為所有 C 編譯單元生成特定于 LLVM 的 bitcode,并且 LTO 感知鏈接器使用 LLVM 后端來組合 bitcode,并將其編譯為本機代碼。

幾十年來,Linux 一直使用 GNU 工具鏈來匯編,編譯和鏈接內核。雖然我們繼續將 GNU 匯編程序用于獨立的匯編代碼,但 LTO 要求我們切換到 LLVM 的集成匯編程序以進行內聯匯編,并將 GNU gold 或 LLVM 自己的 lld 作為鏈接器。在巨大的軟件項目上切換到未經測試的工具鏈會導致兼容性問題,我們已經在內核版本 4.9 和 4.14 的 arm64 LTO 補丁集中解決了這些問題。

3、具體實例

實例的c語言代碼:(action()間接調用,可以調用do_simple()或者do_fancy())

223c49cc-8f13-11ec-952b-dac502259ad0.png

對應的匯編代碼如下:

224f2272-8f13-11ec-952b-dac502259ad0.png

開啟cfi保護以后的匯編代碼:

2269d3ec-8f13-11ec-952b-dac502259ad0.png

5.2

backward-edgeprotectioSCS(Shadow Call Stack

5.2 backward-edge protectioSCS

(Shadow Call Stack)

1f8c596a-8f13-11ec-952b-dac502259ad0.png

Kernel CFI 后向邊沿,使用影子調用堆棧的方式來防護。

● 方式1:專用寄存器用于單獨的返回堆棧:“影子調用堆棧”

x86已經不使用這種方式,因為它運行緩慢且存在競爭條件。arm64可以為所有影子堆棧操作保留寄存器(x18),陰影堆棧的位置需要保密。

22a4a044-8f13-11ec-952b-dac502259ad0.png

結果出現在兩個堆棧寄存器中:sp和未緩存的x18僅將來自影子堆棧(由x18指向)的返回地址(鏈接)寄存器的負載用于返回:

22baf90c-8f13-11ec-952b-dac502259ad0.png

● 方式2:使用專屬硬件完成(x86: CET, arm64:Pointer Authentication)

Intel CET: 基于硬件的只讀影子調用堆棧。在調用和退出指令期間隱式使用否則為只讀的影子堆棧。

ARM v8.3a Pointer Authentication (“signed return address”)。新指令:paciasp 和 autiasp。Clang and gcc: -msign-return-address。

以下是使用arm PA實現的硬件影子堆棧:

22ce446c-8f13-11ec-952b-dac502259ad0.png

5.3 Shared library support

(Cross—DSO)

因為內核是全解析的,所有不會有間接調用外部模塊的情況。在用戶態的共享庫中還有間接調用還是穿越DSO模塊。LLVM Clang Control Flow Integrity Design Documentation一文中詳細描述了這些技術的實現。

06 利用硬件來提升CFI的效率

我們相信上述設計可以在硬件中有效地實現。添加到ISA的一條新指令將允許以每次檢查更少的字節(更小的代碼大小開銷)執行前向CFI檢查(可能會更有效)。當前的純軟件檢測要求每個檢查至少32字節(在x86_64上)。硬件指令可能小于12個字節。這樣的指令將檢查參數指針是否入站且已正確對齊,并且如果檢查失敗,它將捕獲(在單片方案中)或調用慢路徑函數(跨DSO方案)。對于硬件實現而言,位矢量查找可能太復雜了。

注意,這種硬件擴展將補充被叫方的支票,例如。英特爾ENDBRANCH。而且,CFI將從ENDBRANCH具有兩個好處:a)精度和b)防止多態類型之間無效轉換的能力。

為了能夠在性能和防御方面取得更好的效果,一些研究著手于利用現有的硬件機制,來降低CFI的開銷。

Vasilis Pappas提出利用硬件性能計數器,在運行時觀察執行流的思路,該方法被稱為kBouncer[10]。他們利用LBR(Last Branch Register)來捕獲最近的16次跳轉信息。具體做法是在敏感系統調用處,對捕獲的16次跳轉進行安全性判斷,即return指令需要跳轉到調用點的后繼位置,indirect-call指令的目標是函數入口,其余跳轉指令目標基本塊長度不能全部少于20條指令。為了避免攻擊者利用庫函數調用來完成攻擊,文章在所有的庫函數調用點,來進行上述合法性檢查。為了驗證kBouncer的防御效果,作者對IE瀏覽器、Adobe Flash Player和Adobe Reader進行了實驗(利用已知安全漏洞,組織ROP payload攻擊這三種應用),實驗結果表明該方法能夠有效緩解ROP攻擊。同時,該方法的性能開銷低于~4%。

Yueqiang Chen等人設計了一種與kBouncer類似的方法,稱作ROPecker[11],也是利用LBR捕獲程序控制流的方式進行ROP攻擊監測。但不同之處在于判斷是否遭受ROP攻擊的邏輯和觸發監測的時機。1、判斷邏輯:在運行時檢測過去(利用LBR)和未來的執行流(模擬執行)中是否存在長gadget鏈(5個比較短的gadget),若存在,則認為這是一次ROP攻擊。Gadget信息是通過靜態分析二進制程序和共享庫得到的。2、運行時監測是事件驅動的,具體時機是調用敏感系統調用和執行流跳出滑動窗口觸發異常。ROPecker設計了一個滑動窗口,因為代碼本身具有時間和空間的局部性,但是gadget鏈卻是散列的,利用這一特性,系統保證該窗口內的gadget數目不足以構成一次ROP攻擊,窗口內的代碼設置可執行權限,窗口外的代碼不可執行,當執行流跳出滑動窗口時,便會觸發異常,進行運行時檢測。該方法利用代碼本身具有的時間和空間局部性,針對gadget鏈是散列的前提,提出了滑動窗口機制,使用事件驅動的檢測方法,具有較高的準確性和高效性。為了驗證該方法的安全性,ROPecker選取了有棧溢出的真實世界應用(Linux Hex-editer)進行攻防演練。實驗結果證明,ROPecker能夠有效的阻止ROP攻擊。同時,SPEC CPU2006 benchmark顯示了該方法的開銷非常低(~2%)。

Yubin Xia等人設計的CFIMon[12],也是采用性能計數器來捕獲程序執行流,并進行合法性判斷。但他們采用的是BTB(Branch Trace Buffer),來捕獲受保護程序運行過程中所有跳轉指令的信息。BTB與LBR不同之處在于,BTB可以把程序整個執行過程中所有的跳轉指令的歷史信息都記錄下來,LBR只能記錄16條。但是BTB需要CPU向指定的一個緩沖區內寫入跳轉信息,當緩沖區滿時,CPU會觸發異常交給操作系統處理(將緩沖區內容寫入文件中),LBR是循環的寄存器。使用BTB的程序性能明顯比LBR性能低。CFIMon檢查BTB的時機在兩個階段:一是當緩沖區滿時,操作系統將所有歷史信息寫入另一個進程,由另一個進程進行合法性判斷;二是當受保護進程執行敏感系統調用時,另一個進程也進行歷史信息的合法性判斷。合法性判斷主要檢查間接控制轉移的跳轉目標是合法目標集合內。如果所有間接控制轉移的歷史跳轉目標在合法目標集合中,認為當前受保護進程沒有收到攻擊;如果有至少一個間接控制轉移的歷史跳轉目標在合法目標集合中,那么認為受保護進程受到攻擊。合法目標的集合是在線下通過靜態分析獲得的,并且存儲在檢查進程中。

原文標題:CFI/CFG 安全防護原理詳解

文章出處:【微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

審核編輯:彭菁

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    31

    文章

    5363

    瀏覽量

    121192
  • 代碼
    +關注

    關注

    30

    文章

    4828

    瀏覽量

    69055
  • 數據流
    +關注

    關注

    0

    文章

    121

    瀏覽量

    14440

原文標題:CFI/CFG 安全防護原理詳解

文章出處:【微信號:LinuxDev,微信公眾號:Linux閱碼場】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    微帶的基本概念

    微帶的基本概念 如果說帶線可以看成是由同軸線演變而成的,那么,微帶則可以看成是雙導線演化而成的。 [/hide]  
    發表于 11-02 16:11

    Proteus涉及的基本概念

    Proteus涉及的基本概念
    發表于 08-01 20:58

    電子元件基本概念和原理

    電子元件基本概念和原理
    發表于 08-05 21:25

    Fpga Cpld的基本概念

    Fpga Cpld的基本概念
    發表于 08-20 17:14

    C語言基本概念

    C語言基本概念
    發表于 08-01 02:00

    數據結構的基本概念是什么

    數據結構之基本概念
    發表于 05-27 08:29

    阻抗控制相關的基本概念

    阻抗控制部分包括兩部分內容:基本概念及阻抗匹配。本篇主要介紹阻抗控制相關的一些基本概念
    發表于 02-25 08:11

    智能天線的基本概念

    1智能天線的基本概念 智能天線綜合了自適應天線和陣列天線的優點,以自適應信號處理算法為基礎,并引入了人工智能的處理方法。智能天線不再是一個簡單的單元,它已成為一個具有智能的系統。其具體定義為:智能
    發表于 08-05 08:30

    CODESYS的基本概念有哪些

    CODESYS是什么?CODESYS的基本概念有哪些?CODESYS有哪些功能?
    發表于 09-18 06:52

    微波基本概念

    1. 微波傳輸的基本概念,反射、傳輸和熱耗分別是受哪些條件影響;2. 電特性指標 駐波、插損、增益、隔離、耦合、噪聲等分別是什么含義。基本單位dB,dBm,dBc有什么區別。
    發表于 06-23 21:51

    電波的基本概念

    電波的基本概念電波傳播的幾個基本概念 目前GSM和CDMA移動通信使用的頻段為: GSM:890 --- 960 MHz, 1710 --- 1880 MHz CDMA: 806 --- 896 MHz 806 --- 960 MHz 頻率范圍屬超短波范圍
    發表于 12-05 15:32 ?12次下載
    電波的<b class='flag-5'>基本概念</b>

    照明常識基本概念

    照明常識基本概念 一、照明術語
    發表于 07-24 23:43 ?1577次閱讀

    無線定位基本概念與原理

    無線定位基本概念簡介,以及其原理分析
    發表于 11-11 18:01 ?147次下載

    通信原理的基本概念講解

    通信原理的基本概念講解。
    發表于 05-27 14:48 ?17次下載

    基本概念.zip

    基本概念
    發表于 12-30 09:21 ?2次下載
    百家乐官网关台| 大发888客服| 百家乐官网游戏机在哪有| 百家乐群b28博你| 网络百家乐官网的信誉| 大发888体育博彩| 百家乐策略详解| 百家乐官网风云论坛| 老虎百家乐的玩法技巧和规则 | 大发888宫网| 玩百家乐技巧博客| 真博百家乐的玩法技巧和规则| 娱乐网百家乐官网补丁| 足球竞猜| 百家乐任你博娱乐场| 粤港澳百家乐官网娱乐场| 桐庐棋牌世界| 稳赢百家乐的玩法技巧| 百家乐官网投注心态| 现金网注册| 百家乐单机版游戏下载| 百家乐官网路单显示程序| 易胜博官网| 澳门百家乐的玩法技巧和规则 | 海港城娱乐城| 赌百家乐的计划跟策略| 盐城百家乐官网的玩法技巧和规则 | 作弊百家乐官网赌具| 利来国际娱乐| 百家乐开户最快的平台是哪家 | 六合彩特码开奖结果| 上海百家乐的玩法技巧和规则 | 百家乐官网高手qq| 现金网注册送彩金| 电脑打百家乐怎么赢| 聚龍社百家乐官网的玩法技巧和规则| 百家乐官网在线怎么玩| 扬州棋牌中心| 巴西百家乐的玩法技巧和规则 | 雅加达百家乐官网的玩法技巧和规则 | 麻将百家乐筹码|