基于代码防泄漏的代码复用攻击防御技术

2016-11-14 02:12李清宝曾光裕陈志锋
计算机研究与发展 2016年10期
关键词:页表攻击者进程

王 烨 李清宝 曾光裕 陈志锋

(解放军信息工程大学 郑州 450001) (数学工程与先进计算国家重点实验室(解放军信息工程大学) 郑州 450001) (daguoli415@163.com)



基于代码防泄漏的代码复用攻击防御技术

王 烨 李清宝 曾光裕 陈志锋

(解放军信息工程大学 郑州 450001) (数学工程与先进计算国家重点实验室(解放军信息工程大学) 郑州 450001) (daguoli415@163.com)

随着地址空间布局随机化被广泛部署于操作系统上,传统的代码复用攻击受到了较好的抑制.但新型的代码复用攻击能通过信息泄露分析程序的内存布局而绕过地址空间布局随机化(address space layout randomization, ASLR),对程序安全造成了严重威胁.通过分析传统代码复用攻击和新型代码复用攻击的攻击本质,提出一种基于代码防泄漏的代码复用攻击防御方法VXnR,并在Bitvisor虚拟化平台上实现了VXnR,该方法通过将目标进程的代码页设置可执行不可读(Execute-no-Read, XnR),使代码可以被处理器正常执行,但在读操作时根据被读物理页面的存储内容对读操作进行访问控制,从而阻止攻击者利用信息泄露漏洞恶意读进程代码页的方法搜索gadgets,实验结果表明:该方法既能防御传统的代码复用攻击,还能够防御新型的代码复用攻击,且性能开销在52.1%以内.

地址空间布局随机化;代码复用攻击;程序安全;信息泄露;虚拟化

近年来,计算机软件经历着一场漏洞利用攻击与防御恶意攻击行为之间的对抗.越来越多的攻击方法被发现,其中代码复用攻击(code reuse attack,CRA)正成为安全领域研究的热点,如return-into-libc[1],ROP(return-oriented programming)[2-5],JOP(jump-oriented programming)[6-8]和SROP(sigreturn-oriented programming)[9]等.代码复用攻击是一种新型的攻击技术,与传统的恶意代码攻击不同,代码复用攻击不需要引入额外的恶意代码,仅使用程序已有的代码便能实施恶意攻击,使得数据执行保护(data execution protection, DEP)[4]和栈溢出保护(stack smashing protection, SSP)[10]等防御机制失效.

为了有效检测和防御代码复用攻击,研究人员提出了多种检测方法和防御技术,其中应用最广泛的方法是ASLR[11].传统的ASLR机制通过随机化代码段的基地址使得攻击者无法预知代码在内存中的具体位置,从而阻止代码复用攻击.由于这种传统的ASLR只是改变了整个代码段的基地址,一旦泄漏一个指针值就可以通过它们的相对偏移发现所有gadget的地址.为了阻止攻击者获取所需gadgets的有效地址,一些更复杂的随机化技术被研究提出,主要分为细粒度随机化和加载时随机化2类.细粒度随机化通过将随机化的基本块粒度细化到函数级和指令级,Pappas等人[12]就提出了一种in-place代码随机化技术,通过指令重排列、等价指令替换和寄存器重赋值等方法阻止ROP攻击;加载时随机化技术主要是通过在程序加载时进行地址随机化处理,文献[13]分析了Vista中的ASLR机制,如果可执行文件被打上了ASLR标记,进程的代码段基地址、栈基地址、堆基地址和PEB(process environment block)的位置等都在进程加载时被随机化.这类ASLR机制对系统的性能消耗较小,且能有效阻止攻击者使用预先计算的gadget链完成事先设计的攻击.

为了绕过上述ASLR机制,Snow等人[14]提出just-in-time代码复用攻击技术(下面简称JIT-ROP,即时代码复用攻击),该攻击技术是在脚本环境下通过一个内存泄漏漏洞在线获取程序的内存布局,在收集到的内存页中动态搜索API函数和gadgets,完成payload构造,利用payload即时编译攻击代码,完成代码复用攻击.JIT-ROP攻击是一种动态计算构造gadgets链的攻击方法,可以绕过现有的防御机制,是当前最复杂的攻击技术之一.

由于JIT-ROP攻击需要利用一个信息泄漏后门读取任意内存位置内容搜索gadgets,通过强制可执行代码不可被读或者被反汇编,可以避免内存中可执行代码信息泄漏的风险,阻止攻击者在线构造gadgets链.根据上述思想,Backes等人[15]设计完成了XnR系统.XnR只允许代码可以被处理器取指令操作访问和执行,但不能以读数据方式被访问,由此可知XnR能阻止针对可执行代码的内存泄漏攻击和JIT-ROP攻击.但该方法只能阻止未映射到内存的代码页被非法访问,攻击者可以通过在内存中的代码页进行漏洞利用搜索gadgets,从而绕过保护机制发动JIT-ROP攻击.

为了有效防御代码复用攻击,本文借鉴W⊕X和XnR的设计思路,提出了一种基于代码防泄漏的代码复用攻击防御方法VXnR.该方法利用内存虚拟化技术,在虚拟层实现对可疑漏洞程序的内存代码页添加Execute-no-Read保护属性,使得进程的代码页可以被CPU取指执行但不能被读操作访问,攻击者无法通过内存泄漏获取到漏洞进程的代码页信息,这种保护机制大大降低了攻击者绕过防御机制的可能性.实现VXnR需要解决的挑战性技术问题:

