?

代碼重用攻擊與防御機制綜述

2016-02-20 03:23
信息安全學報 2016年2期
關鍵詞:控制流防御機制攻擊者

柳 童 史 崗 孟 丹

?

代碼重用攻擊與防御機制綜述

柳 童1,2史 崗1孟 丹1

1中國科學院信息工程研究所 北京 中國 1000932中國科學院大學 北京 中國 100049

由于C與C++等計算機程序中廣泛存在的漏洞, 攻擊者可以通過這些漏洞讀取或篡改內存中的數據, 改變計算機程序原有的執行狀態達到破壞的目的。為此研究者進行了不懈地努力并采取了一些卓有成效的保護機制, 例如數據不可執行與內存布局隨機化, 這些防御機制對于早期的代碼注入攻擊起到了極好的防御效果, 然而計算機系統的安全性依然不容樂觀。攻擊者在無法通過向內存中注入自己的代碼并執行的方式完成攻擊后, 開始利用內存中原有的代碼, 通過控制它們執行的順序來達到自己的目的, 這種攻擊方式稱為代碼重用攻擊, 它具有極大的威脅性, 能夠繞過多種現行的安全措施, 并成為攻擊者的主流攻擊方式。為此, 研究界針對代碼重用攻擊的研究也逐漸增多。本文簡述了代碼重用攻擊的起源, 攻擊實現的方式, 系統化地總結了現有的防御機制并對這些防御機制進行了評價。對代碼重用攻擊的根本原因進行了簡要的分析, 并提出了一種新的防御機制設計思路。

計算機系統安全; 內存攻擊; 代碼重用攻擊

1 引言

計算機的使用在當代社會已經普及到工業、教育、醫療、金融、軍事等各個行業。然而, 針對計算機系統的攻擊也數不勝數, 造成的損失數以億計。這是由于在C與C++等計算機程序中普遍存在漏洞, 例如能夠對內存的直接存取; 對用戶的輸入沒有自動的邊界檢查機制, 以及對已經釋放的指針再利用等[1]。使攻擊者能夠利用這些漏洞通過溢出沒有邊界檢查機制的緩沖區來注入惡意代碼并篡改內存的函數返回地址, 改變程序控制流使注入的代碼得到執行[2], 這就是最早的代碼注入攻擊。在此之上又發展出了整數溢出、格式化字符串溢出等攻擊方式, 實現原理基本相同。計算機系統安全機制的設計者針對這種攻擊方式采用了許多卓有成效的防御機制, 例如數據不可執行(Data Execution Prevention , DEP)[3-5], 它將原有在內存中無差別存儲的內容分為數據段與代碼段, 并劃分了不同的權限: 數據不可執行, 代碼不可修改。這使攻擊者以溢出緩沖區等形式注入的惡意代碼不會再被允許執行, 從而抑制了代碼注入攻擊。

然而這些漏洞仍然在被利用。近年來, 另一種攻擊方式開始興起。一些攻擊者開始利用程序在內存中原有的代碼, 通過利用漏洞改變它們的執行順序來達到攻擊的目的, 這就是所謂的代碼重用攻擊(Code-reuse Attack)。從最早的Return-to-Libc攻擊[6,7]逐漸發展出了ROP(Return Oriented Programming)[8,9]、JOP(Jump Oriented Programming)[10]等攻擊方式。這些攻擊方式依然能夠達到與傳統的代碼注入攻擊相同的攻擊效果, 能夠使攻擊者執行任意代碼。因此目前對于計算機系統安全性的保護依然不容樂觀, 研究界對于代碼重用攻擊的防御提出了各種各樣的安全機制, 然而都存在安全性或性能、兼容性缺陷, 無法達到令人滿意的效果。本文對代碼重用攻擊的實現機制與主要方法進行了概述, 并對針對代碼重用攻擊的防御機制的實現與存在的問題進行了詳細的介紹。在分析了代碼重用攻擊的根本原因基礎上提出了一種新的針對代碼重用攻擊的防御機制設計思想。

本文結構如下: 第二部分對代碼重用攻擊的實現機制與國內外研究界當前對于代碼重用攻擊的研究現狀進行了概述; 第三部分和第四部分分別對當前主流的防御機制兩大設計思想進行了綜述; 第五部分對這些防御機制進行了總結并提出了一種全新的能夠提高計算機系統安全性的安全機制設計思想; 第六部分對全文進行總結。

2 代碼重用攻擊概述與國內外研究現狀

代碼注入與代碼重用都屬于對計算機系統漏洞進行利用的攻擊方式。他們的區別在于攻擊者執行惡意代碼的方式, 前者通過直接向內存中注入惡意代碼并執行; 后者利用內存中原有的代碼, 通過篡改控制指令執行的數據, 改變了指令原有的執行順序, 使其按照攻擊者的意志執行, 達成攻擊目標?,F有的安全機制, 例如數據不可執行(DEP), 對代碼注入攻擊起到了極大的抑制作用。因此, 代碼重用攻擊得到了攻擊者的青睞, 成為目前攻擊方式的主流, 它能夠繞過現行計算機系統的大部分安全機制。目前代碼重用攻擊有Return-to-Libc、ROP、JOP等具體形式。

2.1 Return-to-Libc攻擊

若攻擊者能夠獲悉程序所使用的庫函數的地址, 便可以用其地址來覆蓋程序中某個函數的返回值, 并將調用庫函數所需要的參數以正確的順序添加至覆蓋區內, 這樣程序在該函數返回后就會執行相應的庫函數, 例如調出一個shell。這種攻擊方式能使攻擊者可以使用任意的參數調用內存中任意的庫函數[11,12]。

雖然Return-to-Libc攻擊能夠達成上述的效果, 但在使用上還是有局限性, 不屬于圖靈完備的攻擊方式[9], 原因有兩點: 一是在Return-to-Libc攻擊中, 攻擊者能夠一個接一個調用任意的庫函數, 然而這仍然只能允許他執行原有的線性代碼, 無法滿足進行任意行為的需求; 二是攻擊者只能夠調用已經加載到內存中的庫函數, 它們功能有限, 因此限制了攻擊者的能力。

然而也有證明Return-to-Libc攻擊的圖靈完備性的成果[13], 通過傳統Return-to-Libc中利用的函數產生的副作用完成特定的操作。找出那些副作用可用的函數來作為執行某項功能的函數配件。再利用與下文講述的ROP攻擊相同的原理將這些函數串聯起來, 完成圖靈完備的攻擊。

2.2 ROP(Return-Oriented Programming)攻擊

OP是在Return-to-Libc攻擊的基礎上逐步發展起來的, 能夠實現任意程序行為(圖靈完備)的攻擊方式[9]。ROP攻擊與函數調用和返回機制有極大的聯系。以x86架構程序為例, call與ret指令在程序的執行過程中總是一一對應的。在執行call指令時, CPU會將call指令的下一條指令地址壓棧作為返回地址, 然后跳轉到call所指示的位置。在ret指令執行時, CPU會自動將預先保存在棧中的返回地址彈給eip寄存器, 繼續執行原有call指令之后的指令。這個操作不會對call的下一條指令的正確性進行檢查或保障。ROP攻擊就是利用了這種缺陷。如圖一所示, 首先在原有代碼中搜索一些短小的指令序列, 這些序列都能完成一定的功能, 例如運算或賦值, 然后以ret指令為結尾, 稱為配件(gadget)。攻擊者依據要執行的配件的順序與所需的參數, 將這些配件的地址與參數進行拼接, 構建一條配件鏈(gadget chain)。并通過棧溢出漏洞將這條配件鏈注入到棧中覆蓋當前或其他某個函數的返回地址。一旦返回地址被覆蓋的函數返回, 那么CPU就會按照棧中攻擊者存放的配件地址鏈進行跳轉, 不斷的從一個配件返回并跳轉到下一個配件執行[14]。ROP攻擊極為靈活, 在發展演變的過程中出現了許多變種與新的實現方式, 并配合內存泄露攻擊, 能夠繞過多種專門針對它的防御機制[15-17]。

