论文部分内容阅读
当前网络空间安全形势严峻,基于信息系统漏洞的攻击事件频发,对国家安全和个人利益构成严重威胁;而移动互联网的兴起,在加速信息化发展的同时,也为传统的系统安全、软件安全带来了新的挑战。在现有系统和软件的安全体系下,软件内存漏洞不可避免;已有的防御、缓解和检测方法出于性能和覆盖面等方面的限制,也难以消除内存漏洞攻击威胁。而代码重用攻击作为内存漏洞利用中的关键技术,其基于内存中已有指令片段实现目标功能的程序逻辑表达方式能够绕过现有系统中内存不可执行、代码签名等防护机制;其灵活的程序逻辑组织方式能够避开已有的基于特征和基于行为的检测方法。因此,本文以软件安全领域的二进制代码重用为研究对象,重点研究针对代码重用攻击的防御和检测方法,最小化其所造成的安全威胁。具体研究工作包括如下几方面。首先,根据代码重用攻击在漏洞利用过程中的控制流异常跳转和对栈完整性破坏的特点,本文提出了基于栈异常的代码重用攻击检测和shellcode定位方法,并在Win-dow平台上实现了相应工具S-Tracker。代码重用攻击通常需要在栈上或者位于堆空间的伪造栈上大量攻击数据来保证gadget-chain的连续跳转执行,据此定义出代码重用攻击发生时的栈异常;以代码重用的攻击目的为出发点,从内核监控敏感系统调用,当系统调用发生时触发从内核到用户空间的栈回溯,逐帧验证是否存在栈异常,进而发现攻击;通过栈异常发生时的异常跳转目标,实现模糊定位shellcode功能。上述检测方法与当时版本的微软EMET工具相比,更加难以被攻击者绕过。其次,根据代码重用攻击对栈上数据的高度依赖性,本文提出了基于ARM指令特性的栈帧布局随机化方法。通过向位于函数prologue、epilogue中push/pop的指令的寄存器列表中随机插入额外的闲置通用寄存器,实现向函数调用栈中引入大小不确定的padding,从而改变对栈上数据相对寻址的offset,使得攻击者难以定位到栈上预期数据(尤其控制流数据),无法将代码重用攻击中的预期控制流跳转目标和参数正确恢复到目标寄存器,从而有效阻止了代码重用攻击中gadget-chain的执行。而ARM指令等长的特性使得本方法更具实际应用价值——指令重写过程中无需改变文件大小、无需移动或插入任何额外指令。文中虽然以ARM平台上Android应用程序中共享库为测试对象,从随机化能力和攻击缓解能力两方面验证了方法的有效性;但本方法不局限于Android系统,对运行在ARM平台上的iOS等系统中的程序也具有适用性。再次,本文从代码重用的角度对Android 5.0及其之后版本中的系统运行时环境Android ART进行了安全性分析,研究过程中发现能够降低代码重用攻击难度的随机化缺陷;根据代码重用攻击对分支指令的依赖性,提出了针对直接跳转指令和间接跳转指令的随机化方法,从而阻止代码重用攻击。研究中发现,对于指定系统,AndroidART生成的boot.oat文件的加载地址是固定的,是ASLR应用过程中的例外导致的缺陷。据此,我们提出了利用boot.oat中的gadget进行代码重用攻击的思路,使得攻击难度较传统的代码重用攻击有所降低。对于上述威胁,在栈随机化方法的研究基础上设计并实现如下缓解方案:在不改变程序语义的前提下,向类似pop{..., pc}的函数epilogue指令中引入额外的寄存器,利用新引入的指令对函数体内类似blx r5的指令中的跳转目标寄存器进行重新分配,从而实现对代码重用gadget中的间接跳转指令、直接跳转指令的随机化。通过将上述代码重用缓解方法在Android 5.1.1系统上进行集成,对oat文件和共享库等二进制文件进行加载时的随机化,有效提升了代码重用的攻击难度。最后,从提升特定系统整体安全性、最小化代码重用等攻击造成的威胁的角度,本文针对Android应用程序中不可信共享库难以审计、进程空间无限制访问、易存在内存漏洞、后门等问题,设计并实现了能够对不可信共享库进行内存隔离、权限隔离的安全性增强Android系统,从而有效解决基于代码重用的模块间权限提升、Dalvik/ART运行时环境的篡改攻击等威胁。利用Android App Sandbox机制,将应用程序Java 代码和不可信共享库安装为两个不同的App,并分配各自所需的权限;通过实现的JNI代理和JNI反射调用代理以IPC的方式完成JNI调用和反射调用,保证了应用程序的正常运行;通过JNI反射调用代理上的访问控制,避免了共享库代码的权限逃逸。上述实现方案对应用程序开发者透明,在不损失易用性的前提下有效增强了系统安全性。