1) 无法直接区分对内存的合法的数据访问和对代码的读行为.虽然HideM[16]通过分立式TLB结构ITLB和DTLB区分对数据和指令代码的访问操作,而目前的处理器已经升级为统一式TLB结构,HideM方法需要依赖硬件结构,不具有普适性.

2) 具有不可读但可执行访问权限的内存并不存在.可执行权限意味着必须可读,无法直接对可执行代码页设置“可执行不可读”权限.XnR通过修改页错误处理函数和请求页面处理函数,限制内存中进程虚拟页面页数,在触发缺页异常时对访问操作进行判断,根据判断结果来限制对代码页的读行为,该方法只能对不在内存的虚拟页访问控制,攻击者可以利用在内存的虚拟页绕过缺页异常处理函数,进行代码复用攻击.

针对代码复用攻击的防御需求及面临的技术挑战,本文主要贡献如下:

1) 提出了一种基于代码防泄漏的代码复用攻击防御方法VXnR.该方法通过阻止对进程代码非法读访问,使攻击者无法搜索构造gadget,实现了对新型代码复用攻击的防御.相比现有的防御方法的优势体现在:①无需修改客户操作系统;②避免客户操作系统旁路甚至破坏代码复用防御系统,解决了VXnR的安全性问题;③性能开销较小,可靠性高.

2) 针对主要技术挑战,提出了2项解决方法:基于缺页异常的内存访问操作识别、基于硬件辅助页面映射机制的XnR权限修改.2项技术均在虚拟机监控层实现,对上层操作系统透明,同时具有更高的安全性,即使客户操作系统内核被攻破也不影响底层安全机制.

3) 在一种虚拟化平台Bitvisor上实现了VXnR原型系统,并使用代码复用攻击测试程序评估了VXnR的有效性和性能.实验表明VXnR在保护客户操作系统中的目标进程,防御代码复用攻击的同时,仅带来了不超过52.1%的运行时开销.

1 VXnR系统

传统的代码复用攻击利用逆向工程工具静态分析目标可执行程序,通过搜索算法寻找以ret,jmp和call等转移指令结尾的短指令序列gadgets,链接这些指令序列构造payload,并将其地址以及指令序列需要的数据布置在堆栈中,当目标程序执行时通过一个程序漏洞将控制流导向堆栈中的payload,进行代码复用攻击.

随着ASLR思想的提出,程序执行的指令和代码在内存中的位置都被改变,静态分析搜索到的gadgets地址并不可用,限制了传统的代码复用攻击.为了绕过该防御机制,新型的代码复用攻击利用内存泄漏漏洞使攻击者在程序运行时可以动态获取内存布局,读取被随机化后的gadget的真实地址,成功利用程序已有代码完成攻击.

综上,随着有效防御机制的发展,传统的代码复用攻击受到了一定的抑制,但新型的代码复用攻击仍然不断涌现.一种新型的代码复用攻击一般分为2个阶段:1)需要针对具有某个漏洞的目标程序进行信息泄露以获取到该程序的内存分布;2)进行实际的漏洞利用并发动代码复用攻击.结合细粒度的地址空间布局随机化机制,本文提出的防御方法旨在第1步阻止代码复用攻击,保护目标程序的内存布局,使攻击者无法搜索读取目标程序的可执行代码,防御攻击者利用目标程序已有代码进行代码复用攻击.

1.1 总体架构

若将代码复用攻击防御程序设置于内核中,那么一旦内核遭到破坏,防御程序就有可能被攻击者禁用,从而被绕过.因此,我们引入虚拟机架构,并将防御程序放置于Hypervisor中,这种机制大大降低了攻击者绕过防御系统的可能性.防御架构如图1所示:

Fig. 1 System architecture of VXnR.图1 VXnR系统架构

从图1中可知,系统架构由进程检测模块process detector和在线保护代码页模块runtime protect两部分组成,分别对应检测漏洞进程加载阶段和在线保护阶段.检测漏洞进程加载阶段通过Hypervisor中的进程检测模块检测目标进程的加载运行.当目标进程processT在用户层加载时,进程检测模块会检测到目标进程的运行,并通知在线保护代码页模块对进程processT执行在线保护.在线保护代码页模块接收到进程检测模块的消息后,系统进入在线保护阶段,目标进程对物理内存的访问操作都需要经过在线保护代码页模块,而未被保护进程对内存的访问不需要通过在线保护代码页模块.利用虚拟化内存管理技术,对目标进程processT的内存页执行Execute-no-Read保护.当处理器访问目标进程代码页进行取指令执行代码(fetch)时,该操作通过在线保护验证;当处理器执行读(read)操作访问目标进程代码页时,在线保护代码页模块认为该操作为非法操作并拒绝服务.本系统实现需要的关键技术主要有2个:1)需要定位到目标进程代码段在内存中的位置,并设置目标进程代码页的访问权限为只可执行不可读;2)在线保护代码页模块需要区分2个内存访问操作,即合法的数据访问和对代码的读行为.