圖1 ROP攻擊模型

2.3 JOP(Jump-Oriented Programming)攻擊

JOP攻擊采用與ROP類似的配件鏈來實現攻擊, 但不依賴棧完成對程序流的控制[10]。如圖二所示, JOP采用以jmp指令為結尾的配件。將配件地址鏈保存在另外一塊任意數據區中, 稱為調度表(dispatch table), 采用了一個專門的配件作為一個指向調度表的指針, 稱為調度配件(dispatcher), 類似于普通程序的eip指針, 它對某個寄存器進行已知操作, 例如自增, 然后跳轉到這個寄存器指示的地址。其他所有的能夠完成特定功能的配件在最后都跳轉到調度配件。而在ROP攻擊中, 配件執行的控制序列是以配件地址鏈的形式存儲在棧上的, 利用棧指針來指向配件。與ROP相同, JOP攻擊的實現也是需要指令序列的, 這些序列就是配件的地址, 但由于采用了調度配件, 配件地址序列可以存放在內存的任何可讀寫區域, 而不是必須在棧上。這就給了攻擊者更大的靈活性和空間。他們可以將配件鏈放置于內存中任意一塊可寫的數據區。

2.4 其他類型代碼重用攻擊

除了上述三種常見的代碼重用攻擊之外, 有研究者和黑客也相繼提出了其他類型的代碼重用攻擊。

SROP[18]利用類UNIX操作系統用進程棧保存信號幀的機制, 通過偽造信號幀來引導進程進入到攻擊者設定的代碼區域中執行實現攻擊目的。

COOP[19]利用了C++面向對象編程的特性, 利用篡改類中的虛函數表來使一系列虛函數按照攻擊者設定的順序執行完成攻擊目標。

2.5 國內外研究現狀

由于代碼重用攻擊具有極強的破壞性, 極高的靈活性, 能夠繞過現行的絕大多數防御機制。已經漸漸成為黑客進行攻擊的主要手段。研究界對于代碼重用攻擊防御機制的研究也得到極大的重視。

在2011-2015年間S&P (IEEE Symposium on Security and Privacy)、CCS(ACM Conference on Computer and Communications Security)以及Usenix (Usenix Security Symposium)安全方面世界三大頂級會議對于代碼重用攻擊的相關論文發表數量如圖三所示, 可以看出, 對于這類攻擊的研究與防范逐漸成為研究界的重點。

代碼重用攻擊的實現需要兩大重要環節, 一個是控制流的劫持, 另外一個是對內存中的代碼位置的獲悉。首先得到內存中的代碼位置, 構建控制程序執行的配件地址鏈, 而后通過對溢出漏洞將配件鏈注入到內存的數據區中, 最后劫持控制流使得程序按照攻擊者注入的配件順序執行。因此防御措施也就分別針對這兩個重要環節, 監測程序的異常行為與增加程序的不可知性。

攻擊者在實行代碼重用攻擊時, 要實現惡意的功能, 勢必改變原有程序的執行路線, 因此研究者通過添加一些監控機制對這種改變做出偵測用以判斷代碼重用攻擊的發生。

實現代碼重用攻擊的另外一個要素是對內存中程序指令位置的精確知曉, 由于攻擊者已經無法注入自己的代碼, 因此只能使用內存中原有的代碼, 他們通過選擇配件, 并精心構造配件地址鏈用來控制這些配件的執行實現自己的惡意目的。因此研究者通過增加內存的不可知性來阻止攻擊者得知內存中代碼的布局, 使其無法構造配件鏈。

3 基于程序異常行為監測的防御機制

目前的針對程序異常行為的監測防御機制中, 大致分為兩種方法, 一種是對ROP/JOP攻擊中配件出現頻率的監測; 另一種是對程序控制流正確性的保障與監測。

3.1 對于配件出現頻率的檢測

研究者在觀察代碼重用攻擊(這里以ROP攻擊為例)發生時的程序行為時發現, 發生ROP攻擊的程序行為與正常程序行為有著明顯不同。在ROP攻擊的過程中, 攻擊者通過將許多以ret指令為結尾的配件連接起來完成攻擊, 這些配件大都較短, 在一定長度以內, 當ROP攻擊發生時程序指令流中會出現大量ret指令。因此監測一段指令當中ret指令出現的頻率, 就成為了一種監測ROP攻擊的方式。然而這種方式只能對ROP攻擊產生效果, 無法防御Return-to-Libc攻擊。

Pappas等人[20]利用Intel處理器中自帶的LBR (Last Branch Recording)機制來對程序中的間接跳轉進行檢測, 保證所有的ret指令返回目標指令都位于一條call指令之后, 這種方式可以防御簡單的Return-to-Libc與ROP攻擊; 利用對LBR中存儲的跳轉指令的地址進行分析, 分析這些地址之間的緊密程度來判斷是否出現了一串以ret為結尾的配件鏈, 從而判斷是否出現了ROP攻擊。Cheng[21]等人采用了相同的對配件鏈的檢查思路, 并采取了對于間接跳轉更為頻繁和嚴格的檢查。Pappas[20]等人與Cheng[21]等人都采用了對配件的出現頻率進行監控的方法, 通過比對遭到攻擊的程序與正常程序之間的差別來監測攻擊的發生。具體涉及到兩個變量: 被認作是配件的指令序列長度Lg和被認作ROP攻擊發生的配件連續出現的次數Lc。通過改變這兩個變量可以提高或降低ROP攻擊檢測的敏感程度。

這種方式存在的問題是無法確定檢查的敏感度。假如提高敏感度, 那么有可能正常的程序也會被判定發生ROP攻擊, 使假警報劇增; 假如降低敏感度, 則ROP攻擊就有可能逃過監測。如何選擇Lg和Lc對是需要解決的問題。更嚴重的是, 目前有些攻擊者已經能夠找到一些長配件, 這些長配件的長度大于被系統認作ROP配件的長度, 并把這些配件加入到實施ROP攻擊的配件鏈中, 就可以完全逃過這種防御機制的監測[15,16,22]。

總體來說, 這種監測思想存在較大的繞過可能性, 無法有效滿足目前的安全需求。

3.2 基于保障控制流完整性思想的防御機制

類比與對配件出現頻率進行監測的方法, 保障間接轉移指令目標地址的正確性是目前更為有效的方法, 這里需要指出的是, 轉移指令分為直接轉移和間接轉移兩大類, 直接轉移指令的目的地址是在編譯鏈接階段就已經確定并寫入二進制代碼中的, 在程序運行時無法更改; 間接轉移指令在運行時對具體的寄存器或內存進行間接尋址, 這些間接轉移指令的目標可能是動態變化的, 因此存在被攻擊者篡改并劫持的可能性, 故所有保障控制流完整性的機制都是針對間接轉移指令的。

3.2.1 細粒度CFI的最早提出與探討

