基于指令集随机化的代码注入型攻击防御技术

2016-06-08 05:49王奕森谢耀滨赵利军
计算机应用与软件 2016年5期
关键词:指令集编译器攻击者

王奕森 舒 辉 谢耀滨 赵利军

(信息工程大学数学工程与先进计算国家重点实验室 河南 郑州 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

猜你喜欢
指令集编译器攻击者
基于Kubernetes的RISC-V异构集群云任务调度系统①
机动能力受限的目标-攻击-防御定性微分对策
3DNow指令集被Linux淘汰
基于相异编译器的安全计算机平台交叉编译环境设计
正面迎接批判
实时微测量系统指令集及解析算法
Microchip为MPLAB XC系列专业版编译器推出低成本可续订包月许可证
有限次重复博弈下的网络攻击行为研究
什么是AMD64
通用NC代码编译器的设计与实现