1.2 基于缺页异常的内存访问操作识别

本文将内存访问操作分为3种:取指令(instr-uction fetch)、读数据(read data)和读代码(read code).取指令操作表示处理器从内存取一个字节,译码执行指令,这是代码执行时发生的合法操作;读数据操作表示指令执行访问内存数据的行为,这里的数据不包含代码,这是程序运行时发生的合法操作;读代码操作表示指令执行访问内存数据的行为,这里的数据仅指代码,这是信息泄露的可疑行为,所以认为是非法的操作.

Fig. 3 Memory access operations identification method based on page fault violation.图3 基于缺页异常的内存访问操作识别方法

为了发现非法的读代码行为,首先需要拦截对内存的访问操作,然后判断该访问操作类型.在虚拟层,拦截对内存的访问操作可以通过监控与内存访问操作行为相关的指令,包括read,load和store等,修改编译器对相关指令静态插桩或者利用动态插桩工具在程序运行过程中动态插桩,当程序执行与内存访问操作相关的指令时触发异常,陷入虚拟机监控器.但是静态插桩需要程序的源码,动态插桩对系统的性能开销较大,而且与内存访问操作行为相关的指令种类较多,因此,该方法有一定局限性且可行性较差.

利用操作系统虚拟内存管理机制,本文提出基于缺页异常的内存访问操作识别方法.新建进程的虚拟地址空间是按写时复制方式从创建者进程中复制,属于共享的虚拟地址空间,在进程刚加载完新程序之后,它的虚拟地址空间几乎是空的.而加载操作仅在虚拟地址空间与可执行文件之间建立了映射关系,并未真正将文件的内容读入内存.在虚拟机监控器架构下,客户机的访存操作需要利用硬件辅助页面映射(hardware assisted paging, HAP)页表项进行地址转换,HAP是基于硬件虚拟化实现虚拟机物理地址空间隔离的页表映射机制,不同的硬件厂商提供特定平台的HAP机制,如Intel处理器的EPT机制和AMD处理器的NPT机制.图2为EPT机制下客户操作系统访存过程,其实现原理和x86架构下的分页机制是一致的,通过客户机虚拟地址到客户机物理地址(guest-physical address, GPA)和客户机物理地址到宿主机物理地址(host-physical address, HPA)两次地址映射转换来支持地址空间的虚拟化.由于新加载的进程并未建立HAP映射将可执行文件的内容读入内存,进程对虚拟地址空间的读、写、执行操作都会触发HAP异常.HAP异常事件相关信息会存储在exit qualifica-tion字段中,这些信息包括触发异常的操作类型(例如取指令操作、读数据和写数据操作),该物理页的HAP权限和引起异常的客户物理地址.因此,新加载目标进程初始运行时由于请求页面引起缺页异常事件,通过分析触发异常事件的相关信息可以判断该访存操作类型.

Fig. 2 Access process in guest OS with EPT mechanism.图2 EPT机制下guest OS 访存过程

图3以x86下Linux操作系统为例,Linux内核采用Copy on Write机制,在请求页面时触发EPT violation,进入do ept violation异常处理函数对异常事件进行分析,在exit qualification字段寻找引起VM-exit的明细信息.其中bits0,bit1,bit2指示产生EPT violation时对GPA进行哪些访问:当bit0=1时,表示正在对GPA进行读访问;当bit1=1时,表示正在对GPA进行写访问;当bit2=1时,表示正在尝试执行GPA地址上的指令(fetch指令).通过分析exit qualification字段的bits0,bit1,bit2位的值,可以得到触发EPT violation的访问操作类型.当bit2=1时,CPU执行instruction fetch指令访问该物理页面,由于进程初始运行阶段并未建立EPT映射,虚拟页面不在内存中从而触发EPT异常,因此,认为该GPA通过EPT映射的物理页存储的是进程的可执行代码段信息,所以记录该GPA并标记为代码页,然后建立EPT映射项将虚拟页映射到物理内存.当bit0=1或bit1=1时,CPU执行readwrite指令访问物理页面,由于进程初始运行阶段未建立EPT映射,虚拟页面不在内存中从而触发EPT异常,因此,认为该GPA通过EPT映射后的物理页存储的是进程的数据信息,所以标记该物理页面为数据页,然后建立EPT映射项将虚拟页映射到物理内存.

Fig. 5 Set XnR permission on the process code page.图5 对进程代码页设置XnR权限

1.3 基于硬件辅助页面映射机制的XnR权限修改

在进程初始运行时,利用基于缺页异常的内存访问操作识别的方法可以实现对进程代码页的定位收集,为了阻止非法的读代码行为,还需要将目标进程的代码页保护起来.

一种方法是通过在内核层修改缺页处理函数实现对进程代码页设置XnR权限,该方法通过只保留N个代码页存在内存中,程序运行时对其它代码页的访问操作都将触发缺页异常,在缺页异常处理函数中处理该异常事件,被修改的缺页异常处理函数会判断触发异常的访问操作类型,当取指令操作触发异常时,缺页异常处理函数建立相应映射项允许访问并将内存中已有的一个代码页移除,从而保证内存中只保留程序的N个代码页;当读写操作触发异常时,缺页处理函数判断该物理页面是否为代码页,若是代码页则拒绝服务,若是数据页则建立相应映射项允许访问.该方法可限制映射到内存的程序代码页数量为N,程序运行到未映射的代码页即会触发缺页异常,当程序运行连续跳转到未映射代码页时会频繁触发缺页异常,严重影响程序的运行效率,而且攻击者也可以利用已映射到内存的N个代码页搜索gadgets从而绕过该保护机制.