文獻[23]是最早提出保障控制流完整性(Control- Flow Integrity,CFI)思想的文章, 首先將要執行的代碼進行靜態分析, 畫出控制流圖, 預先計算出所有的間接轉移指令的可能的目標地址, 并為之配唯一的ID。改寫程序的二進制代碼, 在每一條間接跳轉指令執行之前增加檢查邏輯, 一旦出現違反控制流圖的間接跳轉就會報錯并終止程序。這種為每一個轉移目標地址分配唯一ID的實現思想我們稱之為細粒度CFI。它在被提出時被認為具有極佳的安全性, 能夠檢測出任何代碼重用攻擊并使用純軟件方式實現, 得到了研究界廣泛的重視與探討, 并出現了不少具體的實現方案。

XFI[24]利用CFI思想保證控制流的正確性, 并結合了其他例如內存訪問控制, 影子棧等機制, 將傳統的應用程序包裝成XFI模塊, 在運行時提供保護與監控, 并通過設置外部接口與操作系統交互。然而所有的應用程序都被封裝成塊, 則被設計用于共享的動態鏈接庫就無法使用, 導致運行時內存有一定的空間損耗。

Hypersafe[25]是最早提出的對虛擬機監控器進行CFI保護的安全機制。其對監控器代碼進行分析, 對所有代碼指針的可能調用位置進行計算, 并維持指針索引表, 在每次指針解引用時查表, 若出現非法目標地址就會報錯。對返回地址采用類似的方法。但是只能對直接運行在硬件上的1類監控器進行保護, 在運行與宿主操作系統之上的2類監控器上無法實現。

文獻[26]是最早提出的基于智能手機平臺上的CFI實現方案, 針對蘋果公司的面向對象C語言并且應用程序加密存儲。對程序的二進制代碼進行解密, 反匯編, 繪制控制流圖再對二進制代碼進行改寫。而文獻[27]是屬于對其的改進, 在編譯器階段進行CFI設置, 提高了應用程序的靈活性。

上述文章都屬于對傳統CFI思想在不同平臺上的實現與應用, 沒有本質上的改進與創新。

在提出了近10年以后, CFI思想才在商業領域得到了初步的應用, 微軟公司提出了CFG (Control- Flow Guard)技術, 通過編譯器在編譯階段對代碼的分析。在程序運行時的每一個間接調用進行檢查, 看目標地址是否是一個函數的開頭[28]。這種方式不屬于傳統細粒度CFI思想并且對間接跳轉與返回指令沒有保護, 存在被繞過的可能。

細粒度CFI在提出之后之所以一直沒有得到廣泛的應用, 是由于其本身還存在不少問題, 比如:

1. 針對諸如內核程序上百萬行的代碼, 以及其他的大規模的程序, 如何精確的畫出其控制流圖, 仍然是一個亟待解決的問題。

2. 傳統的細粒度CFI要求在程序載入內存之前需要對所有的程序模塊進行分析并重寫二進制代碼加入檢查指令, 包括動態鏈接庫, 那么每個程序就只能在載入時帶著它們自己重寫好后的庫了, 無法與其他的程序共享, 這與動態鏈接庫的設計初衷相悖[29]。

3. 純軟件的CFI實現方式性能損耗較高。在20%至50%左右[23]。

針對細粒度CFI存在的這些性能與實現上缺陷, 研究界也進行了許多探討與改進。

文獻[29]針對經典CFI[23]對動態鏈接庫無法支持的缺陷, 將ID與地址綁定存在另外一塊內存區中。建立兩個表, 一個映射間接轉移指令地址與其ID, 稱為分支表; 另一個表映射各個ID的轉移指令的合法目標地址, 稱為目標表。對每一個間接轉移指令, 分別查兩個表, 根據指令自身地址在分支表中查其ID, 再在目標表中根據轉移指令的目標地址查ID, 若匹配, 說明通過。若不匹配則報錯。經典CFI要求一次性畫出全部程序的CFG, 但是該方法將程序分為多個模塊, 分別為每個模塊畫出CFG, 在加載多個模塊運行時, 就會將各個模塊的CFG合并。這種運用ID表的方式方便動態的添加與維護。能夠較好的解決傳統二進制代碼改寫的無法兼容共享庫的缺陷。

文獻[30,31]針對傳統CFI使用純軟件實現導致損耗高的缺點, 使硬件層次對上層的CFI機制進行支持, 添加了關于CFI檢查的指令以替代傳統的軟件實現, 能夠大大縮減代碼指令長度并減小了性能損耗。但這種方式會使兼容性降低, 沒有進行硬件修改的硬件無法對上層代碼進行CFI支持。

文獻[32]將沙箱處理的相關技術與CFI進行組合, 對CFI繁瑣的檢查機制進行整合簡化, 提高了CFI檢索的速度, 降低了性能損耗。

文獻[33]將CFI在編譯器層次上實現, 對C++中的虛函數表進行保護, 采用靜態分析, 對虛函數表進行分析, 對目標碼進行修改, 在調用虛函數之前加入一個驗證函數進行確認。該方法在一定程度上提高了CFI的兼容性并減少了性能損耗。但是僅僅能夠對通過函數指針進行的函數調用進行保護, 無法對運行時的棧、堆等數據結構進行保護。

3.2.2 粗粒度CFI的提出與否定

針對經典的細粒度CFI實現較困難, 損耗較高的缺陷。學界提出了一類簡化版的CFI實現方案。它們通過犧牲一定安全性來達到可以接受的性能損耗與實現難度。與先前的細粒度CFI相比, 這些實現方案都不需要畫出程序的控制流圖, 可以稱之為粗粒度CFI。

CCFIR[34]重寫目標碼, 收集所有合法的跳轉指令目標地址并將其以隨機序存儲于一塊獨立的安全內存中, 強制所有的間接跳轉指令只能通過這個內存區域完成控制流的轉移。CFIMon[35]通過靜態分析得出合法的跳轉地址, 并利用處理器中的分支追蹤存儲機制(LBR等)來實時分析控制流的完整性。文獻[36]將間接轉移指令替換為到一個外部處理程序的直接跳轉, 并維持一個合法跳轉表, 每次間接跳轉, 處理程序會查這個表, 只有在表中的目標地址才能作為這個間接跳轉的目的地。文獻[37]首次將CFI思想在操作系統內核上實現。改寫操作系統代碼, 加入檢查邏輯。文獻[38]采用靜態分析與動態監測相結合的方式檢查間接跳轉指令的目標是否位于合法函數區間。

上述幾種方法雖然實現方法各異, 但是他們都有一個共同的特點, 就是不需要畫出程序詳細的控制流圖并且對于間接跳轉目的地址不需要分配唯一ID。僅僅是對程序進行靜態分析, 根據一定的規則找到合法的跳轉地址, 例如, 所有的ret指令的合法目標都是一條call指令下一條指令; 所有的間接調用目標地址都必須是一個函數的開頭。這就導致任意間接轉移指令與他們可能的目標地址之間不再遵從邏輯上的一對一關系, 而是一對多。一條ret指令可以返回到任意一個call指令的下一條指令, 而不必是原本的調用者; 一條call指令可以進入任意一個函數的開頭, 而不用根據邏輯進行判定究竟應當跳轉到哪一個函數的開頭。

