王奕森 舒 輝 謝耀濱 趙利軍
(信息工程大學數學工程與先進計算國家重點實驗室 河南 鄭州 450001)
?
基于指令集隨機化的代碼注入型攻擊防御技術
王奕森舒輝謝耀濱趙利軍
(信息工程大學數學工程與先進計算國家重點實驗室河南 鄭州 450001)
摘要針對當前代碼注入型攻擊防御機制容易被繞過的現狀,提出一種基于指令集隨機化的防御技術。該技術制定了指令集隨機化規則,利用該規則改變obj文件中的指令,從而實現了指令集的隨機化。外部注入代碼與生成的指令集不兼容,經過動態二進制分析平臺翻譯后,程序代碼正常執行而注入代碼變為亂碼。基于該技術設計了一套原型系統,并通過大量實驗表明可以防御大部分代碼注入型攻擊。該技術打破了緩沖區溢出漏洞利用所需要的穩態環境,實現了對攻擊的主動防御。
關鍵詞代碼注入型攻擊指令集隨機化動態二進制分析主動防御
0引言
計算機科學技術高速發展,在給人們帶來便利的同時信息安全的問題困擾著每一位計算機用戶[1]。軟件結構越來越復雜,而軟件中各種漏洞及被惡意植入的后門層出不窮,相對應的防御機制一直處于被動地位,這種不對等的攻防形勢致使互聯網用戶每天都處在不安全的環境之中。攻擊者的一般攻擊方法是利用軟件中存在的漏洞去攻擊用戶,在用戶主機上執行惡意植入的惡意代碼,從而完成特定的攻擊行為。
挖掘軟件中潛在的緩沖區溢出漏洞,對提升信息系統的安全性具有重要意義。現有的軟件漏洞挖掘技術中面向源代碼的漏洞挖掘技術研究最早也最成熟,但面向源代碼的軟件漏洞挖掘技術仍存在很多不足[2]。由于漏洞不可能被消除,只能通過各種措施進行緩解[3]。因此,目前對漏洞攻擊的防御策略主要是基于先驗知識的被動防御,而且大多可以被攻擊者繞過,防御效果不理想。其根本原因在于軟件程序的同構性和運行環境的穩定性,指令集的穩定是運行環境穩定的重要因素。而隨機化技術可以有效打破這種同構和穩定性的環境,以異構和隨機的環境來應對未知的攻擊。PaX項目在2001年首先提出了ASLR(address space layout randomization)技術,2003年Gabriela等人提出了指令集隨機化技術,2010年Georgios等[4]人對ELF文件格式的程序實現了指令集隨機化。Bhatkar提出了數據隨機化技術。這些技術有的已經在信息安全領域發揮了巨大作用,如ASLR技術;但有的技術則沒有被利用,如指令集隨機化技術。因為Georgios提出的這套技術通過對指令進行異或加密再使用虛擬機翻譯執行,一方面開銷很大,另一方面該技術假設在obj文件中指令與數據分離,目前只在ELF文件中基本實現這種指令集隨機化。
本文提出一種基于Phoenix編譯器的指令集隨機化技術,該技術通過新生成的指令集來隨機化程序中的指令,為程序提供了一個隨機、動態和不確定的運行環境,實現了操作碼層次的指令集隨機化。外部注入代碼與新指令集不兼容,即使成功注入攻擊代碼也無法正常運行,可能會導致拒絕服務但無法得到任何有用信息。實驗表明該技術可以在低空間和時間開銷的前提下有效地防御代碼注入型攻擊。目前已經利用該技術實現了X86架構下Windows系統程序的指令隨機化,該技術同樣可以適用于X86架構下Linux系統程序的指令隨機化。
1代碼注入型攻擊及防御策略
代碼注入型攻擊[5]是目前最常見而且破壞性很大的攻擊,攻擊者通過一定的方法將惡意代碼注入到用戶的進程,并通過溢出等手段改變程序正常的控制流,使程序執行惡意代碼從而實現某種攻擊目的。國內外學者對代碼注入型攻擊及其防御策略做了大量的研究工作[6-8]。目前最常見的代碼注入型攻擊分為棧溢出攻擊和堆溢出攻擊。文獻[9]從C語言程序角度總結了棧溢出攻擊的三種基本攻擊模式。2000年,Solar designer第一個實現了堆溢出利用。2001年,Flake提出TEB的利用方法。2005年,Falliere[10]提出通過RtlDeleteCriticalSection覆蓋堆臨界區結構的方法繞過防御。2008年,Hawkes[11]提出堆結構覆蓋和LFH bucket/header覆蓋等技術可以在一定程度上突破現有堆保護技術。
對棧溢出攻擊的防御有在關鍵數據和緩沖區之間加入一個隨機的canary字的Stack Guard[12]防御策略及其衍生出的防御策略;構建與普通棧隔絕的全局返回地址堆棧的Stack Shield防御策略;在棧幀中引入隨機長度的填充區使攻擊者無法準確定位函數返回地址或調用方函數EBP的防御策略。對堆溢出攻擊的防御[13]有安全摘除鏈表檢測鏈表完整性;在堆頭部增加安全cookie;對PEB/TEB的地址做有限隨機化;移除lookaside表和FreeList[0];堆塊元數據加密;動態改變堆分配算法;函數替換與指針編碼等多種堆溢出攻擊防御方法。
這些防御策略有共同的兩個弱點:① 在一定條件下,攻擊者可以采用特定的攻擊手段突破這些防御;② 這些防御都有單一不變性。這就造成防御策略與被防御目標程序的綁定存在,攻擊者一旦獲取待攻擊程序的二進制代碼,就能夠通過學習獲得待攻擊程序采用的所有防御機制。
2基于指令集隨機化的代碼注入型攻擊防御
代碼注入型攻擊向程序中注入攻擊代碼,并在軟件漏洞被觸發時改變程序控制流執行攻擊代碼。代碼注入型攻擊的成功需要有一個穩定的攻擊環境,模塊基址的改變或指令的變換都會在不同程度上影響攻擊的成功率。本文提出了一種基于指令集隨機化的代碼注入型攻擊防御思想,該思想是利用隨機化指令集對obj文件中的指令進行隨機改變,攻擊者不了解這套指令集規則,使外部注入的代碼與新的指令集不兼容,經過動態二進制分析平臺翻譯時正常代碼被翻譯為可執行代碼而惡意代碼則被翻譯為亂碼。與以往的防御策略相比,該防御思想打破了漏洞攻擊所需要的穩態環境,每次編譯都使用不同的指令集,實現了防御策略與被防御目標的分離,使攻擊者很難攻擊成功。該防御思想的原理如以下公式,其中f為指令隨機化函數,source為程序源代碼,rand為經過隨機化的程序,f'為動態二進制平臺翻譯指令函數。惡意代碼沒有進過f函數的轉化,直接用f'處理,被翻譯為無用代碼。
f(source) = rand
f′(rand) = source
f′(malcode) = unknown
基于該主動防御思想,本文提出一種修改obj文件的指令集隨機化技術。該技術利用新的指令集隨機化改變編譯器產生的obj文件中的指令而達到指令隨機化的目的。為了準確定位指令在obj文件中的位置,需要利用Phoenix編譯器在編譯過程中提取出程序的匯編指令信息,并利用該信息與obj文件中代碼段信息進行匹配,生成指令隨機變換規則,如果匹配成功則為指令加上段偏移從而定位了指令位置。完成所有指令的匹配工作后,對obj中的指令按照所制定的規則進行變換,并將變換后的指令回寫入obj。所有的obj文件經過鏈接后生成經過隨機化處理的可執行文件,該可執行文件需要利用動態二進制分析平臺啟動,在一定指令變換規則的支持下將程序中經過隨機變換的指令翻譯回正常X86指令并運行程序。圖1為指令集隨機化流程圖。在上述過程中,所用到的關鍵技術有源程序匯編指令信息的提取;制定指令變換規則;obj文件解析及指令定位;隨機化程序執行。這些技術的實現將在下文進行敘述。