为解决上述问题,利用内存虚拟化技术,本文提出基于硬件辅助页面映射机制的XnR权限修改的解决办法.和传统内存管理类似,HAP使用页表入口设置权限管理物理内存.但HAP支持读权限和present(虚拟页在内存)状态的分立.如图4所示,传统的x86页表第0位控制present状态和读权限,当页面为non-present且不可读时,第0位bit-0(P)被清零,因此,present的页面总是可读的.但HAP是通过将第0位bit-0(R)、第1位bit-1(W)和第2位bit-2(E)全清零代表页面non-present(虚拟页不在内存).所以,只要将HAP入口第2位设置为1并将第0位和第1位清零,就可以实现对该页面设置 “可执行不可读”权限.

Fig. 4 Page-table entry permission bits for x86PAE and HAP.图4 x86PAE和HAP的页表入口权限位

4K页面下EPT页表结构由PML4T(page map level 4 table),PDPT(page-directory-pointer table),PD(page-directory)和PT(page table)共4级页表构成,如图5所示,GPA被分割为5个部分,顶层页表PML4T的物理地址由扩展页表指针(extended page table pointer, EPTP)字段提供,一级一级地往下查找,直到找到PTE,最后加上偏移值offset即可获得真实的HPA,根据已定位的程序物理页信息,查看该HPA所在物理页面的标记.若为代码页,则设置该HAP页表入口权限为可执行不可读;若为数据页,则默认该HAP页表入口权限的初始值,不对其修改.因此,程序在访问该HPA上的内容前,VXnR会检查该物理页面的访问权限,在检查通过后允许访问.当程序执行读操作访问可执行不可读页时触发异常,VXnR对异常事件进行分析处理,当发生读写操作异常时继续分析该页面内容,若该页面被标记为可执行不可读页则拒绝该非法操作访问,若该页面为可读可写页则允许访问.

2 实 现

本文实现的VXnR采用x86架构的CPU,而且CPU需要支持虚拟化技术,目前大多数处理器都能满足该要求,主机操作系统采用Ubuntu 12.04,且配置ASLR机制,使用gcc编译器进行开发,虚拟机监视器使用Bitvisor.VXnR的实现主要分为对进程检测模块和在线保护代码页模块2个模块的实现.

2.1 进程检测模块

采用Ether[17]中提出的系统调用截获技术,当截获到execve系统调用,进程检测模块在VMM中监控CR3控制寄存器的更新来识别客户机操作系统的当前进程,由于新进程创建可能会重用之前撤销的进程页目录基地址,同时考虑顶层页表中第1有效项从而创建唯一的标识符.当发现新进程为目标进程时,立即向在线保护代码页模块发送消息,使系统进入在线保护代码页阶段.

2.2 在线保护代码页模块

实现在线保护代码页模块的关键技术难点主要有2个:1)在目标进程加载完初始运行时定位该进程代码页;2)对目标进程代码页设置XnR访问权限.通过基于缺页异常的内存访问操作识别的方法,在目标进程初始运行中实现对其代码页定位收集,并将该GPA与已记录的代码页GPA进行匹配.若没有匹配项,认为该代码页为第1次请求页面映射到物理内存,则将该GPA添加到记录中并标记为代码页;若存在匹配项,说明该代码页已经收集到记录中.然后利用基于硬件辅助页面映射机制的XnR权限修改的方法,针对定位到的代码页建立EPT映射将虚拟页映射到物理内存,并修改该EPT页表入口权限位,根据图6所示的PTE页表项结构图,对PTE页表项的后3位修改为100来设置对应页面的可执行不可读权限.当存在读(read)该代码页操作时,由于访问权限不够触发EPT violation,此时系统认为存在非法的读取代码行为,报警存在利用目标进程进行内存泄漏,阻止代码复用攻击.

Fig. 6 The structure of PTE.图6 PTE结构图

3 实验及结果分析

本节从有效性和性能2个方面对VXnR进行测试.有效性测试用于验证VXnR能否实现代码复用攻击防御;性能测试用于验证VXnR的效率和开销.实验环境如下:主机CPU为Intel®CoreTMi7-4790 @ 3.60 GHz,内存为16 GB;Hypervisor采用Bitvisor,其版本为1.4.0,Guest OS采用的是3.2.0-x86_32内核的Ubuntu 12.04.

3.1 有效性测试

为了测试VXnR的有效性,我们构造了一个具有栈溢出漏洞和内存泄漏漏洞的目标程序,选择了文献[2,5-7,14,18-22]实现的ROP 作为测试用例,并对其进行修改使其能够运行在32位3.2.0-x86内核的Ubuntu 12.04.