粗粒度CFI這種對間接跳轉目標地址不加以再區分的管理方式, 導致了攻擊者能夠通過精心設計的配件, 組合配件鏈, 能夠做到繼續實施代碼重用攻擊[16,39]。具體使用的配件特點如下: 一種配件以一條call指令的下一條指令為起始, 以ret指令為結尾, 這種配件可以繞過粗理度CFI對ret指令必須調到調用點的檢查機制; 另一種配件是以一個函數開頭為起始, 以一個間接跳轉指令為結束的配件, 這種配件可以繞過粗粒度CFI對間接調用指令必須調到函數開頭的檢查機制。攻擊者將這兩種配件搭配使用, 就可以完全繞開粗粒度CFI的檢查完成攻擊。因此, 粗粒度CFI也被證明無法滿足安全需求而被研究界淘汰。

3.2.3 細粒度CFI安全性弱點的提出與改進

隨著研究界將研究的重點重新轉回細粒度CFI, 研究者又發現了細粒度CFI中存在的安全漏洞。

“控制流彎曲”[40]利用細粒度CFI僅僅保障所有跳轉都按照事先通過靜態分析確定的控制流圖進行, 不會對進程的上下文語義進行分析的缺陷。挑選了一些經常使用的并且會對內存中的數據產生修改的函數(例如printf()、memcpy()等)通過控制這些函數的參數對內存中的數據進行修改, 完成了不逾越控制流圖的控制流劫持, 完成攻擊者所需要的功能。

傳統細粒度CFI的另一個缺陷是無法對系統產生的信號或中斷的返回進行保護, 在類UNIX操作系統中, 這些信號或中斷發生時, 進程原狀態大多數是保存在棧上的。SROP[36]利用這種機制, 通過偽造信號幀來并篡改棧上保存的現場狀態引導進程進入到攻擊者設定的代碼區域中執行實現攻擊的目的。文獻[41]與[42]也針對細粒度CFI在實現上的漏洞提出了繞過的方法。

針對細粒度CFI存在的安全缺陷, 研究者也對其進行了相關的改進。

文獻[43]對所有能夠改變程序控制流的對象進行認證(包括函數返回地址, 函數指針等), 在每次這些對象從內存中存儲的時候計算一個驗證值, 將其存于一個寄存器中, 每次這些對象被讀取時檢查這個值是否與先前相同。

文獻[44]提出了上下文相關的CFI, 利用intel CPU中的LBR(Last Branch Record)機制, 每當程序要執行重要的系統調用時(例如exec()等), 則對LBR中保存的先前的跳轉指令進行CFI判斷, 若全部符合, 則繼續執行, 若有不符合CFG的跳轉則會報錯停止執行。這種方法能夠解決傳統細粒度CFI無法對上下文的跳轉合法性進行判斷的缺陷。

總體來說, 粗粒度CFI安全性不足不能滿足實際需求。細粒度CFI機制尚未完全成熟, 仍然存在安全與性能問題需要克服, 若能達到低耗, 高兼容性實現, 將會產生較好的保護效果。

4 基于增加程序不可知性思想的防御機制

由于代碼重用攻擊的實現要依賴對內存中已有指令的使用。攻擊者需要知道這些指令的確切位置。因此通過增加程序不可知性的方法也可以達到阻止攻擊的發生, 使用隨機化是一個典型并有效的方法。

4.1 隨機化安全機制

ASLR(Address Space Layout Randomization)[45]是一個典型且已經得到廣泛應用的基于隨機化的防御機制。其主要思想是通過對進程中的代碼段、數據段、堆、棧所占的頁面進行隨機化排布來使攻擊者無法得知這些段的具體位置從而無法實施攻擊。這種方式與數據段不可執行機制(DEP)相結合, 起到了很好的防御效果, 不僅能夠對傳統的注入攻擊產生防御效果, 也能提高代碼重用攻擊實施的難度。

但是ASLR仍然存在不足與缺陷, 具體有三點:

1. 隨機化的粒度僅僅到頁一級, 頁內的數據仍然是順序存儲的, 且參與隨機化的內存地址位數不足, 能夠被暴力攻破[46,47];

2. 由于動態鏈接庫的共享機制, 其位置對所有的程序都是可知的, 這就導致了這些代碼無法參與細粒度隨機化處理。防御機制設計者只能選擇放棄動態庫的共享或放棄對這部分代碼的隨機化處理[48];

3. ASLR面臨內存泄露攻擊的威脅, 由于程序代碼段一般都會占用多個頁面, 頁面之間都有跳轉指令維持其之間的聯系。攻擊者若能夠通過懸空指針等漏洞對任意內存地址數據進行讀取, 可以找到頁面之間的相互聯系, 就可以達到知曉代碼段頁面的分布位置, 實現去隨機化[49]。

由于ASLR極為廣泛的使用和極為突出的弱點與缺陷, 目前大多數的研究都是著眼于對ASLR的改進或以ASLR為標尺。在ASLR的基礎上又產生了許多新穎的內存隨機化實現機制。

文獻[50]針對ASLR粒度較粗的缺點, 對代碼的放置順序進行隨機排布, 粒度達到了單個指令級。建立一個記錄代碼順序的表, 對每一條指令, 記錄其后繼指令。

文獻[51]在不影響程序運行正確性的情況下, 對指令進行小范圍的隨機化處理, 能夠做到消除無意識配件, 重排函數調用與返回的寄存器保存和彈出指令。能夠在一定程度上減少攻擊者可以使用的配件數量。但是這種方法的覆蓋不夠廣泛, 無法完全消除配件。

文獻[52]對二進制代碼中的代碼段復制為兩份, 將原有的代碼段當做純數據, 不可執行, 對復制的部分進行分塊, 并在此程序裝載時隨機化, 并運行, 使用相關的算法保證代碼段中的轉移指令的正確性。以此實現內存布局的細粒度隨機化。

文獻[53]將進程的所有代碼數據段分割成任意大小的塊, 然后將這些塊隨機排布的整個進程地址空間。利用二進制代碼重寫技術進行重新匯編, 保持控制流指令正確。

文獻[48]對于ASLR的兼容性問題, 使共享代碼實現隨機化。首先重寫目標代碼, 利用一個間接查找表使控制流轉移重定向, 使得所有跳轉目標都會通過這個表來查找。利用x86的分段機制保護間接查找表, 使用特定的段選擇寄存器FS, 只有修改過的合法跳轉指令才能找到間接查找表。但這種方式僅僅能夠在x86-32架構上實現, 并且無法防御內存泄露的攻擊[54]。

文獻[55]與[56]分別在函數段與程序塊的粒度對內存中代碼進行隨機化分布, 增加了參與隨機化的內存地址位數, 提高了隨機化粒度。

不論實現方式如何, 上述通過隨機化增加程序不可知性的安全機制, 都面臨一個共同的威脅, 那就是內存泄露。內存泄露能夠幫助攻擊者獲得配件的地址, 對代碼重用攻擊的實現起到了極大的幫助作用。代碼重用加內存泄露是目前最具威脅性的攻擊方式。

4.2 內存泄露的威脅與應對

傳統的DEP等權限劃分的安全機制僅僅是將內存頁面的寫操作與執行操作分離開來。無論代碼段還是數據段都是默認可讀的, 這就導致了攻擊者通過懸空指針等程序錯誤對內存頁面進行讀取、掃描。在代碼段或數據段中得到程序隨機化的分布布局, 從而繞過ASLR等隨機化安全機制, 進行攻擊。

文獻[49]能夠使用內存泄露漏洞, 實時對隨機化布局之后的程序代碼段進行掃描, 獲悉每個代碼頁確切的起始地址, 計算出可以用作配件的代碼段的地址, 動態搭建配件鏈實施攻擊。

