论文部分内容阅读
随着网络互联、网络安全技术和各种高级网络应用技术的飞速发展,现代操作系统面临着各种各样的安全威胁。其中,内核级rootkits由于具有良好的隐蔽性,可以长时间的驻留在被注入的系统内核空间,通常具有系统的最高权限,危害巨大。为了应对这些攻击,需要对操作系统的内核代码和内核数据进行全面保护。其中,内核代码和静态的内核数据由于可以被设置为只读,并且它们在内存中的位置确定,保护起来相对比较直观。然而,动态的内核数据由于其无法确定的存放位置和易变性,保护起来难度较大。作为动态内核数据的重要组成部分,内核控制数据决定了内核执行的整体控制流程,常常成为攻击者的目标。通过改写一个控制数据(比如函数返回地址),攻击者就能够改变系统原有的控制流程,将其引导到自己的恶意代码或精心设计的执行流程上。为了全面和有效的保护内核控制数据,包括函数指针和函数返回地址,论文设计并实现了一种基于编译器的内核控制数据保护机制,防御针对操作系统内核控制流程的攻击。更进一步讲,通过修改编译器,在源代码编译阶段识别、定位和转换操作系统内核中与控制数据相关的所有指令来实现内核控制数据的索引机制。该机制为每个控制数据分配一个索引,这个索引指向收集了系统中所有有效跳转地址的表格的某个单元;通过指令转换,在进行程序跳转时,不直接使用控制数据,而是利用它所对应的跳转表格索引去查找跳转表格,获得真正有效的跳转地址来间接执行。同时,该机制借助位于操作系统之下的Hypervisor层(如KVM)来保护跳转表格(例如将存放表格的页面设置为只读),从而提供了对内核控制数据的保护。为了验证保护机制,论文基于开源的GCC-4.6.4编译器-设计并实现了原型系统。原型系统重新编译了Linux-3.11.1/X86-AMD64版本的内核,提供了对其控制数据的保护。原型系统一共修改了内核中35828条direct call指令、2389条indirect call指令、14010条ret指令和1198条mov指令,修改指令总数为53425条,占原内核指令总数的8.39%。内核容量由44.463M增加到44.960M,比原来增加了1.12%。通过对原型系统的攻击测试和性能测试,验证了保护机制的有效性和高效性。测试结果表明,原型系统能够有效阻止针对内核控制数据的控制流程攻击;并且原型系统的额外性能开销较低(平均不超过5%)。