文献[14]实现了just-in-time ROP,该攻击重复利用内存泄漏漏洞,映射出目标程序的内存布局,进而搜索gadegts并即时编译攻击代码.但由于其需要利用信息泄露后门读取程序内存可执行代码,所以攻击会被VXnR阻止.文献[6]实现了以非ret结尾转移指令的ROP攻击,但由于其复用的代码中包含loadstore,在执行loadstore指令对内存代码的操作时会被VXnR阻止.文献[2]实现了return-into-libc攻击,由于该攻击在寻找所需动态库函数地址时违背了VXnR代码不可读原则,所以攻击失效.文献[18]实现了一种利用call-preceded gadget构造call-preceded ROP攻击.文献[19]提出了一种新型的代码复用攻击LOP.文献[20]实现了在不破坏ROP payload的语义的前提下构建Long-NOP gadget.文献[21]定义了2种类型的gadget:call-site(CS) gadgets和entry-point(EP) gadgets.其中CS gadgets与call-preceded gadget概念相同,而EP gadgets是从函数入口点指令开始,到间接跳转或间接调用指令结束的指令序列,基于这2种gadget只能绕过控制流完整性保护从而实现ROP攻击.文献[7]提出了一种ROP攻击的变种JOP攻击,文献[5]提出了一种增强型的代码复用攻击BIOP,文献[22]利用内存泄漏分析程序内存布局实现ROP攻击.但本系统配置了地址空间布局随机化保护机制,文献[5,7,18-22]都需要获取程序内存布局的前提去搜索gadget,所以违背了VXnR代码页不可读的原则而攻击失效.测试结果如表1所示,表1的列1为测试用例名称,列2是测试用例的实现原理,列3表示VXnR能够检测到并防御列1所列的测试用例,列4表示VXnR认为测试用例的非法行为.

Table 1 The Defense Results for ROP

Note:“√”means successful defense.

从表1可知,VXnR成功防御了这10类攻击,表明本文提出的方法是有效的.

为了进一步验证本方法的有效性,我们与目前主流的代码复用攻击防御工具kBoucer[23]和Isomeron[24]对比测试,测试结果如表2所示:

Table 2 Comparison of Different Defense Methods

Note:“√”means successful defense, “×”means failed defense.

根据表2,VXnR能够防御所有的代码复用攻击,而kBoucer无法防御文献[18]提出的攻击方法,这是因为kBoucer通过LBR (last branch recording)寄存器检查与返回地址指向的指令位置相邻的上一条指令是否为call指令,通过防止返回地址被修改的方法来防御ROP攻击,而文献[18]提出了call-preceded ROP并采用历史记录冲洗的方法在系统调用前使用一些无关的指令片段将LBR中存储的真正的gadget信息给替换掉,从而使得kBouncer无法防御攻击行为,kBoucer也无法防御文献[19]提出的攻击方法.因为文献[19]是通过以整个函数为粒度搜索gadget,实现了call和ret指令是成对出现的LOP(loop-oriented programming)攻击,能够绕过控制流完整性(control-flow integrity, CFI)策略.Isomeron无法防御文献[7,19]提出的攻击方法,因为Isomeron通过结合执行路径随机化和代码随机化防御传统的ROP和JIT-ROP攻击,所以无法防御文献[7,19]实现的ROP攻击的变种JOP和LOP攻击.文献[20]实现了在不破坏ROP payload语义的前提下构建Long-NOP gadget,使kBouncer对于gadget长度的检测防御失效.文献[21]基于CS gadgets和EP gadgets这2种gadget成功绕过kBouncer控制流完整性保护实现ROP攻击.文献[22]能够利用内存泄漏分析程序内存布局绕过随机化机制,所以Isomeron无法防御文献[22]提出的攻击方法.

为了检验本文方法的误报率,我们使用了一些常用应用程序进行对比检测.通过运行500次表3列举的应用程序,观察每次运行过程中是否会产生误报,记录产生误报的次数,测试结果如表3所示:

Table 3 Results of False Positive Test

由表3可知,没有误报产生,这也进一步验证了本文方法的有效性.

3.2 性能测试

3.2.1 微基准测试

由于本文对系统调用、内存访问等进行监控,选择了lmbench中的与系统调用、文件处理、缺页异常、信号处理以及进程创建等相关事件作为测试项.通过分别测试裸机、Bitvisor,VXnR三者下的性能开销,并通过对比来分析VXnR所引入的性能开销,测试结果如表4所示.

其中,在VXnR系统中,受保护程序用户态和内核态之间的切换会触发陷入以及相应EPT页表的切换,因此上下文切换的处理时间会有所增加.由于在VXnR中对所有系统调用进行截获,系统调用的每次执行都会陷入陷出Hypervisor,因此与系统调用相关的测试项都会受到VXnR的影响.pagefault以及fork proc,fork exec,sh proc执行过程中会更新受保护程序页表,访问新的物理页面时会触发EPT violation异常陷入VMM,因此它们会引入较大的时间开销.如图7所示.

Table 4 LMBench Results: Time in Microseconds

Fig. 7 Microbenchmark results of VXnR.图7 VXnR微基准测试结果

3.2.2 微基准测试

为了进一步评估VXnR的性能,本文采用4种常用的应用程序对其性能开销进行测试,每项测试进行500次取平均值,测试结果如表5所示.