內存泄露大致分為兩種方式: 一是直接泄漏: 讀取代碼段, 找到直接跳轉和直接調用的目標地址, 收集這些地址進行分析, 就可以得出代碼頁面的分布位置; 二是間接泄漏: 讀取數據段中的函數指針(例如虛函數表), 返回地址可以達到相同的目的[57]。

傳統的寫/執行權限分離思想無法防御內存泄露的攻擊, 內存泄露又會導致隨機化安全機制的失效。因此防御針對內存泄露也成為了學界研究的重點。針對這種威脅, 最初的防御思想是分離讀權限。但是針對目前的硬件結構來說, CPU無法對頁面的讀權限進行剝離, 需要通過上層的操作系統進行支持, 并且傳統的代碼段中是包含數據信息的, 如何對代碼段中的數據進行剝離也是實現的難點之一。

文獻[58]將讀與執行權限分離。通過改寫MMU中的頁錯誤處理機制實現。假如進程對內存空間中代碼區中一個不存在的頁面進行取指操作, 則說明屬于正常的缺頁異常, MMU會從硬盤中載入這個頁并將頁存在相關位置。但如果對這個代碼頁進行的不是取指操作, 則說明是對代碼頁的讀取, 屬非法, 會導致進程停止。能夠對直接泄露產生防御效果。然而這種防御機制無法對間接泄露產生防御效果, 無法保護數據段中包含代碼段地址的函數指針等不會被泄露。

文獻[57]將代碼段與數據段嚴格區分, 確保代碼段只可執行而不再可讀。將代碼段中的數據進行修改為只執行(例如switch轉換表, 之前的是跳轉的地址, 文章改成跳轉到該地址的指令。)實現代碼只可執行可以防止直接內存泄露。再將數據段中的函數指針和返回地址都改為代碼段中的一個中轉站, 這個中轉站通過指令的形式跳轉到對應的目標地址, 通過這種方式防御間接內存泄露。這種防御方式在目前來說能夠對內存泄露起到有效的防御效果。

由于對內存代碼段中的數據與代碼強行進行分離的方法實現過于困難, 有研究者通過對代碼段進行復制并添加不同的方式實現對內存泄露攻擊的防御。

文獻[59]將可執行的代碼段復制作為數據段。當有對代碼段中的數據進行讀取操作時, 就將這段數據用隨機數代替, 并對MMU進行重定向操作, 使之指向復制的數據段。將對數據和代碼的操作分割在不同的區域, 在可執行區的數據在讀取后將不會再與原來相同。

文獻[54]先對二進制代碼進行修改, 將其復制為兩份, 一份是原有狀態, 一份是經過隨機化排布的, 在每個函數的調用和返回階段, 隨機選取運行哪一份的代碼, 這樣即使攻擊者能夠通過泄漏得到內存布局, 也無法使構造的ROP鏈得到執行。

文獻[60]將程序段分為兩個大段, 代碼段和數據段。AG作為中間的轉接層。將程序中所有的能夠控制代碼執行的位置稱為代碼地址, 例如基地址, GOT、PLT的入口、棧中的返回地址, 跳轉表等。每當有代碼地址將向數據區泄露時, AG對其進行加密作為一個標識, 每當有標識被用于控制流跳轉時, AG對其進行解密。對棧上的數據進行了保護, 將函數返回地址等數據保存在原有的位置。將棧上的其他數據用另一個寄存器指示。

文獻[61]與文獻[58]類似,利用MMU通過軟件實現對代碼可讀屬性與可執行屬性的分離。利用頁錯誤處理程序區分程序的非法讀操作與正常的指令獲取(Instruction Fetch)。

總結來說, 基于隨機化的安全機制在確保內存不被泄露并且隨機熵足夠高的情況下能夠起到較好的防御效果。

5 思考與討論

本小節對現有的對于代碼重用攻擊的防御方式進行系統化的總結, 并提出了一種能夠從根本上提升對于代碼重用攻擊防御效果的設計思路。

對于計算機系統的攻擊與防御是一對不斷上升與交錯的矛盾雙方: 對于計算機系統的攻擊催生著防御方式的改進; 防御方式的改進有促使黑客或研究者開發與使用新的更有效的攻擊方式。

而在對于計算機防御機制的設計與實現方面。性能與安全又成為了一對矛盾的兩個方面。要提高系統的安全性必然伴隨著性能或兼容性的損耗。能夠平衡這一對矛盾, 在可接受的性能與兼容性損耗限度內達到令人滿意的安全效果的防御機制才得以廣泛的采用。DEP與ASLR可以成為這種防御機制的典型, 它們二者組合使用可以做到在較低的損耗的情形大幅度提高攻擊者成功實施攻擊的難度。

但這兩種防御機制在代碼重用攻擊與內存泄露攻擊的雙重威脅之下其安全效能已經不再適用。DEP僅僅能夠防御計算機系統不受代碼注入的攻擊, 無法對代碼重用攻擊產生防御效果; ASLR本身具有諸多弱點并且面臨內存泄露的威脅。研究界對于這種新興的攻擊方式開始了不懈地探索與研究。

5.1 程序行為監控

針對代碼重用攻擊的防御, 思路上最簡單的方法是對于程序運行時行為的監測, 有效實施這種防御機制的難點與關鍵在于快速區別正常運行的程序與遭到攻擊的程序之間運行狀態的差異。

早期的研究者對指令流中出現配件的頻率進行監控。這種方法能夠對最原始的ROP攻擊產生較好的防御效果, 但其本身仍然存在問題, 嚴格地監控會導致大量虛假警報, 而降低敏感度會使攻擊行為被忽視。且攻擊者已經開始使用超過被認作的配件的長指令段以此稀釋配件出現的頻率將其繞過。

對于配件出現頻率的監控無法進行, 研究者開始轉而控制進程跳轉行為的合法性, 傳統細粒度CFI越來越得到重視。這種機制安全性較好高, 但存在先天性的性能損耗高, 無法使用動態鏈接庫等缺陷。于是研究者開始研究能夠實現的CFI方案, 出現了粗粒度CFI實現方案。

粗粒度CFI不需要事先精確分析程序的控制流, 采用了較為寬松的CFI檢查機制, 得到了性能上的提升, 但是其檢查機制過于寬松, 無法保障函數在返回時跳轉到的是原先的調用點, 也無法保障函數調用時, 所進入的函數體就是原本應當調用的函數, 攻擊者就可以利用精心設計的配件加以繞過。

在粗粒度的CFI實現方案被否定以后, 研究界繼續細粒度CFI的研究。對于細粒度CFI安全性的質疑被提出, 難點依然無法解決: 無法準確判斷某個跳轉屬于程序正常的操作還是被攻擊者劫持, 有攻擊者能夠實現不違反控制流圖的攻擊; 由于目前操作系統自身的代碼沒有經過CFI強化, 對于從操作系統到用戶代碼的轉移沒有檢查, 因此攻擊者可以通過偽造系統調用或信號幀來實現對控制流的劫持。

針對程序行為監控這種安全機制的基本思想是使程序按照一定的規則運行, 一旦檢測出程序有違反規則的行為則認作攻擊發生。兩個關鍵點分別是監控的實施與規則的設定。有些攻擊者通過安全機制的監控盲區進行攻擊[18]; 有些攻擊者則利用規則的漏洞進行攻擊[40]。因此, 能否全面地對程序的行為進行監控與能否設定安全高效的規則, 是決定安全機制有效與否的關鍵。而由于計算機程序的龐雜性、程序運行時的狀態多樣性, 使得這種監控的實施與規則的設定具有很高的挑戰性。

