论文部分内容阅读
用C/C++等类型不安全语言编写的程序在具有很高性能的同时,经常遭受控制流劫持攻击的困扰。绝大多数操作系统内核及在其上运行的重要软件程序都是用C/C++实现的,因此现代操作系统广泛部署DEP、ASLR等防御机制来提高了计算机系统的安全性。然而目前主流的控制流攻击利用代码重用技术能成功绕过这些保护措施,并构造出满足图灵完备性计算的代码片段集来执行任意恶意程序操作。控制流完整性是比DEP和ASLR等防御机制更加安全的代码重用攻击防御技术。现有基于二进制的控制流完整性技术存在的主要问题是其构造出来的程序控制流图不完整,所以所实施的安全策略可能会被绕过。本文的研究工作旨在通过深入分析二进制并尽可能复原函数原型、调用点签名和C++语义信息,以提高控制流图的准确性并对目标二进制提供高精度的控制流完整性保护。针对ROP等后向代码重用攻击,通过动态代码插桩技术和线程劫持技术,在不修改程序的情况下设计实现了适用于多线程情形的影子调用栈,并借助线程局部存储机制隐藏了影子调用栈位置。对所设计实现的原型系统进行了功能和性能测试,原型系统能有效保护函数返回地址的完整性且具有合理的性能开销。针对通过劫持虚函数表和破坏函数指针来劫持程序执行流的前向控制流攻击,设计并实现了细粒度的前向控制流完整性方案。首先,从X8664系统下应用程序二进制接口的定义出发,对目标二进制进行静态地过程间数据流分析,通过收集分析参数寄存器和返回值寄存器的状态信息来确定函数和间接函数调用点的参数数量及返回值使用情况,根据参数数量和返回值使用情况保守地重构函数原型和调用点签名;根据C++虚函数调用的行为特点和虚函数表的特殊属性复原C++语义信息,即提取虚函数调用点和虚函数表。其次,根据静态分析的函数原型、调用点签名和C++语义信息在间接函数调用点和函数之间建立基于类型的、多对多的映射关系来确定间接函数调用点合法目标集。最后,利用动态代码插桩技术验证间接调用指令目标的合法性,并通过限制间接调用指令只调用类型的匹配函数提高前向CFI的精度。在影子调用栈方案的基础上对原型系统进行了扩展,并对它进行了功能和性能测试,测试结果表明它能有效保护前向控制流完整性且性能开销在合理范围内。