压缩(compression)和解压缩(decompress)程序均为计算密集型应用,VXnR所引入的性能开销较小,分别为3.55%和7.89%.内核编译(kernel build)属于综合型应用,既需要CPU时间,也会进行大量的IO操作,VXnR引入了34%的性能开销.Postmark是IO密集型应用,用于测试系统的后端存储性能,需要频繁地存取小文件.我们配置postmark为并发的文件数500个,文件大小的上下限分别是500 B和9.77 KB,读写块大小均为512 B,读追加发生的概率相等,创建删除发生的概率相等,文件操作将使用标准的缓冲区IO,随机数产生的种子是42,事务处理的数目为500000,由于VXnR对读写系统调用函数被调用时陷入Hypervisor,因此导致了一定的性能开销(52.1%).如图8所示.

Table 5 Application Benchmark Performance Test Results Time in Seconds

表5 应用程序基准测试时间结果 s

Fig. 8 Application benchmark performance test results.图8 应用基准程序性能测试结果

4 相关工作

为了有效防御代码复用攻击,研究人员提出了若干方法,主要分为2类:1)通过移除二进制文件中gadget或者随机化关键内存区域来被动阻止ROP攻击;2)通过基于预定策略执行检查来有效防御ROP攻击.

其中,第1类方法应用最广泛典型的是ASLR机制.然而,ASLR机制通过将程序代码段加载到一个随机的基地址使代码段中每一条指令的地址都发生了变化,但容易被内存泄漏攻击绕过,为了提升ASLR机制,研究人员通过细粒度随机化增加随机化熵,将随机化对象缩小到函数级和指令级,Marlin[25]是一种函数粒度随机化方法,该方法通过符号分析、函数重排和跳转修复3个阶段实现改变每一个gadget绝对地址,从而防御代码复用攻击.ILR(instruction location randomization)[26]将程序中每一条指令的地址进行随机化,并利用一个映射表引导指令的执行,从而实现指令级随机化.Pappas等人[12]提出了IPR(in-place randomization)的方法,通过用语义相同的指令替换gadget中的指令,减少可构造的gadget,因为该方法并未改变函数的位置,所以不能防御return-into-libc攻击.Davi等人提出了一种基于随机化有效防御JIT-ROP的防御方法Isomeron[24],通过结合执行路径随机化和代码随机化来防御传统的ROP和JIT-ROP攻击,但该方法无法防御ROP攻击的变种JOP和LOP攻击.由于随机化方法通常只是在程序加载前或加载时进行一次随机化处理,攻击者可以利用信息泄露或暴力破解的方式在程序运行时获取gadget的有效地址.为了防止随机化保护被绕过,Bigelow等人[27]提出了运行时代码随机化的方法,该方法能够在存在可疑内存泄漏的时间点对程序进行运行时随机化,从而阻止攻击者获取gadget的真实地址.但由于运行时随机化需要暂停当前程序、保存现场、然后随机化等操作,所以会带来较大性能损耗.

第2类方法应用最广泛典型是CFI.该方法通过构造程序的控制流图(control-flow graph, CFG),在程序运行时对比检查程序执行流是否遵循CFG中的有效路径,从而确保程序运行时的控制流完整性.KBouncer[23]通过在Windows API插入检查点,利用LBR寄存器检查与返回地址指向的指令位置相邻的上一条指令是否为call指令来防御ROP攻击,由于LBR记录在上下文切换时会产生记录溢出或者污染记录,所以其漏报率较高.为了克服KBouncer的漏报问题,ROPecker[28]将当前LBR中的记录和后续的记录结合起来进行检查,但由于该方法是粗粒度的控制流完整性保护,仍然存在被绕过的风险.Kuznetsov等人[29]提出了一种细粒度的控制流完整性方法代码指针完整性(code-pointer integrity, CPI),该方法通过使用静态分析程序所有指向代码的指针变量,在运行时将存储变量的内存分为安全区和正常区2个区域,分别存储代码指针变量和其它变量.限制所有对安全区的访问操作必须通过安全检查来阻止控制流劫持.由于CPI需要静态分析目标程序源码,无法确保动态生成代码的代码指针完整性.相比于基于随机化的方法,CFI通过执行检查主动防御ROP攻击,但带来的开销明显更高.结合粗粒度CFI和随机化方法,Opaque CFI[30]通过在控制流转移前插入CFI检查限制跳转目标地址的范围,由于该阈值因随机化而改变且隔离在安全区域,可以防御信息泄露攻击,但是该方法仍然需要静态分析程序源码重构跳转地址,没有考虑到动态生成的代码.XnR通过保护目标程序部分代码页的隐私安全防御代码复用攻击,但攻击者可以利用未受保护的代码页发动攻击.HideM弥补了XnR的缺陷,能够对目标进程的全部代码页进行保护,但HideM 需要依赖硬件结构,所以不具有普适性.

综上,随机化的方法只能在某种程度上减轻代码复用攻击,但攻击者可以通过暴力破解和信息泄露的方式分析获取可用gadget的地址,并完成代码复用攻击,而控制流完整性保护的性能开销较大,且攻击者可以通过程序运行时动态生成的代码绕过完整性保护并构造代码复用攻击.本文结合细粒度的随机化机制,利用内存虚拟化技术,保护程序的内存布局,阻止攻击者读取可执行代码的地址,避免代码被攻击者滥用进行恶意攻击,能够更加有效地防御代码复用攻击.