5.2 增加程序的不可知性

代碼重用攻擊的另一個防御思想是通過增加程序不可知性使攻擊者無法得知程序代碼的布置方式從而無法構建配件地址鏈。主要的實現方式是進行隨機化排布。然而在進行隨機化的同時還應當保證程序自身運行的正確性。這個過程可以成為去隨機化(Derandomization), 有些安全機制例如ASLR[45]通過生成地址無關代碼與程序裝載時的隨機化分布來自動實現隨機化程序的逆隨機化; 有些需要一定的內存占用與時間開銷來完成隨機化代碼的去隨機化例如ILR[50]使用額外的指令流程圖控制每條指令的執行。攻擊者可以利用諸如內存泄露等方式獲得ASLR隨機化后的內存布局或是ILR的指令流程圖, 進而實現去隨機化, 找到要用的配件鏈完成代碼重用攻擊。

評價一個隨機化安全機制有兩個關鍵指標: 程序正常去隨機化的難度以及攻擊者掌握去隨機化方法的難度。一個好的隨機化安全機制必然是程序自身能夠實現簡便的去隨機化過程, 而攻擊者很難進行去隨機化。

對于內存泄露的防御也得到了研究者的重視, 主要的防御思想是分離并限制讀權限, 例如使代碼段不可讀, 僅可執行等。但是傳統的程序代碼段是包含數據的, 如何將代碼段中的數據剝離也是等待解決的問題。除此之外也有對代碼段進行冗余化并采取原份與備份不同處理的方式。

總體來說, 本文認為能夠克服諸多限制的細粒度CFI, 以及能夠有效防范內存泄露的隨機化機制可以較好地防御代碼重用攻擊。

5.3 代碼重用攻擊根本原因分析與安全機制設計思路

代碼重用攻擊的一個重要的原因是控制流被劫持, 許多防御機制針對如何保護控制流的完整性, 致力于發現并制止控制流的被劫持。但這種防御措施僅僅是被動地檢測, 實際的根本問題是控制流為什么會被劫持。從計算機系統結構級考慮, 發生傳統緩沖區溢出攻擊的根本原因是在程序的執行過程中, 對程序的代碼段和數據段采取了相同的權限管理, 所有的頁面都是可讀可寫并可執行的。這就導致了攻擊者利用軟件漏洞將自己要執行的惡意代碼以數據形式注入到內存中, 并通過修改控制流使得這些惡意代碼以代碼的形式得到了執行。對于數據與代碼權限與處理方式的混淆導致了這種情況的發生。研究界認識到了這種問題, 并提出了數據不可知性思想, 即一段內存頁不能既可修改, 又可執行。并采取相應的實際防御機制, 即DEP, 使得這個問題得到了很好的解決。

然而攻擊仍在發生, 只是攻擊者不再將惡意代碼以數據的形式注入到內存中去, 而是利用內存中原有的代碼, 通過控制它們執行的順序來達到自己的目的, 也就是所謂的代碼重用攻擊。數據與指令具有極大的關聯性, 真正控制指令執行的還是數據。這些控制指令執行的數據在內存中是以地址或指針的形式存儲的。這些數據與傳統的整數、浮點數等數據類型都被保存在內存的數據區中。那么類比針對傳統注入攻擊的分類并采取權限分離的防御思想, 我們可以對內存中的內容進行再次分類。具體可以分為普通數據, 例如傳統的char、int類型數據等; 普通指令, 即原有意義上的指令; 數據地址, 例如指向普通數據的指針, 數組等; 指令地址, 例如函數指針, 函數的返回地址、基地址、虛函數表等。那么如此分類之后, 代碼重用攻擊的根本原因也就顯而易見了——指令地址被篡改。然而攻擊者能夠注入自己數據的地方僅僅是在內存的普通數據段與數據地址段中, 但是由于這些數據段與指令地址在內存中都是按照傳統數據這種方式進行無差別存儲與管理的, 它們之間沒有邏輯上或空間上的分隔。這就給了攻擊者篡改指令地址的機會, 導致了代碼重用攻擊的發生。

依據這種宏觀思想, 本文提出了一種初步的設計思路。如圖六所示, 對程序運行時棧的結構進行重構, 將原有的棧一分為二: 一個用于保存壓入的普通數據, 稱之為數據棧; 一個用于保存所有的函數返回地址和基地址, 稱之為地址棧。為兩個棧分別維護一套棧頂指針與棧幀指針。將地址棧的權限設置為只有函數的調用與返回階段才會進行壓棧與彈棧操作。將地址棧的位置置于數據棧的地址減小方向, 這樣即使攻擊者利用漏洞對棧中的緩沖區進行溢出, 也不會覆蓋到地址棧中函數的返回地址。

為了初步實現這種設計思路, 本文給出兩種方案: 第一種在硬件上實現, 增加兩條機器指令分別對新的數據棧進行壓棧與彈棧操作, 從原有的寄存器中保留兩個用于保存數據棧的棧頂地址與棧幀地址, 將原有的壓棧與彈棧指令改為對新的數據棧進行的操作, 原有的棧作為地址棧?;蚴菍all指令與ret指令進行修改, 將壓入原有棧中的返回地址壓入新的地址棧中, 原有的棧作為數據棧; 第二種是用軟件實現, 與文獻[60]中的AG-Stack類似, 由編譯器用mov與sub(add)指令組合來模擬對新開辟的數據棧的壓(彈)棧操作, 原有的棧作為地址棧。采用軟件實現的方式與硬件實現相比, 能夠產生較少的兼容性損耗和較高的性能損耗。硬件實現需要對底層的指令架構進行修改, 兼容性變差, 但是產生的性能損耗較低。這樣將棧結構分開并處以不同的處理方式, 可以有效避免攻擊者利用漏洞對保存在棧中的函數返回地址等指向指令的數據進行篡改, 從而大幅增加了實現代碼重用攻擊的難度。

本小節提出的設計思路僅僅是一種構想, 具體實現的細節仍然有待完善。

導致計算機系統不安全的原因是沒有相應權限的訪問與修改: 攻擊者能夠讀取本來不應該被讀取的部分, 導致了內存泄露攻擊; 通過在普通數據區的溢出修改了控制程序運行的指令地址段, 導致了代碼重用攻擊。這些都是權限劃分不清, 處理方法模糊造成的安全隱患。那么針對這些問題就可以通過權限與處理方式再細化的思想予以解決。假如通過安全機制的設計能夠實現普通數據與指令地址在邏輯上或空間上隔離, 將有效的阻止代碼重用攻擊的發生。

6 總結

本文介紹了代碼重用攻擊的起源與三種主要的實現方式。系統化的闡述了目前應對這種攻擊的兩類防御思想: 針對程序行為的監控思想以及增加程序的不可知性的思想, 以及它們在研究與實現過程中遇到的困難與解決方式。其中, 對程序行為監控的思想又可以分為針對配件頻率的監控與程序控制流完整性的監控; 增加程序不可知性的思想以ASLR為代表, 介紹了實現過程中遇到的問題以及能夠使這種安全機制失效的內存泄露攻擊, 并介紹了針對內存泄露攻擊的防御機制。最后, 對這兩類防御思想進行了深入且詳細的分析, 并提出了一種新的能夠提升對代碼重用攻擊防御效果的安全機制設計思想。

[1] V. van der Veen , N. dutt-Sharma , L. Cavallaro , and H. Bos. “Memory errors: The past, the present, and the future,” in, pp. 86-106, 2012.

