论文部分内容阅读
近年来,一些针对软件漏洞利用的防范技术已经得到了广泛部署。典型地,数据执行保护机制(Data Execution Prevention,DEP)被 Windows 和 Linux等主流操作系统用于防范传统的代码注入攻击。DEP通过设置内存页面不能同时具有可写可执行属性,让攻击者不能以输入数据的方式注入并执行shellcode。现在攻击者普遍应用代码复用技术来绕过DEP。代码复用技术利用受害进程地址空间中已有的代码片段(称为gadget)来构造功能代码。返回导向编程(return-oriented programming,ROP)是一种典型的代码复用技术:它通过复用以ret指令结束的代码片段来构造功能代码。当前,主流系统主要通过部署址空间布局随机化(Address Space Layout Randomization,ASLR)机制来缓解代码复用攻击。ASLR将代码模块加载到随机选择的地址空间,让代码片段的地址拥有不确定性,因此可以显著地提高代码复用攻击的难度。本文以Ubuntu系统为例,研究在DEP和ASLR普遍实施的情况下,代码复用攻击技术对主流系统构成的安全威胁。同时,本文提出一个可行的代码复用攻击检测方案。本文具体研究内容如下:●图灵完备功能的普遍可构造性。构造功能复杂的ROP代码比编写shellcode困难得多。在构造ROP代码的过程中,如果缺少某种类型的gadget或不能消除gadgets之间的副作用,都会导致构造失败。在图灵基本功能中,实现条件跳转逻辑是构造ROP代码的一个难点;传统方法需要使用数十个不同的gadgets来实现该功能。本文突破了对条件转移机器指令的传统认知,指出使用条件转移机器指令开始的代码片段(称为if-gadget)能够帮助ROP代码实现条件转移逻辑,而且使用if-gadget能够极大地简化ROP构造条件转移逻辑功能的过程。实验结果证实:引入if-gadget后,图灵完备功能在软件模块中普遍可构造。在Ubuntu等操作系统上,虽然动态库都支持ASLR,但可执行二进制程序普遍地并不支持ASLR,因此攻击者可以通过串接在这些程序上找到的gadgets来构造纯ROP攻击代码,实现恶意功能。●基于Javascript脚本代码块的gadget注入。现代浏览器不但提供脚本执行环境,而且还支持即时编译机制。脚本执行环境有利于攻击者发动即时返回导向编程(just-in-time ROP,JIT-ROP)来绕过ASLR和DEP。同时,即时编译机制为攻击者向浏览器进程注入自定义的gadgets提供了便利。注入自定义的gadgets可以极大地简化攻击者构造ROP代码的难度。通过常数致盲等去毒化处理,现有的基于常数的gadget注入已经得到有效遏制。本文证实不使用常数,转而通过填充Javascript脚本代码块也能实施gadget注入,并得到图灵完备的gadget集合。我们发现,在编译一段给定的Javascript脚本代码时,即时编译器生成的动态代码(机器码)中通常存在着一些固定的指令序列。这些指令序列的存在性不受常数致盲和地址空间布局随机化等安全机制的影响,而且它们可能蕴涵着攻击者期望的gadgets。因此,攻击者在实施攻击时可以把特定的Javascript脚本代码片段填充到攻击脚本中,借助即时编译器来注入gadgets,为发动JIT-ROP攻击提供素材。●硬件辅助的细粒度代码复用攻击检测。代码复用攻击典型地通过串接以间接控制流指令结束的代码片段来构造恶意代码,因此通过检查控制流指令的每次执行是否会导致控制流完整性违规能够有效地检测出代码复用攻击。本文通过巧妙地组合x86处理器上的硬件特性,实现了一种支持分支指令类型过滤的控制流监控机制,且在该机制的基础上实现了一个代码复用攻击检测方案。具体地,使用硬件来跟踪间接控制流指令的每一次执行,即记录其跳转的源地址和目标地址;同时,通过即时地对照细粒度的控制流图来检查每次控制流转移的合法性。在Ubuntu系统上试验表明,该方案可以有效地检测到攻击。对一组典型的服务器应用程序的实验结果表明,该方案引入大约2.9%的微小性能开销。