5 结 论

本文提出了一种基于代码防泄漏的代码复用攻击防御方法VXnR,并给出了VXnR的设计和具体实现.VXnR通过对目标进程的可执行代码内存区域进行保护,防止信息泄露,从而阻止攻击者利用目标进程进行代码复用攻击.VXnR在虚拟层实现,无需修改客户操作系统内核,具有良好的兼容性和安全性.我们在Bitvisor虚拟化平台上实现了VXnR的原型系统,并对VXnR的有效性和性能进行了评测.结果表明VXnR在有效防御代码复用攻击的同时,引入的性能开销不超过52.1%.我们的后续工作将侧重于从运行时代码随机化的角度研究防御代码复用攻击的方法.

[1]Tran M, Etheridge M, Bletsch T, et al. On the expressiveness of return-into-libc attacks[G] //LNCS 6961: Proc of the 14th Int Conf on Recent Advances in Intrusion Detection. Berlin: Springer, 2011: 121-141

[2]Shacham H. The geometry of innocent flesh on the bone: Return-into-libc without function calls (on the x86)[C] //Proc of the 14th ACM Conf on Computer and Communications Security. New York: ACM, 2007: 552-561

[3]Buchanan E, Roemer R, Shacham H, et al. When good instructions go bad: Generalizing return-oriented programming to RISC[C] //Proc of the 15th ACM Conf on Computer and Communications Security. New York: ACM, 2008: 27-38

[4]Hund R, Holz T, Freiling F C. Return-oriented rootkits: Bypassing kernel code integrity protection mechanisms[C] //Proc of the 18th Conf on USENIX Security Symp. Berkeley: USENIX Association, 2009: 383-398

[5]Xing Xiao, Chen Ping, Ding Wenbiao, et al. BIOP: Automatic construction of enhanced ROP attack[J]. Chinese Journal of Computers, 2014, 37(5): 1111-1123 (in Chinese)(邢骁, 陈平, 丁文彪, 等. BIOP:自动构造增强型ROP攻击[J]. 计算机学报, 2014, 37(5): 1111-1123)

[6]Checkoway S, Davi L, Dmitrienko A, et al. Return-oriented programming without returns[C] //Proc of the 17th ACM Conf on Computer and Communications Security. New York: ACM, 2010: 559-572

[7]Bletsch T, Jiang X, Freeh V W, et al. Jump-oriented programming: A new class of code-reuse attack[C] //Proc of the 6th ACM Symp on Information, Computer and Communications Security. New York: ACM, 2011: 303-307

[8]Sadeghi A A, Aminmansour F, Shahriari H R. Tiny jump-oriented programming attack (A class of code reuse attacks)[C] //Proc of the 12th Int Iranian Society of Cryptology Conf on Information Security and Cryptology. Piscataway, NJ: IEEE, 2015: 52-57

[9]Bosman E, Bos H. Framing signals—A return to portable shellcode[C] //Proc of the 35th IEEE Symp on Security and Privacy. Los Alamitos, CA: IEEE Computer Society, 2014: 243-258

[10]Cowan C, Pu C, Maier D, et al. StackGuard: Automatic adaptive detection and prevention of buffer-overflow attacks[C] //Proc of the 7th USENIX Security Symp. Berkeley, CA: USENIX Association, 1998: 63-78

[11]PaX Team. Address Space Layout Randomization (ASLR)[EB/OL].[2016-08-06]. http://pax.grsecurity.net/docs/aslr.txt

[12]Pappas V, Polychronakis M, Keromytis A D. Smashing the Gadgets: Hindering return-oriented programming using in-place code randomization[C] //Proc of the 33rd IEEE Symp on Security and Privacy. Piscataway, NJ: IEEE, 2012: 601-615

[13]Sotirov A, Dowd M. Bypassing browser memory protections in windows vista[EB/OL].[2016-08-06]. http://www.phreedom.org/research/bypassi-ng-browser-memory-protections

[14]Snow K Z, Monrose F, Davi L, et al. Just-in-time code reuse: On the effectiveness of fine-grained address space layout randomization[C] //Proc of the 34th Symp on Security and Privacy. Piscataway, NJ: IEEE, 2013: 574-588

[15]Backes M, Holz T, Kollenda B, et al. You can run but you can’t read: Preventing disclosure exploits in executable code[C] //Proc of the 2014 ACM SIGSAC Conf on Computer and Communications Security. New York: ACM, 2014: 1342-1353

[16]Gionta J, Enck W, Ning P. HideM: Protecting the contents of userspace memory in the face of disclosure vulnerabilities[C] //Proc of the 5th ACM Conf on Data and Application Security and Privacy. New York: ACM, 2015: 325-336

[17]Dinaburg A, Royal P, Sharif M, et al. Ether: Malware analysis via hardware virtualization extensions[C] //Proc of the 15th ACM Conf on Computer and Communications Security. New York: ACM, 2008: 51-62

[18]Carlini N, Wagner D. ROP is still dangerous: Breaking modern defenses[C] //Proc of the 23rd USENIX Security Symp. Berkeley, CA: USENIX Association, 2014: 385-399