[2] “Smashing the stack for fun and profit.” Aleph One. http://insecure. org/stf/smashstack.html, 2000.

[3] M. Russinovich. “Windows internals.”, 2009.

[4] V. De Ven Arjan. “New security enhancements in red hat enterprise linux v.3, update 3”., 2004.

[5] Microsoft. “Data Execution Prevention (DEP).” http:// windows.microsoft.com/en-us/windows-vista/data-execution-prevention-frequently-asked-questions#, 2001.

[6] C0ntex. “Bypassing non-executable-stack during exploitation using return-to-libc”, http://css.csail.mit.edu/6.858/2014/readings/ return-to-libc.pdf, 2005.

[7] Nergal. “The advanced return-into-lib(c) exploits (pax case study).”, 58(4): 54. http://phrack.org/issues/ 58/4.html Dec.2001.

[8] T. Kornau “Return oriented programming for the ARM architecture.”, 2009.

[9] H. Shacham. “The geometry of innocent flesh on the bone: Returninto-libc without function calls (on the x86).” In Proc., pp. 552-561, 2007.

[10] T. Bletsch, X. Jiang, V.Freh, and Z. Liang. “Jump Oriented Programming:A New Class of Code-Reuse.” in Proc.. pp. 30-40, 2011.

[11] S. El-Sherei, Return-to-libc,https://www.exploit-db.com/docs/ 28553. pdf.

[12] Wikipidia, “Return-to-Libc Attack.” https://en.wikipedia.org/wiki/ Return-to-libc_attack. Aug. 2015.

[13] M. Tran, M. Etheridge,X. Jiang, T. Bletsch, and N. Peng. “On the expressiveness of return-into-libc Attacks” inpp. 121-141, 2011.

[14] R. Roemer ,E. Buchanan ,H. Shacham,. “Return-Oriented Programming System,Languages, and Applications”: Volume 15 Issue 1, March 2012.

[15] N. Carlini ,D. Wagner. “ROP is still dangerous: Breaking modern defenses” inpp. 385-399, 2014.

[16] L. Davi, A. Sadeghi, D. Lehmann. and F. Monrose, “Stitching the Gadgets On the Ineffectiveness of Coarse-Grained Control-Flow Integrity Protection” in, pp. 401-416, 2014.

[17] S. Checkoway, L. Davi, A. Dmitrienko, and H. Shacham. “Return-oriented programming without returns” in, pp. 559-572, 2010.

[18] R. Bosman, H. Bos. “Framing Signals:A Return to Portable Shellcode” inProc.,pp. 243-258, 2014.

[19] F. Schuster, T. Tendyck, C. Liebchen, L. Davi, A. Sadeghi. and T. Holz. “Counterfeit Object-Oriented Programming: On the difficulty of Preventing Code Reuse Attacks in C++ Applications,” in. pp. 745-762, 2015

[20] V. Pappas, M. Polychronakis, and A. D. Keromytis. “Transparent ROP Exploit Mitigation using Indirect Branch Tracing,” in., pp. 447-462, 2013.

[21] Y. Cheng,Z. Zhou, and M. Yu. “ROPecker: A generic and practical for defending against ROP attacks” in Proc.Symposium. 2014

[22] E. Athanasopoulos,M. Polychronakis,H. Bos, “Size Does Matter: Why Using Gadget-Chain Length to Prevent Code-Reuse Attacks is Hard” in, pp. 417-432, 2014

[23] M. Abadi, M. Budiu, J. Ligatti, and U. Erlingsson. “Control-Flow Integrity” inpp.340-353, 2005.

[24] M. Abadi, M. Vrable,M. Budiu, and U. Erlingsson. “XFI Software Guards for System Address Spaces” in,, pp. 75-88, 2006.

[25] Z. Wang, X. Jiang. “HyperSafe A Lightweight Approach to Provide Lifetime Hypervisor Control Flow” in. pp. 380-395 , 2010.

[26] L. Davi, R. Dmitrienko, M. Egele, T. Fischer, T. Holz, R Hund, S. Nurnberger, and A Sadeghi.“: A Framework to Mitigate Control-Flow Attacks on Smartphones” in. 2012.

[27] J. Pewny, T. Holz. “Control-flow Restrictor: Compiler-based CFI for iOS”. Inthe, pp. 309-318, 2013.

[28] J. Tang. “Exploring Control Flow Guard in Windows 10”, http://sjc1-te-ftp.trendmicro.com/assets/wp/exploring-control-flow-guard-in-windows10.pdf, Jan. 2015.

[29] B. Niu,G. Tang. “Modular Control-Flow Integrity” in, pp. 577-587, 2014.

[30] L. Davi, P. Koeberl, and A. Sadeghi. “Hardware-Assisted Fine-Grained Control-Flow Integrity:Towards Efficient Protection of Embedded Systems Against Software Exploitation” in, pp.1-6, 2014.

[31] M. Budiu, U. Erlingsson, and M. Abadi. “Architectural Support for Software-Based Protection” in Proc. the 1st workshop on Architectural and system support for improving software dependability. (ASID’06), pp. 42-51, 2006.

[32] B. Zeng, T. Gang. and G. Morrisett. “Combining Control-Flow Integrity and Static Analysis for Efficient and Validated Data Sandboxing” in Proc..pp. 29-40, 2011.

[33] C. Tice,T. Roeder, S.Checkoway, U.Erlingsson, L. Locano, G. Pike, and P. Collingbournel. “Enforcing Forward-Edge Control-Flow Integrity in GCC & LLVM” inpp. 941-955, 2014.

[34] C. Zhang, T. Wei. Z. Chen, L. Duan, L. Szekeres, S. McCamant, D. Song, and W. Zou. “Practical Control Flow Integrity & Randomization for Binary Executables” in, pp. 559-573, 2013.

[35] Y. Xia,Y. Liu,H. Chen, and B. Zang. “CFIMon: Detecting Violation of control flow integrity using performance counters” in Proc., pp. 1-12, 2012.

[36] M. Zhang,R. Sekar. “Control flow integrity for COTS binaries.” in, pp. 337-352, 2013.

[37] J. Criswell, N. Dautenhahn, and V. Adve. “KCoFI: Complete control-flow integrity for commodity operating system kernels.” in Proc. The 2014,, pp. 292-307, 2014.

[38] W. Dai, Z. Liu, Y.H. Liu. “Function Pointer Attack Detection with address integrity checking”. Vol. 35, No. 2, pp. 424-429, 2015. (代偉, 劉智, 劉益和, “基于地址完整新檢查的函數指針攻擊檢測”,, 2015,35(2):424-429.)

[39] E. Athanasopoulos.H. Bos,G. Portokalidis, and E. Goktas. “Out of Control Overcoming Control-Flow Integrity” in, pp. 575-589, 2014.

[40] N. Carlin,A. Barresi,D. Wagner, M. Payer, and T. R. Gross. “Control-Flow Bending:On the Effectiveness of Control-Flow Integrity” in, pp. 161-176, 2015.

[41] C. Liebchen, M. Nergro, P. Larsen, M. Conti, S. Crane, L. Davi, M. Franz, M. Qunaibit, A. Sadeghi. “Losing Control : On the Effectiveness of Control-Flow Integrity under Stack Attacks” inpp. 952-963, 2015.

[42] I. Evans, F. Long, H. Shrobe, U. Otgonbaatar, and M. Rinard. “Control Jujutsu: On the Weaknesses of Fine-Grained Control Flow Integrity” in, pp. 901-913, 2015.