圖1 指令集隨機化流程圖
2.1基于Phoenix的匯編指令提取
匯編指令提取主要是在Phoenix編譯器編譯目標程序的后期,即將程序信息寫入obj階段,提取出目標程序的匯編指令信息,為下一步定位obj文件中的指令位置做準備。
Phoenix是微軟提供的一個編譯器框架,用戶可以通過Phoenix設計編譯器及各種工具用于軟件程序的分析、優化和測試。源代碼經過Phoenix分析,被表示為IR(中間表示,Intermediate Representation)形式,Phoenix編譯器和各種基于Phoenix的工具對程序后期的處理工作都是在IR層次上進行的。與其他編譯器不同,Phoenix可以為微軟支持的所有語言和平臺生成二進制文件或MSIL代碼。同時Phoenix提供了豐富的API接口函數,用戶可以利用Phoenix提供的API函數開發自己想要的工具。圖2為Phoenix編譯器框架圖。

圖2 Phoenix編譯器框架圖
與其他編譯器相同,Phoenix對源文件進行編譯會生成目標對象文件(obj文件),為了避免反匯編帶來的不確定性,使指令隨機化更加準確,本文提出了在obj文件中進行指令隨機化的方法。為了精確定位指令在obj文件中的位置,需要通過Phoenix提供的API函數編寫一個源程序匯編代碼自動化提取插件,在Phoenix后期處理的Emission階段(phase)之后插入一個匯編代碼提取階段Getasm階段。根據提取出來的匯編代碼結合obj文件信息可以準確定位各條指令的地址。
算法1
input:source, Getasm phase
output:file.asm
1)Compile program with phoenix
2)if FindByName(“Emission”) then do
3)InsertAfter(Getasm);
4)end;
5)Execute Getasm phase
6)if unit is functionunit then do
7)While !insnislast do
8)If insn is realinstruction then do
9)Insn.offset ← get(offset);
10)Insn.opcode ← get(opcode);
11)Insn.asm ← get(asm);
12)file.asm ← Insn;
13)end;
14)end;
算法1利用Phoenix編譯器提取程序的匯編指令,其中FindByName()為找phase函數,IsertAfter()為插入phase函數,兩個函數均為Phoenix編譯器提供的API函數,file.asm為存取匯編指令信息的文件。Phoenix對程序分模塊編譯,Getasm為插入的phase,當執行到Getasm時開始匯編指令信息提取。算法中結構體Insn的定義如下:
typedef struct asm_insn_info
{
uint32 offset;
uint32 opcode;
string asm;
}Insn;
2.2obj文件解析及指令定位
obj文件為程序經過編譯器編譯生成的目標文件,包含程序中的指令、數據等信息。解析obj文件需要從obj文件中的代碼段提取出段偏移、大小等信息,并結合已經提取出的指令信息定位指令在obj文件中的位置,進而根據變化規則完成指令隨機化工作。
指令變換規則的制定需要滿足以下幾點條件:1) 有效性。指令進行隨機化后,在DynamoRIO進行翻譯時會進行語義檢查,如果語義錯誤將無法正常執行。2) 細粒度性。隨機化的粒度應盡可能細,粗粒度的防御策略已經很多,且容易被攻擊者繞過。3) 開銷可控性。指令集隨機化要求在增加安全的情況下控制開銷,代價過大將使工作失去意義。為滿足以上要求,本文采取對指令集分層隨機化策略,經過對IA-32 Inter指令集中1099個指令進行篩選分類,將可隨機化的指令組成一個集合ISRInsn。集合ISRInsn中有四個子集: OnebyteInsn、TwobyteInsn、OperateOnebyte、OperateTwobyte,分別表示單字節指令、雙字節指令、操作碼單字節長度相等指令、操作碼雙字節長度相等指令。OpercodeOnebyte與OpercodeTwobyte又可按照指令長度分成若干子集。表1為選取的部分隨機指令分組表。
ISRInsn = { OnebyteInsn,TwobyteInsn,OpercodeOnebyte,OpercodeTwobyte }

