柳 童 史 崗 孟 丹
?
代碼重用攻擊與防御機(jī)制綜述
柳 童1,2史 崗1孟 丹1
1中國科學(xué)院信息工程研究所 北京 中國 1000932中國科學(xué)院大學(xué) 北京 中國 100049
由于C與C++等計算機(jī)程序中廣泛存在的漏洞, 攻擊者可以通過這些漏洞讀取或篡改內(nèi)存中的數(shù)據(jù), 改變計算機(jī)程序原有的執(zhí)行狀態(tài)達(dá)到破壞的目的。為此研究者進(jìn)行了不懈地努力并采取了一些卓有成效的保護(hù)機(jī)制, 例如數(shù)據(jù)不可執(zhí)行與內(nèi)存布局隨機(jī)化, 這些防御機(jī)制對于早期的代碼注入攻擊起到了極好的防御效果, 然而計算機(jī)系統(tǒng)的安全性依然不容樂觀。攻擊者在無法通過向內(nèi)存中注入自己的代碼并執(zhí)行的方式完成攻擊后, 開始利用內(nèi)存中原有的代碼, 通過控制它們執(zhí)行的順序來達(dá)到自己的目的, 這種攻擊方式稱為代碼重用攻擊, 它具有極大的威脅性, 能夠繞過多種現(xiàn)行的安全措施, 并成為攻擊者的主流攻擊方式。為此, 研究界針對代碼重用攻擊的研究也逐漸增多。本文簡述了代碼重用攻擊的起源, 攻擊實(shí)現(xiàn)的方式, 系統(tǒng)化地總結(jié)了現(xiàn)有的防御機(jī)制并對這些防御機(jī)制進(jìn)行了評價。對代碼重用攻擊的根本原因進(jìn)行了簡要的分析, 并提出了一種新的防御機(jī)制設(shè)計思路。
計算機(jī)系統(tǒng)安全; 內(nèi)存攻擊; 代碼重用攻擊
計算機(jī)的使用在當(dāng)代社會已經(jīng)普及到工業(yè)、教育、醫(yī)療、金融、軍事等各個行業(yè)。然而, 針對計算機(jī)系統(tǒng)的攻擊也數(shù)不勝數(shù), 造成的損失數(shù)以億計。這是由于在C與C++等計算機(jī)程序中普遍存在漏洞, 例如能夠?qū)?nèi)存的直接存取; 對用戶的輸入沒有自動的邊界檢查機(jī)制, 以及對已經(jīng)釋放的指針再利用等[1]。使攻擊者能夠利用這些漏洞通過溢出沒有邊界檢查機(jī)制的緩沖區(qū)來注入惡意代碼并篡改內(nèi)存的函數(shù)返回地址, 改變程序控制流使注入的代碼得到執(zhí)行[2], 這就是最早的代碼注入攻擊。在此之上又發(fā)展出了整數(shù)溢出、格式化字符串溢出等攻擊方式, 實(shí)現(xiàn)原理基本相同。計算機(jī)系統(tǒng)安全機(jī)制的設(shè)計者針對這種攻擊方式采用了許多卓有成效的防御機(jī)制, 例如數(shù)據(jù)不可執(zhí)行(Data Execution Prevention , DEP)[3-5], 它將原有在內(nèi)存中無差別存儲的內(nèi)容分為數(shù)據(jù)段與代碼段, 并劃分了不同的權(quán)限: 數(shù)據(jù)不可執(zhí)行, 代碼不可修改。這使攻擊者以溢出緩沖區(qū)等形式注入的惡意代碼不會再被允許執(zhí)行, 從而抑制了代碼注入攻擊。
然而這些漏洞仍然在被利用。近年來, 另一種攻擊方式開始興起。一些攻擊者開始利用程序在內(nèi)存中原有的代碼, 通過利用漏洞改變它們的執(zhí)行順序來達(dá)到攻擊的目的, 這就是所謂的代碼重用攻擊(Code-reuse Attack)。從最早的Return-to-Libc攻擊[6,7]逐漸發(fā)展出了ROP(Return Oriented Programming)[8,9]、JOP(Jump Oriented Programming)[10]等攻擊方式。這些攻擊方式依然能夠達(dá)到與傳統(tǒng)的代碼注入攻擊相同的攻擊效果, 能夠使攻擊者執(zhí)行任意代碼。因此目前對于計算機(jī)系統(tǒng)安全性的保護(hù)依然不容樂觀, 研究界對于代碼重用攻擊的防御提出了各種各樣的安全機(jī)制, 然而都存在安全性或性能、兼容性缺陷, 無法達(dá)到令人滿意的效果。本文對代碼重用攻擊的實(shí)現(xiàn)機(jī)制與主要方法進(jìn)行了概述, 并對針對代碼重用攻擊的防御機(jī)制的實(shí)現(xiàn)與存在的問題進(jìn)行了詳細(xì)的介紹。在分析了代碼重用攻擊的根本原因基礎(chǔ)上提出了一種新的針對代碼重用攻擊的防御機(jī)制設(shè)計思想。
本文結(jié)構(gòu)如下: 第二部分對代碼重用攻擊的實(shí)現(xiàn)機(jī)制與國內(nèi)外研究界當(dāng)前對于代碼重用攻擊的研究現(xiàn)狀進(jìn)行了概述; 第三部分和第四部分分別對當(dāng)前主流的防御機(jī)制兩大設(shè)計思想進(jìn)行了綜述; 第五部分對這些防御機(jī)制進(jìn)行了總結(jié)并提出了一種全新的能夠提高計算機(jī)系統(tǒng)安全性的安全機(jī)制設(shè)計思想; 第六部分對全文進(jìn)行總結(jié)。
代碼注入與代碼重用都屬于對計算機(jī)系統(tǒng)漏洞進(jìn)行利用的攻擊方式。他們的區(qū)別在于攻擊者執(zhí)行惡意代碼的方式, 前者通過直接向內(nèi)存中注入惡意代碼并執(zhí)行; 后者利用內(nèi)存中原有的代碼, 通過篡改控制指令執(zhí)行的數(shù)據(jù), 改變了指令原有的執(zhí)行順序, 使其按照攻擊者的意志執(zhí)行, 達(dá)成攻擊目標(biāo)?,F(xiàn)有的安全機(jī)制, 例如數(shù)據(jù)不可執(zhí)行(DEP), 對代碼注入攻擊起到了極大的抑制作用。因此, 代碼重用攻擊得到了攻擊者的青睞, 成為目前攻擊方式的主流, 它能夠繞過現(xiàn)行計算機(jī)系統(tǒng)的大部分安全機(jī)制。目前代碼重用攻擊有Return-to-Libc、ROP、JOP等具體形式。
2.1 Return-to-Libc攻擊
若攻擊者能夠獲悉程序所使用的庫函數(shù)的地址, 便可以用其地址來覆蓋程序中某個函數(shù)的返回值, 并將調(diào)用庫函數(shù)所需要的參數(shù)以正確的順序添加至覆蓋區(qū)內(nèi), 這樣程序在該函數(shù)返回后就會執(zhí)行相應(yīng)的庫函數(shù), 例如調(diào)出一個shell。這種攻擊方式能使攻擊者可以使用任意的參數(shù)調(diào)用內(nèi)存中任意的庫函數(shù)[11,12]。
雖然Return-to-Libc攻擊能夠達(dá)成上述的效果, 但在使用上還是有局限性, 不屬于圖靈完備的攻擊方式[9], 原因有兩點(diǎn): 一是在Return-to-Libc攻擊中, 攻擊者能夠一個接一個調(diào)用任意的庫函數(shù), 然而這仍然只能允許他執(zhí)行原有的線性代碼, 無法滿足進(jìn)行任意行為的需求; 二是攻擊者只能夠調(diào)用已經(jīng)加載到內(nèi)存中的庫函數(shù), 它們功能有限, 因此限制了攻擊者的能力。
然而也有證明Return-to-Libc攻擊的圖靈完備性的成果[13], 通過傳統(tǒng)Return-to-Libc中利用的函數(shù)產(chǎn)生的副作用完成特定的操作。找出那些副作用可用的函數(shù)來作為執(zhí)行某項(xiàng)功能的函數(shù)配件。再利用與下文講述的ROP攻擊相同的原理將這些函數(shù)串聯(lián)起來, 完成圖靈完備的攻擊。
2.2 ROP(Return-Oriented Programming)攻擊
OP是在Return-to-Libc攻擊的基礎(chǔ)上逐步發(fā)展起來的, 能夠?qū)崿F(xiàn)任意程序行為(圖靈完備)的攻擊方式[9]。ROP攻擊與函數(shù)調(diào)用和返回機(jī)制有極大的聯(lián)系。以x86架構(gòu)程序?yàn)槔? call與ret指令在程序的執(zhí)行過程中總是一一對應(yīng)的。在執(zhí)行call指令時, CPU會將call指令的下一條指令地址壓棧作為返回地址, 然后跳轉(zhuǎn)到call所指示的位置。在ret指令執(zhí)行時, CPU會自動將預(yù)先保存在棧中的返回地址彈給eip寄存器, 繼續(xù)執(zhí)行原有call指令之后的指令。這個操作不會對call的下一條指令的正確性進(jìn)行檢查或保障。ROP攻擊就是利用了這種缺陷。如圖一所示, 首先在原有代碼中搜索一些短小的指令序列, 這些序列都能完成一定的功能, 例如運(yùn)算或賦值, 然后以ret指令為結(jié)尾, 稱為配件(gadget)。攻擊者依據(jù)要執(zhí)行的配件的順序與所需的參數(shù), 將這些配件的地址與參數(shù)進(jìn)行拼接, 構(gòu)建一條配件鏈(gadget chain)。并通過棧溢出漏洞將這條配件鏈注入到棧中覆蓋當(dāng)前或其他某個函數(shù)的返回地址。一旦返回地址被覆蓋的函數(shù)返回, 那么CPU就會按照棧中攻擊者存放的配件地址鏈進(jìn)行跳轉(zhuǎn), 不斷的從一個配件返回并跳轉(zhuǎn)到下一個配件執(zhí)行[14]。ROP攻擊極為靈活, 在發(fā)展演變的過程中出現(xiàn)了許多變種與新的實(shí)現(xiàn)方式, 并配合內(nèi)存泄露攻擊, 能夠繞過多種專門針對它的防御機(jī)制[15-17]。
圖1 ROP攻擊模型
2.3 JOP(Jump-Oriented Programming)攻擊
JOP攻擊采用與ROP類似的配件鏈來實(shí)現(xiàn)攻擊, 但不依賴棧完成對程序流的控制[10]。如圖二所示, JOP采用以jmp指令為結(jié)尾的配件。將配件地址鏈保存在另外一塊任意數(shù)據(jù)區(qū)中, 稱為調(diào)度表(dispatch table), 采用了一個專門的配件作為一個指向調(diào)度表的指針, 稱為調(diào)度配件(dispatcher), 類似于普通程序的eip指針, 它對某個寄存器進(jìn)行已知操作, 例如自增, 然后跳轉(zhuǎn)到這個寄存器指示的地址。其他所有的能夠完成特定功能的配件在最后都跳轉(zhuǎn)到調(diào)度配件。而在ROP攻擊中, 配件執(zhí)行的控制序列是以配件地址鏈的形式存儲在棧上的, 利用棧指針來指向配件。與ROP相同, JOP攻擊的實(shí)現(xiàn)也是需要指令序列的, 這些序列就是配件的地址, 但由于采用了調(diào)度配件, 配件地址序列可以存放在內(nèi)存的任何可讀寫區(qū)域, 而不是必須在棧上。這就給了攻擊者更大的靈活性和空間。他們可以將配件鏈放置于內(nèi)存中任意一塊可寫的數(shù)據(jù)區(qū)。
2.4 其他類型代碼重用攻擊
除了上述三種常見的代碼重用攻擊之外, 有研究者和黑客也相繼提出了其他類型的代碼重用攻擊。
SROP[18]利用類UNIX操作系統(tǒng)用進(jìn)程棧保存信號幀的機(jī)制, 通過偽造信號幀來引導(dǎo)進(jìn)程進(jìn)入到攻擊者設(shè)定的代碼區(qū)域中執(zhí)行實(shí)現(xiàn)攻擊目的。
COOP[19]利用了C++面向?qū)ο缶幊痰奶匦? 利用篡改類中的虛函數(shù)表來使一系列虛函數(shù)按照攻擊者設(shè)定的順序執(zhí)行完成攻擊目標(biāo)。
2.5 國內(nèi)外研究現(xiàn)狀
由于代碼重用攻擊具有極強(qiáng)的破壞性, 極高的靈活性, 能夠繞過現(xiàn)行的絕大多數(shù)防御機(jī)制。已經(jīng)漸漸成為黑客進(jìn)行攻擊的主要手段。研究界對于代碼重用攻擊防御機(jī)制的研究也得到極大的重視。
在2011-2015年間S&P (IEEE Symposium on Security and Privacy)、CCS(ACM Conference on Computer and Communications Security)以及Usenix (Usenix Security Symposium)安全方面世界三大頂級會議對于代碼重用攻擊的相關(guān)論文發(fā)表數(shù)量如圖三所示, 可以看出, 對于這類攻擊的研究與防范逐漸成為研究界的重點(diǎn)。
代碼重用攻擊的實(shí)現(xiàn)需要兩大重要環(huán)節(jié), 一個是控制流的劫持, 另外一個是對內(nèi)存中的代碼位置的獲悉。首先得到內(nèi)存中的代碼位置, 構(gòu)建控制程序執(zhí)行的配件地址鏈, 而后通過對溢出漏洞將配件鏈注入到內(nèi)存的數(shù)據(jù)區(qū)中, 最后劫持控制流使得程序按照攻擊者注入的配件順序執(zhí)行。因此防御措施也就分別針對這兩個重要環(huán)節(jié), 監(jiān)測程序的異常行為與增加程序的不可知性。
攻擊者在實(shí)行代碼重用攻擊時, 要實(shí)現(xiàn)惡意的功能, 勢必改變原有程序的執(zhí)行路線, 因此研究者通過添加一些監(jiān)控機(jī)制對這種改變做出偵測用以判斷代碼重用攻擊的發(fā)生。
實(shí)現(xiàn)代碼重用攻擊的另外一個要素是對內(nèi)存中程序指令位置的精確知曉, 由于攻擊者已經(jīng)無法注入自己的代碼, 因此只能使用內(nèi)存中原有的代碼, 他們通過選擇配件, 并精心構(gòu)造配件地址鏈用來控制這些配件的執(zhí)行實(shí)現(xiàn)自己的惡意目的。因此研究者通過增加內(nèi)存的不可知性來阻止攻擊者得知內(nèi)存中代碼的布局, 使其無法構(gòu)造配件鏈。
目前的針對程序異常行為的監(jiān)測防御機(jī)制中, 大致分為兩種方法, 一種是對ROP/JOP攻擊中配件出現(xiàn)頻率的監(jiān)測; 另一種是對程序控制流正確性的保障與監(jiān)測。
3.1 對于配件出現(xiàn)頻率的檢測
研究者在觀察代碼重用攻擊(這里以ROP攻擊為例)發(fā)生時的程序行為時發(fā)現(xiàn), 發(fā)生ROP攻擊的程序行為與正常程序行為有著明顯不同。在ROP攻擊的過程中, 攻擊者通過將許多以ret指令為結(jié)尾的配件連接起來完成攻擊, 這些配件大都較短, 在一定長度以內(nèi), 當(dāng)ROP攻擊發(fā)生時程序指令流中會出現(xiàn)大量ret指令。因此監(jiān)測一段指令當(dāng)中ret指令出現(xiàn)的頻率, 就成為了一種監(jiān)測ROP攻擊的方式。然而這種方式只能對ROP攻擊產(chǎn)生效果, 無法防御Return-to-Libc攻擊。
Pappas等人[20]利用Intel處理器中自帶的LBR (Last Branch Recording)機(jī)制來對程序中的間接跳轉(zhuǎn)進(jìn)行檢測, 保證所有的ret指令返回目標(biāo)指令都位于一條call指令之后, 這種方式可以防御簡單的Return-to-Libc與ROP攻擊; 利用對LBR中存儲的跳轉(zhuǎn)指令的地址進(jìn)行分析, 分析這些地址之間的緊密程度來判斷是否出現(xiàn)了一串以ret為結(jié)尾的配件鏈, 從而判斷是否出現(xiàn)了ROP攻擊。Cheng[21]等人采用了相同的對配件鏈的檢查思路, 并采取了對于間接跳轉(zhuǎn)更為頻繁和嚴(yán)格的檢查。Pappas[20]等人與Cheng[21]等人都采用了對配件的出現(xiàn)頻率進(jìn)行監(jiān)控的方法, 通過比對遭到攻擊的程序與正常程序之間的差別來監(jiān)測攻擊的發(fā)生。具體涉及到兩個變量: 被認(rèn)作是配件的指令序列長度Lg和被認(rèn)作ROP攻擊發(fā)生的配件連續(xù)出現(xiàn)的次數(shù)Lc。通過改變這兩個變量可以提高或降低ROP攻擊檢測的敏感程度。
這種方式存在的問題是無法確定檢查的敏感度。假如提高敏感度, 那么有可能正常的程序也會被判定發(fā)生ROP攻擊, 使假警報劇增; 假如降低敏感度, 則ROP攻擊就有可能逃過監(jiān)測。如何選擇Lg和Lc對是需要解決的問題。更嚴(yán)重的是, 目前有些攻擊者已經(jīng)能夠找到一些長配件, 這些長配件的長度大于被系統(tǒng)認(rèn)作ROP配件的長度, 并把這些配件加入到實(shí)施ROP攻擊的配件鏈中, 就可以完全逃過這種防御機(jī)制的監(jiān)測[15,16,22]。
總體來說, 這種監(jiān)測思想存在較大的繞過可能性, 無法有效滿足目前的安全需求。
3.2 基于保障控制流完整性思想的防御機(jī)制
類比與對配件出現(xiàn)頻率進(jìn)行監(jiān)測的方法, 保障間接轉(zhuǎn)移指令目標(biāo)地址的正確性是目前更為有效的方法, 這里需要指出的是, 轉(zhuǎn)移指令分為直接轉(zhuǎn)移和間接轉(zhuǎn)移兩大類, 直接轉(zhuǎn)移指令的目的地址是在編譯鏈接階段就已經(jīng)確定并寫入二進(jìn)制代碼中的, 在程序運(yùn)行時無法更改; 間接轉(zhuǎn)移指令在運(yùn)行時對具體的寄存器或內(nèi)存進(jìn)行間接尋址, 這些間接轉(zhuǎn)移指令的目標(biāo)可能是動態(tài)變化的, 因此存在被攻擊者篡改并劫持的可能性, 故所有保障控制流完整性的機(jī)制都是針對間接轉(zhuǎn)移指令的。
3.2.1 細(xì)粒度CFI的最早提出與探討
文獻(xiàn)[23]是最早提出保障控制流完整性(Control- Flow Integrity,CFI)思想的文章, 首先將要執(zhí)行的代碼進(jìn)行靜態(tài)分析, 畫出控制流圖, 預(yù)先計算出所有的間接轉(zhuǎn)移指令的可能的目標(biāo)地址, 并為之配唯一的ID。改寫程序的二進(jìn)制代碼, 在每一條間接跳轉(zhuǎn)指令執(zhí)行之前增加檢查邏輯, 一旦出現(xiàn)違反控制流圖的間接跳轉(zhuǎn)就會報錯并終止程序。這種為每一個轉(zhuǎn)移目標(biāo)地址分配唯一ID的實(shí)現(xiàn)思想我們稱之為細(xì)粒度CFI。它在被提出時被認(rèn)為具有極佳的安全性, 能夠檢測出任何代碼重用攻擊并使用純軟件方式實(shí)現(xiàn), 得到了研究界廣泛的重視與探討, 并出現(xiàn)了不少具體的實(shí)現(xiàn)方案。
XFI[24]利用CFI思想保證控制流的正確性, 并結(jié)合了其他例如內(nèi)存訪問控制, 影子棧等機(jī)制, 將傳統(tǒng)的應(yīng)用程序包裝成XFI模塊, 在運(yùn)行時提供保護(hù)與監(jiān)控, 并通過設(shè)置外部接口與操作系統(tǒng)交互。然而所有的應(yīng)用程序都被封裝成塊, 則被設(shè)計用于共享的動態(tài)鏈接庫就無法使用, 導(dǎo)致運(yùn)行時內(nèi)存有一定的空間損耗。
Hypersafe[25]是最早提出的對虛擬機(jī)監(jiān)控器進(jìn)行CFI保護(hù)的安全機(jī)制。其對監(jiān)控器代碼進(jìn)行分析, 對所有代碼指針的可能調(diào)用位置進(jìn)行計算, 并維持指針?biāo)饕? 在每次指針解引用時查表, 若出現(xiàn)非法目標(biāo)地址就會報錯。對返回地址采用類似的方法。但是只能對直接運(yùn)行在硬件上的1類監(jiān)控器進(jìn)行保護(hù), 在運(yùn)行與宿主操作系統(tǒng)之上的2類監(jiān)控器上無法實(shí)現(xiàn)。
文獻(xiàn)[26]是最早提出的基于智能手機(jī)平臺上的CFI實(shí)現(xiàn)方案, 針對蘋果公司的面向?qū)ο驝語言并且應(yīng)用程序加密存儲。對程序的二進(jìn)制代碼進(jìn)行解密, 反匯編, 繪制控制流圖再對二進(jìn)制代碼進(jìn)行改寫。而文獻(xiàn)[27]是屬于對其的改進(jìn), 在編譯器階段進(jìn)行CFI設(shè)置, 提高了應(yīng)用程序的靈活性。
上述文章都屬于對傳統(tǒng)CFI思想在不同平臺上的實(shí)現(xiàn)與應(yīng)用, 沒有本質(zhì)上的改進(jìn)與創(chuàng)新。
在提出了近10年以后, CFI思想才在商業(yè)領(lǐng)域得到了初步的應(yīng)用, 微軟公司提出了CFG (Control- Flow Guard)技術(shù), 通過編譯器在編譯階段對代碼的分析。在程序運(yùn)行時的每一個間接調(diào)用進(jìn)行檢查, 看目標(biāo)地址是否是一個函數(shù)的開頭[28]。這種方式不屬于傳統(tǒng)細(xì)粒度CFI思想并且對間接跳轉(zhuǎn)與返回指令沒有保護(hù), 存在被繞過的可能。
細(xì)粒度CFI在提出之后之所以一直沒有得到廣泛的應(yīng)用, 是由于其本身還存在不少問題, 比如:
1. 針對諸如內(nèi)核程序上百萬行的代碼, 以及其他的大規(guī)模的程序, 如何精確的畫出其控制流圖, 仍然是一個亟待解決的問題。
2. 傳統(tǒng)的細(xì)粒度CFI要求在程序載入內(nèi)存之前需要對所有的程序模塊進(jìn)行分析并重寫二進(jìn)制代碼加入檢查指令, 包括動態(tài)鏈接庫, 那么每個程序就只能在載入時帶著它們自己重寫好后的庫了, 無法與其他的程序共享, 這與動態(tài)鏈接庫的設(shè)計初衷相悖[29]。
3. 純軟件的CFI實(shí)現(xiàn)方式性能損耗較高。在20%至50%左右[23]。
針對細(xì)粒度CFI存在的這些性能與實(shí)現(xiàn)上缺陷, 研究界也進(jìn)行了許多探討與改進(jìn)。
文獻(xiàn)[29]針對經(jīng)典CFI[23]對動態(tài)鏈接庫無法支持的缺陷, 將ID與地址綁定存在另外一塊內(nèi)存區(qū)中。建立兩個表, 一個映射間接轉(zhuǎn)移指令地址與其ID, 稱為分支表; 另一個表映射各個ID的轉(zhuǎn)移指令的合法目標(biāo)地址, 稱為目標(biāo)表。對每一個間接轉(zhuǎn)移指令, 分別查兩個表, 根據(jù)指令自身地址在分支表中查其ID, 再在目標(biāo)表中根據(jù)轉(zhuǎn)移指令的目標(biāo)地址查ID, 若匹配, 說明通過。若不匹配則報錯。經(jīng)典CFI要求一次性畫出全部程序的CFG, 但是該方法將程序分為多個模塊, 分別為每個模塊畫出CFG, 在加載多個模塊運(yùn)行時, 就會將各個模塊的CFG合并。這種運(yùn)用ID表的方式方便動態(tài)的添加與維護(hù)。能夠較好的解決傳統(tǒng)二進(jìn)制代碼改寫的無法兼容共享庫的缺陷。
文獻(xiàn)[30,31]針對傳統(tǒng)CFI使用純軟件實(shí)現(xiàn)導(dǎo)致?lián)p耗高的缺點(diǎn), 使硬件層次對上層的CFI機(jī)制進(jìn)行支持, 添加了關(guān)于CFI檢查的指令以替代傳統(tǒng)的軟件實(shí)現(xiàn), 能夠大大縮減代碼指令長度并減小了性能損耗。但這種方式會使兼容性降低, 沒有進(jìn)行硬件修改的硬件無法對上層代碼進(jìn)行CFI支持。
文獻(xiàn)[32]將沙箱處理的相關(guān)技術(shù)與CFI進(jìn)行組合, 對CFI繁瑣的檢查機(jī)制進(jìn)行整合簡化, 提高了CFI檢索的速度, 降低了性能損耗。
文獻(xiàn)[33]將CFI在編譯器層次上實(shí)現(xiàn), 對C++中的虛函數(shù)表進(jìn)行保護(hù), 采用靜態(tài)分析, 對虛函數(shù)表進(jìn)行分析, 對目標(biāo)碼進(jìn)行修改, 在調(diào)用虛函數(shù)之前加入一個驗(yàn)證函數(shù)進(jìn)行確認(rèn)。該方法在一定程度上提高了CFI的兼容性并減少了性能損耗。但是僅僅能夠?qū)νㄟ^函數(shù)指針進(jìn)行的函數(shù)調(diào)用進(jìn)行保護(hù), 無法對運(yùn)行時的棧、堆等數(shù)據(jù)結(jié)構(gòu)進(jìn)行保護(hù)。
3.2.2 粗粒度CFI的提出與否定
針對經(jīng)典的細(xì)粒度CFI實(shí)現(xiàn)較困難, 損耗較高的缺陷。學(xué)界提出了一類簡化版的CFI實(shí)現(xiàn)方案。它們通過犧牲一定安全性來達(dá)到可以接受的性能損耗與實(shí)現(xiàn)難度。與先前的細(xì)粒度CFI相比, 這些實(shí)現(xiàn)方案都不需要畫出程序的控制流圖, 可以稱之為粗粒度CFI。
CCFIR[34]重寫目標(biāo)碼, 收集所有合法的跳轉(zhuǎn)指令目標(biāo)地址并將其以隨機(jī)序存儲于一塊獨(dú)立的安全內(nèi)存中, 強(qiáng)制所有的間接跳轉(zhuǎn)指令只能通過這個內(nèi)存區(qū)域完成控制流的轉(zhuǎn)移。CFIMon[35]通過靜態(tài)分析得出合法的跳轉(zhuǎn)地址, 并利用處理器中的分支追蹤存儲機(jī)制(LBR等)來實(shí)時分析控制流的完整性。文獻(xiàn)[36]將間接轉(zhuǎn)移指令替換為到一個外部處理程序的直接跳轉(zhuǎn), 并維持一個合法跳轉(zhuǎn)表, 每次間接跳轉(zhuǎn), 處理程序會查這個表, 只有在表中的目標(biāo)地址才能作為這個間接跳轉(zhuǎn)的目的地。文獻(xiàn)[37]首次將CFI思想在操作系統(tǒng)內(nèi)核上實(shí)現(xiàn)。改寫操作系統(tǒng)代碼, 加入檢查邏輯。文獻(xiàn)[38]采用靜態(tài)分析與動態(tài)監(jiān)測相結(jié)合的方式檢查間接跳轉(zhuǎn)指令的目標(biāo)是否位于合法函數(shù)區(qū)間。
上述幾種方法雖然實(shí)現(xiàn)方法各異, 但是他們都有一個共同的特點(diǎn), 就是不需要畫出程序詳細(xì)的控制流圖并且對于間接跳轉(zhuǎn)目的地址不需要分配唯一ID。僅僅是對程序進(jìn)行靜態(tài)分析, 根據(jù)一定的規(guī)則找到合法的跳轉(zhuǎn)地址, 例如, 所有的ret指令的合法目標(biāo)都是一條call指令下一條指令; 所有的間接調(diào)用目標(biāo)地址都必須是一個函數(shù)的開頭。這就導(dǎo)致任意間接轉(zhuǎn)移指令與他們可能的目標(biāo)地址之間不再遵從邏輯上的一對一關(guān)系, 而是一對多。一條ret指令可以返回到任意一個call指令的下一條指令, 而不必是原本的調(diào)用者; 一條call指令可以進(jìn)入任意一個函數(shù)的開頭, 而不用根據(jù)邏輯進(jìn)行判定究竟應(yīng)當(dāng)跳轉(zhuǎn)到哪一個函數(shù)的開頭。
粗粒度CFI這種對間接跳轉(zhuǎn)目標(biāo)地址不加以再區(qū)分的管理方式, 導(dǎo)致了攻擊者能夠通過精心設(shè)計的配件, 組合配件鏈, 能夠做到繼續(xù)實(shí)施代碼重用攻擊[16,39]。具體使用的配件特點(diǎn)如下: 一種配件以一條call指令的下一條指令為起始, 以ret指令為結(jié)尾, 這種配件可以繞過粗理度CFI對ret指令必須調(diào)到調(diào)用點(diǎn)的檢查機(jī)制; 另一種配件是以一個函數(shù)開頭為起始, 以一個間接跳轉(zhuǎn)指令為結(jié)束的配件, 這種配件可以繞過粗粒度CFI對間接調(diào)用指令必須調(diào)到函數(shù)開頭的檢查機(jī)制。攻擊者將這兩種配件搭配使用, 就可以完全繞開粗粒度CFI的檢查完成攻擊。因此, 粗粒度CFI也被證明無法滿足安全需求而被研究界淘汰。
3.2.3 細(xì)粒度CFI安全性弱點(diǎn)的提出與改進(jìn)
隨著研究界將研究的重點(diǎn)重新轉(zhuǎn)回細(xì)粒度CFI, 研究者又發(fā)現(xiàn)了細(xì)粒度CFI中存在的安全漏洞。
“控制流彎曲”[40]利用細(xì)粒度CFI僅僅保障所有跳轉(zhuǎn)都按照事先通過靜態(tài)分析確定的控制流圖進(jìn)行, 不會對進(jìn)程的上下文語義進(jìn)行分析的缺陷。挑選了一些經(jīng)常使用的并且會對內(nèi)存中的數(shù)據(jù)產(chǎn)生修改的函數(shù)(例如printf()、memcpy()等)通過控制這些函數(shù)的參數(shù)對內(nèi)存中的數(shù)據(jù)進(jìn)行修改, 完成了不逾越控制流圖的控制流劫持, 完成攻擊者所需要的功能。
傳統(tǒng)細(xì)粒度CFI的另一個缺陷是無法對系統(tǒng)產(chǎn)生的信號或中斷的返回進(jìn)行保護(hù), 在類UNIX操作系統(tǒng)中, 這些信號或中斷發(fā)生時, 進(jìn)程原狀態(tài)大多數(shù)是保存在棧上的。SROP[36]利用這種機(jī)制, 通過偽造信號幀來并篡改棧上保存的現(xiàn)場狀態(tài)引導(dǎo)進(jìn)程進(jìn)入到攻擊者設(shè)定的代碼區(qū)域中執(zhí)行實(shí)現(xiàn)攻擊的目的。文獻(xiàn)[41]與[42]也針對細(xì)粒度CFI在實(shí)現(xiàn)上的漏洞提出了繞過的方法。
針對細(xì)粒度CFI存在的安全缺陷, 研究者也對其進(jìn)行了相關(guān)的改進(jìn)。
文獻(xiàn)[43]對所有能夠改變程序控制流的對象進(jìn)行認(rèn)證(包括函數(shù)返回地址, 函數(shù)指針等), 在每次這些對象從內(nèi)存中存儲的時候計算一個驗(yàn)證值, 將其存于一個寄存器中, 每次這些對象被讀取時檢查這個值是否與先前相同。
文獻(xiàn)[44]提出了上下文相關(guān)的CFI, 利用intel CPU中的LBR(Last Branch Record)機(jī)制, 每當(dāng)程序要執(zhí)行重要的系統(tǒng)調(diào)用時(例如exec()等), 則對LBR中保存的先前的跳轉(zhuǎn)指令進(jìn)行CFI判斷, 若全部符合, 則繼續(xù)執(zhí)行, 若有不符合CFG的跳轉(zhuǎn)則會報錯停止執(zhí)行。這種方法能夠解決傳統(tǒng)細(xì)粒度CFI無法對上下文的跳轉(zhuǎn)合法性進(jìn)行判斷的缺陷。
總體來說, 粗粒度CFI安全性不足不能滿足實(shí)際需求。細(xì)粒度CFI機(jī)制尚未完全成熟, 仍然存在安全與性能問題需要克服, 若能達(dá)到低耗, 高兼容性實(shí)現(xiàn), 將會產(chǎn)生較好的保護(hù)效果。
由于代碼重用攻擊的實(shí)現(xiàn)要依賴對內(nèi)存中已有指令的使用。攻擊者需要知道這些指令的確切位置。因此通過增加程序不可知性的方法也可以達(dá)到阻止攻擊的發(fā)生, 使用隨機(jī)化是一個典型并有效的方法。
4.1 隨機(jī)化安全機(jī)制
ASLR(Address Space Layout Randomization)[45]是一個典型且已經(jīng)得到廣泛應(yīng)用的基于隨機(jī)化的防御機(jī)制。其主要思想是通過對進(jìn)程中的代碼段、數(shù)據(jù)段、堆、棧所占的頁面進(jìn)行隨機(jī)化排布來使攻擊者無法得知這些段的具體位置從而無法實(shí)施攻擊。這種方式與數(shù)據(jù)段不可執(zhí)行機(jī)制(DEP)相結(jié)合, 起到了很好的防御效果, 不僅能夠?qū)鹘y(tǒng)的注入攻擊產(chǎn)生防御效果, 也能提高代碼重用攻擊實(shí)施的難度。
但是ASLR仍然存在不足與缺陷, 具體有三點(diǎn):
1. 隨機(jī)化的粒度僅僅到頁一級, 頁內(nèi)的數(shù)據(jù)仍然是順序存儲的, 且參與隨機(jī)化的內(nèi)存地址位數(shù)不足, 能夠被暴力攻破[46,47];
2. 由于動態(tài)鏈接庫的共享機(jī)制, 其位置對所有的程序都是可知的, 這就導(dǎo)致了這些代碼無法參與細(xì)粒度隨機(jī)化處理。防御機(jī)制設(shè)計者只能選擇放棄動態(tài)庫的共享或放棄對這部分代碼的隨機(jī)化處理[48];
3. ASLR面臨內(nèi)存泄露攻擊的威脅, 由于程序代碼段一般都會占用多個頁面, 頁面之間都有跳轉(zhuǎn)指令維持其之間的聯(lián)系。攻擊者若能夠通過懸空指針等漏洞對任意內(nèi)存地址數(shù)據(jù)進(jìn)行讀取, 可以找到頁面之間的相互聯(lián)系, 就可以達(dá)到知曉代碼段頁面的分布位置, 實(shí)現(xiàn)去隨機(jī)化[49]。
由于ASLR極為廣泛的使用和極為突出的弱點(diǎn)與缺陷, 目前大多數(shù)的研究都是著眼于對ASLR的改進(jìn)或以ASLR為標(biāo)尺。在ASLR的基礎(chǔ)上又產(chǎn)生了許多新穎的內(nèi)存隨機(jī)化實(shí)現(xiàn)機(jī)制。
文獻(xiàn)[50]針對ASLR粒度較粗的缺點(diǎn), 對代碼的放置順序進(jìn)行隨機(jī)排布, 粒度達(dá)到了單個指令級。建立一個記錄代碼順序的表, 對每一條指令, 記錄其后繼指令。
文獻(xiàn)[51]在不影響程序運(yùn)行正確性的情況下, 對指令進(jìn)行小范圍的隨機(jī)化處理, 能夠做到消除無意識配件, 重排函數(shù)調(diào)用與返回的寄存器保存和彈出指令。能夠在一定程度上減少攻擊者可以使用的配件數(shù)量。但是這種方法的覆蓋不夠廣泛, 無法完全消除配件。
文獻(xiàn)[52]對二進(jìn)制代碼中的代碼段復(fù)制為兩份, 將原有的代碼段當(dāng)做純數(shù)據(jù), 不可執(zhí)行, 對復(fù)制的部分進(jìn)行分塊, 并在此程序裝載時隨機(jī)化, 并運(yùn)行, 使用相關(guān)的算法保證代碼段中的轉(zhuǎn)移指令的正確性。以此實(shí)現(xiàn)內(nèi)存布局的細(xì)粒度隨機(jī)化。
文獻(xiàn)[53]將進(jìn)程的所有代碼數(shù)據(jù)段分割成任意大小的塊, 然后將這些塊隨機(jī)排布的整個進(jìn)程地址空間。利用二進(jìn)制代碼重寫技術(shù)進(jìn)行重新匯編, 保持控制流指令正確。
文獻(xiàn)[48]對于ASLR的兼容性問題, 使共享代碼實(shí)現(xiàn)隨機(jī)化。首先重寫目標(biāo)代碼, 利用一個間接查找表使控制流轉(zhuǎn)移重定向, 使得所有跳轉(zhuǎn)目標(biāo)都會通過這個表來查找。利用x86的分段機(jī)制保護(hù)間接查找表, 使用特定的段選擇寄存器FS, 只有修改過的合法跳轉(zhuǎn)指令才能找到間接查找表。但這種方式僅僅能夠在x86-32架構(gòu)上實(shí)現(xiàn), 并且無法防御內(nèi)存泄露的攻擊[54]。
文獻(xiàn)[55]與[56]分別在函數(shù)段與程序塊的粒度對內(nèi)存中代碼進(jìn)行隨機(jī)化分布, 增加了參與隨機(jī)化的內(nèi)存地址位數(shù), 提高了隨機(jī)化粒度。
不論實(shí)現(xiàn)方式如何, 上述通過隨機(jī)化增加程序不可知性的安全機(jī)制, 都面臨一個共同的威脅, 那就是內(nèi)存泄露。內(nèi)存泄露能夠幫助攻擊者獲得配件的地址, 對代碼重用攻擊的實(shí)現(xiàn)起到了極大的幫助作用。代碼重用加內(nèi)存泄露是目前最具威脅性的攻擊方式。
4.2 內(nèi)存泄露的威脅與應(yīng)對
傳統(tǒng)的DEP等權(quán)限劃分的安全機(jī)制僅僅是將內(nèi)存頁面的寫操作與執(zhí)行操作分離開來。無論代碼段還是數(shù)據(jù)段都是默認(rèn)可讀的, 這就導(dǎo)致了攻擊者通過懸空指針等程序錯誤對內(nèi)存頁面進(jìn)行讀取、掃描。在代碼段或數(shù)據(jù)段中得到程序隨機(jī)化的分布布局, 從而繞過ASLR等隨機(jī)化安全機(jī)制, 進(jìn)行攻擊。
文獻(xiàn)[49]能夠使用內(nèi)存泄露漏洞, 實(shí)時對隨機(jī)化布局之后的程序代碼段進(jìn)行掃描, 獲悉每個代碼頁確切的起始地址, 計算出可以用作配件的代碼段的地址, 動態(tài)搭建配件鏈實(shí)施攻擊。
內(nèi)存泄露大致分為兩種方式: 一是直接泄漏: 讀取代碼段, 找到直接跳轉(zhuǎn)和直接調(diào)用的目標(biāo)地址, 收集這些地址進(jìn)行分析, 就可以得出代碼頁面的分布位置; 二是間接泄漏: 讀取數(shù)據(jù)段中的函數(shù)指針(例如虛函數(shù)表), 返回地址可以達(dá)到相同的目的[57]。
傳統(tǒng)的寫/執(zhí)行權(quán)限分離思想無法防御內(nèi)存泄露的攻擊, 內(nèi)存泄露又會導(dǎo)致隨機(jī)化安全機(jī)制的失效。因此防御針對內(nèi)存泄露也成為了學(xué)界研究的重點(diǎn)。針對這種威脅, 最初的防御思想是分離讀權(quán)限。但是針對目前的硬件結(jié)構(gòu)來說, CPU無法對頁面的讀權(quán)限進(jìn)行剝離, 需要通過上層的操作系統(tǒng)進(jìn)行支持, 并且傳統(tǒng)的代碼段中是包含數(shù)據(jù)信息的, 如何對代碼段中的數(shù)據(jù)進(jìn)行剝離也是實(shí)現(xiàn)的難點(diǎn)之一。
文獻(xiàn)[58]將讀與執(zhí)行權(quán)限分離。通過改寫MMU中的頁錯誤處理機(jī)制實(shí)現(xiàn)。假如進(jìn)程對內(nèi)存空間中代碼區(qū)中一個不存在的頁面進(jìn)行取指操作, 則說明屬于正常的缺頁異常, MMU會從硬盤中載入這個頁并將頁存在相關(guān)位置。但如果對這個代碼頁進(jìn)行的不是取指操作, 則說明是對代碼頁的讀取, 屬非法, 會導(dǎo)致進(jìn)程停止。能夠?qū)χ苯有孤懂a(chǎn)生防御效果。然而這種防御機(jī)制無法對間接泄露產(chǎn)生防御效果, 無法保護(hù)數(shù)據(jù)段中包含代碼段地址的函數(shù)指針等不會被泄露。
文獻(xiàn)[57]將代碼段與數(shù)據(jù)段嚴(yán)格區(qū)分, 確保代碼段只可執(zhí)行而不再可讀。將代碼段中的數(shù)據(jù)進(jìn)行修改為只執(zhí)行(例如switch轉(zhuǎn)換表, 之前的是跳轉(zhuǎn)的地址, 文章改成跳轉(zhuǎn)到該地址的指令。)實(shí)現(xiàn)代碼只可執(zhí)行可以防止直接內(nèi)存泄露。再將數(shù)據(jù)段中的函數(shù)指針和返回地址都改為代碼段中的一個中轉(zhuǎn)站, 這個中轉(zhuǎn)站通過指令的形式跳轉(zhuǎn)到對應(yīng)的目標(biāo)地址, 通過這種方式防御間接內(nèi)存泄露。這種防御方式在目前來說能夠?qū)?nèi)存泄露起到有效的防御效果。
由于對內(nèi)存代碼段中的數(shù)據(jù)與代碼強(qiáng)行進(jìn)行分離的方法實(shí)現(xiàn)過于困難, 有研究者通過對代碼段進(jìn)行復(fù)制并添加不同的方式實(shí)現(xiàn)對內(nèi)存泄露攻擊的防御。
文獻(xiàn)[59]將可執(zhí)行的代碼段復(fù)制作為數(shù)據(jù)段。當(dāng)有對代碼段中的數(shù)據(jù)進(jìn)行讀取操作時, 就將這段數(shù)據(jù)用隨機(jī)數(shù)代替, 并對MMU進(jìn)行重定向操作, 使之指向復(fù)制的數(shù)據(jù)段。將對數(shù)據(jù)和代碼的操作分割在不同的區(qū)域, 在可執(zhí)行區(qū)的數(shù)據(jù)在讀取后將不會再與原來相同。
文獻(xiàn)[54]先對二進(jìn)制代碼進(jìn)行修改, 將其復(fù)制為兩份, 一份是原有狀態(tài), 一份是經(jīng)過隨機(jī)化排布的, 在每個函數(shù)的調(diào)用和返回階段, 隨機(jī)選取運(yùn)行哪一份的代碼, 這樣即使攻擊者能夠通過泄漏得到內(nèi)存布局, 也無法使構(gòu)造的ROP鏈得到執(zhí)行。
文獻(xiàn)[60]將程序段分為兩個大段, 代碼段和數(shù)據(jù)段。AG作為中間的轉(zhuǎn)接層。將程序中所有的能夠控制代碼執(zhí)行的位置稱為代碼地址, 例如基地址, GOT、PLT的入口、棧中的返回地址, 跳轉(zhuǎn)表等。每當(dāng)有代碼地址將向數(shù)據(jù)區(qū)泄露時, AG對其進(jìn)行加密作為一個標(biāo)識, 每當(dāng)有標(biāo)識被用于控制流跳轉(zhuǎn)時, AG對其進(jìn)行解密。對棧上的數(shù)據(jù)進(jìn)行了保護(hù), 將函數(shù)返回地址等數(shù)據(jù)保存在原有的位置。將棧上的其他數(shù)據(jù)用另一個寄存器指示。
文獻(xiàn)[61]與文獻(xiàn)[58]類似,利用MMU通過軟件實(shí)現(xiàn)對代碼可讀屬性與可執(zhí)行屬性的分離。利用頁錯誤處理程序區(qū)分程序的非法讀操作與正常的指令獲取(Instruction Fetch)。
總結(jié)來說, 基于隨機(jī)化的安全機(jī)制在確保內(nèi)存不被泄露并且隨機(jī)熵足夠高的情況下能夠起到較好的防御效果。
本小節(jié)對現(xiàn)有的對于代碼重用攻擊的防御方式進(jìn)行系統(tǒng)化的總結(jié), 并提出了一種能夠從根本上提升對于代碼重用攻擊防御效果的設(shè)計思路。
對于計算機(jī)系統(tǒng)的攻擊與防御是一對不斷上升與交錯的矛盾雙方: 對于計算機(jī)系統(tǒng)的攻擊催生著防御方式的改進(jìn); 防御方式的改進(jìn)有促使黑客或研究者開發(fā)與使用新的更有效的攻擊方式。
而在對于計算機(jī)防御機(jī)制的設(shè)計與實(shí)現(xiàn)方面。性能與安全又成為了一對矛盾的兩個方面。要提高系統(tǒng)的安全性必然伴隨著性能或兼容性的損耗。能夠平衡這一對矛盾, 在可接受的性能與兼容性損耗限度內(nèi)達(dá)到令人滿意的安全效果的防御機(jī)制才得以廣泛的采用。DEP與ASLR可以成為這種防御機(jī)制的典型, 它們二者組合使用可以做到在較低的損耗的情形大幅度提高攻擊者成功實(shí)施攻擊的難度。
但這兩種防御機(jī)制在代碼重用攻擊與內(nèi)存泄露攻擊的雙重威脅之下其安全效能已經(jīng)不再適用。DEP僅僅能夠防御計算機(jī)系統(tǒng)不受代碼注入的攻擊, 無法對代碼重用攻擊產(chǎn)生防御效果; ASLR本身具有諸多弱點(diǎn)并且面臨內(nèi)存泄露的威脅。研究界對于這種新興的攻擊方式開始了不懈地探索與研究。
5.1 程序行為監(jiān)控
針對代碼重用攻擊的防御, 思路上最簡單的方法是對于程序運(yùn)行時行為的監(jiān)測, 有效實(shí)施這種防御機(jī)制的難點(diǎn)與關(guān)鍵在于快速區(qū)別正常運(yùn)行的程序與遭到攻擊的程序之間運(yùn)行狀態(tài)的差異。
早期的研究者對指令流中出現(xiàn)配件的頻率進(jìn)行監(jiān)控。這種方法能夠?qū)ψ钤嫉腞OP攻擊產(chǎn)生較好的防御效果, 但其本身仍然存在問題, 嚴(yán)格地監(jiān)控會導(dǎo)致大量虛假警報, 而降低敏感度會使攻擊行為被忽視。且攻擊者已經(jīng)開始使用超過被認(rèn)作的配件的長指令段以此稀釋配件出現(xiàn)的頻率將其繞過。
對于配件出現(xiàn)頻率的監(jiān)控?zé)o法進(jìn)行, 研究者開始轉(zhuǎn)而控制進(jìn)程跳轉(zhuǎn)行為的合法性, 傳統(tǒng)細(xì)粒度CFI越來越得到重視。這種機(jī)制安全性較好高, 但存在先天性的性能損耗高, 無法使用動態(tài)鏈接庫等缺陷。于是研究者開始研究能夠?qū)崿F(xiàn)的CFI方案, 出現(xiàn)了粗粒度CFI實(shí)現(xiàn)方案。
粗粒度CFI不需要事先精確分析程序的控制流, 采用了較為寬松的CFI檢查機(jī)制, 得到了性能上的提升, 但是其檢查機(jī)制過于寬松, 無法保障函數(shù)在返回時跳轉(zhuǎn)到的是原先的調(diào)用點(diǎn), 也無法保障函數(shù)調(diào)用時, 所進(jìn)入的函數(shù)體就是原本應(yīng)當(dāng)調(diào)用的函數(shù), 攻擊者就可以利用精心設(shè)計的配件加以繞過。
在粗粒度的CFI實(shí)現(xiàn)方案被否定以后, 研究界繼續(xù)細(xì)粒度CFI的研究。對于細(xì)粒度CFI安全性的質(zhì)疑被提出, 難點(diǎn)依然無法解決: 無法準(zhǔn)確判斷某個跳轉(zhuǎn)屬于程序正常的操作還是被攻擊者劫持, 有攻擊者能夠?qū)崿F(xiàn)不違反控制流圖的攻擊; 由于目前操作系統(tǒng)自身的代碼沒有經(jīng)過CFI強(qiáng)化, 對于從操作系統(tǒng)到用戶代碼的轉(zhuǎn)移沒有檢查, 因此攻擊者可以通過偽造系統(tǒng)調(diào)用或信號幀來實(shí)現(xiàn)對控制流的劫持。
針對程序行為監(jiān)控這種安全機(jī)制的基本思想是使程序按照一定的規(guī)則運(yùn)行, 一旦檢測出程序有違反規(guī)則的行為則認(rèn)作攻擊發(fā)生。兩個關(guān)鍵點(diǎn)分別是監(jiān)控的實(shí)施與規(guī)則的設(shè)定。有些攻擊者通過安全機(jī)制的監(jiān)控盲區(qū)進(jìn)行攻擊[18]; 有些攻擊者則利用規(guī)則的漏洞進(jìn)行攻擊[40]。因此, 能否全面地對程序的行為進(jìn)行監(jiān)控與能否設(shè)定安全高效的規(guī)則, 是決定安全機(jī)制有效與否的關(guān)鍵。而由于計算機(jī)程序的龐雜性、程序運(yùn)行時的狀態(tài)多樣性, 使得這種監(jiān)控的實(shí)施與規(guī)則的設(shè)定具有很高的挑戰(zhàn)性。
5.2 增加程序的不可知性
代碼重用攻擊的另一個防御思想是通過增加程序不可知性使攻擊者無法得知程序代碼的布置方式從而無法構(gòu)建配件地址鏈。主要的實(shí)現(xiàn)方式是進(jìn)行隨機(jī)化排布。然而在進(jìn)行隨機(jī)化的同時還應(yīng)當(dāng)保證程序自身運(yùn)行的正確性。這個過程可以成為去隨機(jī)化(Derandomization), 有些安全機(jī)制例如ASLR[45]通過生成地址無關(guān)代碼與程序裝載時的隨機(jī)化分布來自動實(shí)現(xiàn)隨機(jī)化程序的逆隨機(jī)化; 有些需要一定的內(nèi)存占用與時間開銷來完成隨機(jī)化代碼的去隨機(jī)化例如ILR[50]使用額外的指令流程圖控制每條指令的執(zhí)行。攻擊者可以利用諸如內(nèi)存泄露等方式獲得ASLR隨機(jī)化后的內(nèi)存布局或是ILR的指令流程圖, 進(jìn)而實(shí)現(xiàn)去隨機(jī)化, 找到要用的配件鏈完成代碼重用攻擊。
評價一個隨機(jī)化安全機(jī)制有兩個關(guān)鍵指標(biāo): 程序正常去隨機(jī)化的難度以及攻擊者掌握去隨機(jī)化方法的難度。一個好的隨機(jī)化安全機(jī)制必然是程序自身能夠?qū)崿F(xiàn)簡便的去隨機(jī)化過程, 而攻擊者很難進(jìn)行去隨機(jī)化。
對于內(nèi)存泄露的防御也得到了研究者的重視, 主要的防御思想是分離并限制讀權(quán)限, 例如使代碼段不可讀, 僅可執(zhí)行等。但是傳統(tǒng)的程序代碼段是包含數(shù)據(jù)的, 如何將代碼段中的數(shù)據(jù)剝離也是等待解決的問題。除此之外也有對代碼段進(jìn)行冗余化并采取原份與備份不同處理的方式。
總體來說, 本文認(rèn)為能夠克服諸多限制的細(xì)粒度CFI, 以及能夠有效防范內(nèi)存泄露的隨機(jī)化機(jī)制可以較好地防御代碼重用攻擊。
5.3 代碼重用攻擊根本原因分析與安全機(jī)制設(shè)計思路
代碼重用攻擊的一個重要的原因是控制流被劫持, 許多防御機(jī)制針對如何保護(hù)控制流的完整性, 致力于發(fā)現(xiàn)并制止控制流的被劫持。但這種防御措施僅僅是被動地檢測, 實(shí)際的根本問題是控制流為什么會被劫持。從計算機(jī)系統(tǒng)結(jié)構(gòu)級考慮, 發(fā)生傳統(tǒng)緩沖區(qū)溢出攻擊的根本原因是在程序的執(zhí)行過程中, 對程序的代碼段和數(shù)據(jù)段采取了相同的權(quán)限管理, 所有的頁面都是可讀可寫并可執(zhí)行的。這就導(dǎo)致了攻擊者利用軟件漏洞將自己要執(zhí)行的惡意代碼以數(shù)據(jù)形式注入到內(nèi)存中, 并通過修改控制流使得這些惡意代碼以代碼的形式得到了執(zhí)行。對于數(shù)據(jù)與代碼權(quán)限與處理方式的混淆導(dǎo)致了這種情況的發(fā)生。研究界認(rèn)識到了這種問題, 并提出了數(shù)據(jù)不可知性思想, 即一段內(nèi)存頁不能既可修改, 又可執(zhí)行。并采取相應(yīng)的實(shí)際防御機(jī)制, 即DEP, 使得這個問題得到了很好的解決。
然而攻擊仍在發(fā)生, 只是攻擊者不再將惡意代碼以數(shù)據(jù)的形式注入到內(nèi)存中去, 而是利用內(nèi)存中原有的代碼, 通過控制它們執(zhí)行的順序來達(dá)到自己的目的, 也就是所謂的代碼重用攻擊。數(shù)據(jù)與指令具有極大的關(guān)聯(lián)性, 真正控制指令執(zhí)行的還是數(shù)據(jù)。這些控制指令執(zhí)行的數(shù)據(jù)在內(nèi)存中是以地址或指針的形式存儲的。這些數(shù)據(jù)與傳統(tǒng)的整數(shù)、浮點(diǎn)數(shù)等數(shù)據(jù)類型都被保存在內(nèi)存的數(shù)據(jù)區(qū)中。那么類比針對傳統(tǒng)注入攻擊的分類并采取權(quán)限分離的防御思想, 我們可以對內(nèi)存中的內(nèi)容進(jìn)行再次分類。具體可以分為普通數(shù)據(jù), 例如傳統(tǒng)的char、int類型數(shù)據(jù)等; 普通指令, 即原有意義上的指令; 數(shù)據(jù)地址, 例如指向普通數(shù)據(jù)的指針, 數(shù)組等; 指令地址, 例如函數(shù)指針, 函數(shù)的返回地址、基地址、虛函數(shù)表等。那么如此分類之后, 代碼重用攻擊的根本原因也就顯而易見了——指令地址被篡改。然而攻擊者能夠注入自己數(shù)據(jù)的地方僅僅是在內(nèi)存的普通數(shù)據(jù)段與數(shù)據(jù)地址段中, 但是由于這些數(shù)據(jù)段與指令地址在內(nèi)存中都是按照傳統(tǒng)數(shù)據(jù)這種方式進(jìn)行無差別存儲與管理的, 它們之間沒有邏輯上或空間上的分隔。這就給了攻擊者篡改指令地址的機(jī)會, 導(dǎo)致了代碼重用攻擊的發(fā)生。
依據(jù)這種宏觀思想, 本文提出了一種初步的設(shè)計思路。如圖六所示, 對程序運(yùn)行時棧的結(jié)構(gòu)進(jìn)行重構(gòu), 將原有的棧一分為二: 一個用于保存壓入的普通數(shù)據(jù), 稱之為數(shù)據(jù)棧; 一個用于保存所有的函數(shù)返回地址和基地址, 稱之為地址棧。為兩個棧分別維護(hù)一套棧頂指針與棧幀指針。將地址棧的權(quán)限設(shè)置為只有函數(shù)的調(diào)用與返回階段才會進(jìn)行壓棧與彈棧操作。將地址棧的位置置于數(shù)據(jù)棧的地址減小方向, 這樣即使攻擊者利用漏洞對棧中的緩沖區(qū)進(jìn)行溢出, 也不會覆蓋到地址棧中函數(shù)的返回地址。
為了初步實(shí)現(xiàn)這種設(shè)計思路, 本文給出兩種方案: 第一種在硬件上實(shí)現(xiàn), 增加兩條機(jī)器指令分別對新的數(shù)據(jù)棧進(jìn)行壓棧與彈棧操作, 從原有的寄存器中保留兩個用于保存數(shù)據(jù)棧的棧頂?shù)刂放c棧幀地址, 將原有的壓棧與彈棧指令改為對新的數(shù)據(jù)棧進(jìn)行的操作, 原有的棧作為地址棧?;蚴菍all指令與ret指令進(jìn)行修改, 將壓入原有棧中的返回地址壓入新的地址棧中, 原有的棧作為數(shù)據(jù)棧; 第二種是用軟件實(shí)現(xiàn), 與文獻(xiàn)[60]中的AG-Stack類似, 由編譯器用mov與sub(add)指令組合來模擬對新開辟的數(shù)據(jù)棧的壓(彈)棧操作, 原有的棧作為地址棧。采用軟件實(shí)現(xiàn)的方式與硬件實(shí)現(xiàn)相比, 能夠產(chǎn)生較少的兼容性損耗和較高的性能損耗。硬件實(shí)現(xiàn)需要對底層的指令架構(gòu)進(jìn)行修改, 兼容性變差, 但是產(chǎn)生的性能損耗較低。這樣將棧結(jié)構(gòu)分開并處以不同的處理方式, 可以有效避免攻擊者利用漏洞對保存在棧中的函數(shù)返回地址等指向指令的數(shù)據(jù)進(jìn)行篡改, 從而大幅增加了實(shí)現(xiàn)代碼重用攻擊的難度。
本小節(jié)提出的設(shè)計思路僅僅是一種構(gòu)想, 具體實(shí)現(xiàn)的細(xì)節(jié)仍然有待完善。
導(dǎo)致計算機(jī)系統(tǒng)不安全的原因是沒有相應(yīng)權(quán)限的訪問與修改: 攻擊者能夠讀取本來不應(yīng)該被讀取的部分, 導(dǎo)致了內(nèi)存泄露攻擊; 通過在普通數(shù)據(jù)區(qū)的溢出修改了控制程序運(yùn)行的指令地址段, 導(dǎo)致了代碼重用攻擊。這些都是權(quán)限劃分不清, 處理方法模糊造成的安全隱患。那么針對這些問題就可以通過權(quán)限與處理方式再細(xì)化的思想予以解決。假如通過安全機(jī)制的設(shè)計能夠?qū)崿F(xiàn)普通數(shù)據(jù)與指令地址在邏輯上或空間上隔離, 將有效的阻止代碼重用攻擊的發(fā)生。
本文介紹了代碼重用攻擊的起源與三種主要的實(shí)現(xiàn)方式。系統(tǒng)化的闡述了目前應(yīng)對這種攻擊的兩類防御思想: 針對程序行為的監(jiān)控思想以及增加程序的不可知性的思想, 以及它們在研究與實(shí)現(xiàn)過程中遇到的困難與解決方式。其中, 對程序行為監(jiān)控的思想又可以分為針對配件頻率的監(jiān)控與程序控制流完整性的監(jiān)控; 增加程序不可知性的思想以ASLR為代表, 介紹了實(shí)現(xiàn)過程中遇到的問題以及能夠使這種安全機(jī)制失效的內(nèi)存泄露攻擊, 并介紹了針對內(nèi)存泄露攻擊的防御機(jī)制。最后, 對這兩類防御思想進(jìn)行了深入且詳細(xì)的分析, 并提出了一種新的能夠提升對代碼重用攻擊防御效果的安全機(jī)制設(shè)計思想。
[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. (代偉, 劉智, 劉益和, “基于地址完整新檢查的函數(shù)指針攻擊檢測”,, 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攻擊的函數(shù)粒度隨機(jī)化防御方法的設(shè)計與實(shí)現(xiàn)[碩士學(xué)位論文]. 南京: 南京大學(xué)軟件學(xué)院, 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攻擊的塊粒度地址空間隨機(jī)化防御技術(shù)的研究[碩士學(xué)位論文]. 南京: 南京大學(xué)軟件學(xué)院, 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.(楊超, 王清賢, 魏強(qiáng), “基于可執(zhí)行內(nèi)存不可讀屬性的防代碼重用技術(shù)”,, 2016,17(1):59-64.)
柳童 于2013年在西安電子科技大學(xué)計算機(jī)科學(xué)與技術(shù)專業(yè)獲得學(xué)士學(xué)位?,F(xiàn)在中國科學(xué)院信息工程研究所系統(tǒng)結(jié)構(gòu)專業(yè)攻讀博士學(xué)位。研究領(lǐng)域?yàn)橛嬎銠C(jī)系統(tǒng)安全。研究興趣包括代碼重用攻擊、系統(tǒng)防御等。Email: liutong9017@iie.ac.cn史崗 于2004年在中國科學(xué)院計算技術(shù)研究所計算機(jī)體系結(jié)構(gòu)專業(yè)獲得博士學(xué)位。現(xiàn)任中國科學(xué)院信息工程研究所第五研究室高級工程師。研究領(lǐng)域?yàn)橛嬎銠C(jī)系統(tǒng)安全。研究興趣包括計算機(jī)架構(gòu), 計算機(jī)芯片安全等。Email: shigang@iie.ac.cn 孟丹 于1995年在哈爾濱工業(yè)大學(xué)獲得計算機(jī)體系結(jié)構(gòu)專業(yè)博士學(xué)位?,F(xiàn)任中國科學(xué)院信息工程研究所所長。研究領(lǐng)域包括計算機(jī)系統(tǒng)安全, 大數(shù)據(jù)與云計算等。研究興趣包括計算機(jī)系統(tǒng)安全, 云計算安全等。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