[43] A. Bittau, D. Boneh,D. Mazieres, and A.J.Mashtizadeh. “CCFI: Cryptographically Enforced Control Flow Integrity” in, pp. 941-951, 2015.

[44] D. Andriesse,V. Veen, B. Gras, H. Bos, L. Sambuc, A. Slowinska, and C. Giuffrida. “Practical Context-Sensitive CFI” in, pp. 927-940, 2015.

[45] PAX Team. “Address Space Layout Randomization” http://pax. grsecurity.net/docs/aslr.txt, 2003.

[46] H. Shacham,M. Page, B. Ptaff, E. Goh, N. Modadugu, and D. Boneh. “On the Effectiveness of Address-Space Randomization” in, pp. 298-307, 2004.

[47] G. Roglia, L. Martignoni, R. Paleari, and D. Bruschi. “Surgically Returning to Randomized Lib(c)” in, pp. 60-69, 2009.

[48] M. Backes, S. Nurnberger. “Oxymoron: Making Fine- Grained Memory Randomization Practical by Allowing Code Sharing” in, pp. 433-447, 2014.

[49] K. Snow, F. Monrose, L. Davi, A. Dmitrienko, C. Liebchen, and A. Sadeghi. “Just-In-Time Code Reuse:On the Effectiveness of Fine-Grained Address Space Layout Randomization” in Proc. the 2013 IEEE Symposium on Security and Privacy.(SP’13), pp. 574-588, 2013.

[50] J. Hiser, M. Co, M. Hall, A. Nguyen-Tuong, and J. Davidson. “ILR: Where’d My Gadgets Go?” in, pp. 571-585, 2012.

[51] V. Pappas, M. Polychronakis, and A. Keromytis. “Smashing the Gadgets: Hindering ROP Programming Using In-Place Code Randomization” in, pp. 601-615, 2012.

[52] R. Wartel, V. Mohan, K. Halen, and Z. Lin. “Binary Stirring: Self-randomizing Instruction Addresses of Legacy x86 Binary Code” in, pp. 157-168, 2012.

[53] L. Davi, A. Dmitrienko, A. Sadeghi, and S. Nurnberger. “Gadge Me If You Can: Secure and Efficient Ad-hoc Instruction-Level Randomization for X86 and ARM” in, pp. 299-310, 2013.

[54] L. Davi, C. Liebchen, A. Sadeghi, K. Snow, and F.Monrose. “Isomeron: Code Randomization Resilient to (Just-In-Time) Return-Oriented Programming” in, 2015

[55] L. Xiao. “The Design and Implementation of a Function Lever Randomization Defensing Method against ROP Attack [Master Degree Thesis],” Nanjing:Software School,Nanjing University, 2013. (肖亮.一種針對ROP攻擊的函數粒度隨機化防御方法的設計與實現[碩士學位論文]. 南京: 南京大學軟件學院, 2013.)

[56] X. Zhan. “The Research of Defending ROP Attacks Using Basic Block Level Randomization [Master Degree Thesis],” Nanjing: Software School, Nanjing University, 2014. (詹珣. 針對ROP攻擊的塊粒度地址空間隨機化防御技術的研究[碩士學位論文]. 南京: 南京大學軟件學院, 2014)

[57] S. Crane, C. Lirbchen, A. Homescu, L. Davi, P. Larsen, A. Sadeghi, S. Brunthaler, and M. Franz. “Readactor: Practical Code Randomization Resilient to Memory Disclosure” in. 2015

[58] M. Backes, T. Holz, B. Kollenda, P. Koppe, S. Nurnberger, and J. Pewny. “You Can Run but You Cant Read Preventing Disclosure Exploits in Executable Code” in, pp. 1342-1353, 2014.

[59] A. Tang, S. Sethumadhavan, S. Stolfo, “Heisenbyte: Thwarting Memory Disclosure Attacks using Destructive Code Reads” in, pp. 256-267, 2015.

[60] K. Lu, C. Song, W. Lee, S. Chung, T. Kim, and W. Lee. “ASLR-Guard:Stopping Address Space Leakage for Code Reuse Attacks” in, pp. 280-291, 2015.

[61] C. Yang, Q.X. Wang, Q. Wei, “Code Reuse Attack Mitigation Based on Unreadable Property of Executable Memory”, Journal of Information Engineering University. Vol. 17, No. 1, 2016.(楊超, 王清賢, 魏強, “基于可執行內存不可讀屬性的防代碼重用技術”,, 2016,17(1):59-64.)

柳童 于2013年在西安電子科技大學計算機科學與技術專業獲得學士學位?,F在中國科學院信息工程研究所系統結構專業攻讀博士學位。研究領域為計算機系統安全。研究興趣包括代碼重用攻擊、系統防御等。Email: liutong9017@iie.ac.cn史崗 于2004年在中國科學院計算技術研究所計算機體系結構專業獲得博士學位?,F任中國科學院信息工程研究所第五研究室高級工程師。研究領域為計算機系統安全。研究興趣包括計算機架構, 計算機芯片安全等。Email: shigang@iie.ac.cn 孟丹 于1995年在哈爾濱工業大學獲得計算機體系結構專業博士學位?,F任中國科學院信息工程研究所所長。研究領域包括計算機系統安全, 大數據與云計算等。研究興趣包括計算機系統安全, 云計算安全等。Email: mengdan@iie.ac.cn

A Survey of Code Reuse Attack and Defense Mechanisms

LIU Tong1, 2, SHI Gang1, MENG Dan1

1Institute of Information Engineering, Chinese Academy of Science, Beijing 100093, China2University of Chinese Academy of Science, Beijing 100049, China

Due to the wide existence of vulnerabilities in computer programs such as C and C++, computer systems is vulnerable to be tampered by adversary changing the original running states. Researchers have made great efforts and take some effective protection mechanisms, for instance, Data Execution Prevention and Address Space Layout Randomization. These security mechanisms have a great effect against the primitive attack patterns like code-injection attack. However, the security of computer system is still not optimistic. Though the adversary could not inject their own codes into the memory then run them ever again, they began to use the original benign codes in the memory, manipulate them to achieve malicious purpose by changing their order of operating, which is called code-reuse attack. And it is able to bypass a variety of security mechanisms of commodity computer systems, thus it has become a major threat and the main pattern of hacking. For this reason, researches about code-reuse attack have been taken up in recent years. This paper illustrates the origin of code-reuse attack and achieved way of attack, summarizes the existing defense mechanisms and simply evaluates these defense mechanisms systematically. Meanwhile, this paper analyzes briefly the basic reason of code reuse attack and puts forward an new idea of defense mechanism designing.

computer system security; memory security; code-reuse attack

TP309.2

柳童, 博士研究生, Email: liutong9017@iie.ac.cn。

2016-2-24; 修改日期: 2015-4-14; 定稿日期: 2016-4-18

DOI號 10.19363/j.cnki.cn10-1380/tn.2016.02.002

猜你喜歡
控制流防御機制攻擊者
防御機制在醫學生抑郁的性別差異中的中介作用*
抵御控制流分析的Python 程序混淆算法
基于返回地址簽名的控制流攻擊檢測方法
基于控制流的盒圖動態建模與測試
正面迎接批判
基于Petri網數據流約束下的業務流程變化域分析
正面迎接批判
有限次重復博弈下的網絡攻擊行為研究
軀體形式障礙患者治療前后防御機制的對照觀察
大學生防御機制及人際信任的相關研究
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合