表1 部分隨機指令分組表
目標對象文件(.obj文件)中包含了編譯后的機器指令代碼、數據,以及鏈接時所需要的各種信息,這些信息在obj文件中按照屬性的不同以段(segment)的形式進行存儲。機器指令被放在代碼段(.text和.textx),全局變量和局部靜態變量數據被放在數據段(.data)。本文通過解析obj文件映像頭和段落頭來獲取段名、段落頭數以及代碼段的偏移大小等信息,為指令隨機化做準備。圖3為指令隨機變換示意圖。

圖3 指令隨機變換示意圖
算法2
輸入:選取的隨機指令、obj文件、asm文件
輸出:isr.config
1) 對指令按不同集合進行分組,并存入不同數組中;
2) 對不同數組中指令的順序進行隨機化,得到順序隨機的指令數組;
3) 對每一組指令進行雙雙配對存入一個結構體,并將所有指令壓入vector容器中,寫入指令規則rule.config之中;
4) 解析obj文件:將obj文件映射到內存之中,根據obj文件格式讀取obj文件中.text段與textx段,提取段名、段大小和段偏移等信息,分別存入兩個鏈表List text與List textx;
5) 讀取.asm文件,并提取text、textx段中指令的偏移、操作碼和匯編指令,存入結構體并壓入vector容器Instruction_all中;
6) 將Instruction_all中的指令與鏈表中節點進行匹配,若匹配上則為指令加上段偏移地址,若未匹配則進行下一個節點匹配,直至所有節點都被匹配,所有指令匹配結束壓入一個map中,并將結果寫入文件;
7) 在obj中按照制定的隨機變換規則對選取的指令進行隨機變換,并將隨機變換的指令回寫入obj文件。
2.3隨機化程序執行
經過隨機化處理的程序不能直接執行,需要利用動態二進制分析平臺將被隨機化的指令動態翻譯回正常的X86指令。本文利用了DynamoRIO平臺。
DynamoRIO可以在指令級別上對程序動態分析,采用代碼緩存技術將程序代碼拷貝到代碼緩存,進而對目標程序模擬執行,在執行過程中修改目標程序的二進制代碼,達到指令級分析的目的。本文對目標程序進行指令級插樁,在目標程序的地址范圍內讀取基本塊中的每一條指令進行判斷,如果是經過變換的指令則按照規則翻譯回正常指令,如果不是則讀取下一條指令,直到所有指令被翻譯回正常指令。
隨機化程序執行流程如下:
1) 利用動態二進制平臺啟動目標程序;
2) 讀取隨機指令變換規則;
3) 主模塊加載時(event_module_load)獲取主模塊的起始和結束地址;
4) 讀取當前基本塊的當前指令,根據指令操作數判斷該指令是否為指令變換規則中的指令,如果是則讀取出變換目標指令操作碼,如果不是則讀取下一條指令;
5) 根據目標指令操作碼創建目標指令,并獲取目標指令的源操作數與目的操作數;
6) 進行指令替換;
7) 循環執行(4),直至所有指令被翻譯為正常指令。
2.4系統設計與實現
為驗證該技術的可行性,本文設計了一套原型系統。圖4為系統設計原理圖。該系統主要分為四個模塊:信息提取模塊、指令隨機變換模塊、隨機策略支撐模塊、動態翻譯模塊。