[19]Lan B, Li Y, Sun H, et al. Loop-oriented programming: A new code reuse attack to bypass modern defenses[C] //Proc of the 2015 IEEE Trustcom/BigDataSE/ISPA. Piscataway, NJ: IEEE, 2015: 190-197

[20]Davi L, Sadeghi A R, Lehmann D, et al. Stitching the gadgets: On the ineffectiveness of coarse-grained control-flow integrity protection[C] //Proc of the 23rd USENIX Security Symp. Berkeley, CA: USENIX Association, 2014: 401-416

[21]Goktas E, Athanasopoulos E, Bos H, et al. Out of control: Overcoming control-flow integrity[C] //Proc of the 35th IEEE Symp on Security and Privacy. Piscataway, NJ: IEEE, 2014: 575-589

[22]Strackx R, Younan Y, Philippaerts P, et al. Breaking the memory secrecy assumption[C] //Proc of the 2nd European Workshop on System Security. New York: ACM, 2009: 1-8

[23]Pappas V, Polychronakis M, Keromytis A D. Transparent ROP exploit mitigation using indirect branch tracing[C] //Proc of the 22nd USENIX Conf on Security. Berkeley: USENIX Association, 2013: 447-462

[24]Davi L, Liebchen C, Sadeghi A-R, et al. Isomeron: Code randomization resilient to (just-in-time) return-oriented programming[C] //Proc of the 22nd Network and Distributed System Security Symp. Washington, DC: Internet Society: 2015

[25]Gupta A, Kerr S, Kirkpatrick M S, et al. Marlin: A fine grained randomization approach to defend against ROP attacks[G] //LNCS 7873: Proc of Network and System Security. Berlin: Springer, 2013: 293-306

[26]Davidson J W, Hall M, Co M, et al. ILR: Where’d my gadgets go?[C] //Proc of the 33rd IEEE Symp on Security and Privacy. Piscataway, NJ: IEEE, 2012: 571-585

[27]Bigelow D, Hobson T, Rudd R, et al. Timely rerandomization for mitigating memory disclosures[C] //Proc of the 22nd ACM SIGSAC Conf on Computer and Communications Security. New York: ACM, 2015: 268-279

[28]Cheng Y, Zhou Z, Yu M, et al. ROPecker: A generic and practical approach for defending against ROP attacks[C] //Proc of the 21st Network and Distributed System Security Symp. Washington, DC: Internet Society: 2014

[29]Kuznetsov V, Szekeres L, Payer M, et al. Code-pointer integrity[C] //Proc of the 11th USENIX Conf on Operating Systems Design and Implementation. Berkeley, CA: USENIX Association, 2014: 147-163

[30]Mohan V, Larsen P, Brunthaler S, et al. Opaque control-flow integrity[C] //Proc of the 22nd Network and Distributed System Security Symp. Washington, DC: Internet Society: 2015

Wang Ye, born in 1993. Master candidate. His main research interests include information security and trust computing.

Li Qingbao, born in 1967, Professor and PhD supervisor. Senior member of China Computer Federation. His main research interests include information security and trust computing.

Zeng Guangyu, born in 1966. Associate professor and master supervisor. Senior member of China Computer Federation. Her main research interests include information security and trust computing.

A Code Reuse Attack Protection Technique Based on Code Anti-Leakage

Wang Ye, Li Qingbao, Zeng Guangyu, and Chen Zhifeng

(PLAInformationEngineeringUniversity,Zhengzhou450001) (StateKeyLaboratoryofMathematicalEngineeringandAdvancedComputing(PLAInformationEngineeringUniversity),Zhengzhou450001)

As the address space layout randomization (ASLR) is widely deployed on operating systems, traditional code reuse attacks are suppressed. New code reuse attacks analyze program memory layout through information leak to bypass ASLR, which causes a serious threat to the safety of programs. By analyzing the nature of traditional code reuse attacks and new code reuse attacks, we propose a code reuse attack protection technique VXnR based on code anti-leakage. In this method, we set Execute-no-Read (XnR) permission for the code pages of the target process so that code can be properly executed by the processor, but a read operation is controlled according to the content in the physical page to be accessed, which can prevent attackers from maliciously reading code pages of process to search gadgets by using the information disclosure vulnerability, and defense both traditional code reuse attacks and new code reuse attacks. We have developed a prototype of VXnR and implemented it in a virtual machine monitor Bitvisor. We also evaluate the effectiveness and performance overhead of our approach by comprehensive experiments. The experimental results show that VXnR can effectively prevent attackers from exploiting executable code of the target process to launch code reuse attacks with less than 52.1% overhead.

address space layout randomization (ASLR); code reuse attack; program security; information leaks; virtualization

2016-06-15;

2016-08-10

国家社会科学基金项目(15AGJ012);“核高基”国家科技重大专项基金项目(2013JH00103)

TP303; TP309

This work was supported by the National Social Science Foundation of China (15AGJ012) and the National Science and Technology Major Projects of Hegaoji (2013JH00103).

猜你喜欢
页表攻击者进程
更正
机动能力受限的目标-攻击-防御定性微分对策
作者更正
勘 误
债券市场对外开放的进程与展望
改革开放进程中的国际收支统计
更正
正面迎接批判
有限次重复博弈下的网络攻击行为研究
社会进程中的新闻学探寻