圖4 系統設計原理圖
3實驗過程及結果分析
通過實驗驗證原型系統的有效性,并分析經過隨機化后程序的時間開銷與空間開銷。實驗條件:兩臺裝有XP系統的虛擬機A、B橋接互連。A主機用作攻擊者主機,安裝metasploit 3和python2.7;B主機用作被攻擊者的主機,安裝DynamoRIO。
實驗一對Miniweb植入shellcode打開計算器
在Miniweb源碼中構造一個緩沖區溢出漏洞,并用metasploit構造攻擊腳本進行攻擊。配置metasploit攻擊載荷參數:windows/exec(執行任意的cmd命令),測試其啟動計算器的功能。執行exploit命令,Miniweb程序被關閉,彈出了計算器窗口,攻擊成功。經過系統防護后,用DynamoRIO平臺運行,Miniweb崩潰。
實驗二利用Miniweb上傳木馬測試
使用相同的攻擊腳本對Miniweb進行攻擊。生成灰鴿子服務程序,在meterpreter提示符下完成灰鴿子服務端的上傳,執行木馬程序。打開灰鴿子控制端程序,點擊自動上線,攻擊成功,退出meterpreter。使用系統的防護措施后,攻擊失敗。
圖5、圖6為Miniweb經過指令隨機化處理前后指令片段對比,經過隨機化處理后Miniweb程序的指令按照指令變換規則進行了隨機變換。

圖5 Miniweb指令隨機化前指令片段

圖6 Miniweb指令隨機化后指令片段
結果分析:
經過原型系統隨機化過的軟件,其安全性能得到了很大的提高,可以防御絕大多數的代碼注入型攻擊,該系統為軟件提供了一個隨機、多態和不確定的運行環境,打破了各類漏洞利用所需要的穩態環境,實現了一種主動式的軟件抗攻擊技術。通過大量測試表明該系統能夠防御大多數代碼注入型攻擊,表2為部分測試結果。經過隨機化處理后軟件的時間開銷與空間開銷會相應增大,圖7、圖8為四種軟件經過隨機化處理前后時間和空間開銷對比圖。以Miniweb為例進行說明,Miniweb程序指令條數在四種軟件中最多,其被隨機化的指令條數最多,在動態解釋執行時翻譯指令消耗時間較長,所以時間和空間開銷都較大。Miniweb在執行cmd和上傳木馬兩種不同的攻擊時,上傳木馬的攻擊行為較為復雜,其時間開銷與空間開銷較大。由此可知,隨機化后軟件的開銷會受其指令條數的影響,指令條數多的軟件,其時間空間開銷較大。同一軟件受到的攻擊行為越復雜,其時間空間開銷越大。總體來說,增大的開銷在軟件運行可接受的范圍內。

表2 部分實驗測試結果
注:運行時間、內存消耗效率是指本系統處理后的軟件運行時間、內存消耗值與未經本系統處理軟件運行時間、內存消耗值的比值

圖7 隨機化前后時間開銷對比

圖8 隨機化前后空間開銷對比
4結語
本文提出了一種指令集隨機化技術,該技術在編譯層對程序指令進行隨機化改變,為軟件構建出一個隨機、動態和不確定的運行環境,打破了各類漏洞利用所需要的穩態環境,對代碼注入型攻擊不再關心代碼如何注入到進程,而是阻止惡意代碼被執行從而對軟件進行防護。設計并實現了一套原型系統,并通過大量實驗證明,該技術可以成功防御大部分代碼注入型攻擊,改變了被動防御局面實現了主動防御。
參考文獻
[1] 國家互聯網應急中心.互聯網網絡安全熱點問題分析[J].互聯網天地,2013(5):85-93.
[2] Balakrishnan G,Reps T.Wysinwyx:What you see is not what you execute[J].ACM Transactions on Programming Languages and Systems (TOPLAS),2010,32(6):23.
[3] 魏強,韋韜,王嘉捷.軟件漏洞利用緩解及其對抗技術演化[J].清華大學學報:自然科學版,2011,51(10):1274-1280.
[4] Portokalidis G,Keromytis A D.Fast and practical instruction-set randomization for commodity systems[C]//Proceedings of the 26th Annual Computer Security Applications Conference.ACM,2010:41-48.
[5] Ray D,Ligatti J.Defining code-injection attacks[C]//ACM SIGPLAN Notices.ACM,2012,47(1):179-190.
[6] Son S,McKinley K S,Shmatikov V.Diglossia:detecting code injection attacks with precision and efficiency[C]//Proceedings of the 2013 ACM SIGSAC conference on Computer & communications security.ACM,2013:1181-1192.
[7] Younan Y,Joosen W,Piessens F.Runtime countermeasures for code injection attacks against C and C++ programs[J].ACM Computing Surveys (CSUR),2012,44(3):17.
[8] Snow K Z,Krishnan S,Monrose F.SHELLOS:Enabling Fast Detection and Forensic Analysis of Code Injection Attacks[C]//USENIX Security Symposium,2011.
[9] Jiang J,Zhang L,Jin T,et al.Dynamic buffer overflow prevention based on k circular random sequence[J].Journal of Tongji University.Natural Science,2010,38(6):917-924.
[10] Falliere N.A new way to bypass Windows heap protections[J].Security Focus White Paper,2005.
[11] Hawkes B.Attacking the Vista Heap[C].Blackhat USA.(Aug.2008),2008.
[12] Cowan C,Pu C,Maier D,et al.StackGuard:Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks[C]//Usenix Security,1998,98:63-78.
[13] Li L,Just J E,Sekar R.Address-space randomization for windows systems[C]//Computer Security Applications Conference,2006.ACSAC’06.22nd Annual. IEEE,2006:329-338.
DEFENSE TECHNOLOGY AGAINST CODE-INJECTION ATTACKS BASED ON INSTRUCTION SET RANDOMISATION
Wang YisenShu HuiXie YaobinZhao Lijun
(StateKeyLaboratoryofMathematicalEngineeringandAdvancedComputing,PLAInformationEngineeringUniversity,Zhengzhou450001,Henan,China)
AbstractFor current status quo that code-injection attack defense mechanisms are easily bypassed by attackers, we proposed a new defense technology which is based on instruction set randomisation. In this technology, we drew up randomisation rules of instruction set, that could be used to change the instructions in objs files so as to implement the randomisation of instruction set. The external injection codes are not compatible with the generated instruction set, when translated by the dynamic binary analysis platform, the program codes can be executed as usual but the injected codes become the disordered codes. Based on this technology we designed a set of prototype systems, and demonstrated through a large number of experiments that it was able to defense most of code-injection attacks. This technology breaks through the steady environment needed by exploiting the buffer overflow vulnerabilities and achieves the proactive defense against attacks.
KeywordsCode-injection attackInstruction set randomisationDynamic binary analysisProactive defense
收稿日期:2014-12-04。國家高技術研究發展計劃項目(2009 AA012200)。王奕森,碩士生,主研領域:信息安全。舒輝,教授。謝耀濱,博士生。趙利軍,碩士生。
中圖分類號TP309.1
文獻標識碼A
DOI:10.3969/j.issn.1000-386x.2016.05.077