APP下载

一种利用EPT机制的动态物理内存隔离方法

2021-12-08孔维亮滕俊章

小型微型计算机系统 2021年12期
关键词:访问控制进程应用程序

孔维亮,滕俊章,薛 猛

1(32753部队,武汉 430000) 2(78123部队,成都 610000) E-mail:qrhappy@163.com

1 引 言

Linux操作系统以页为基本单位对用户的内存访问操作进行控制,但这种内存访问控制机制只能限制普通用户,对超级用户缺乏严格的约束.在Linux操作系统中,超级用户拥有最高权限,能够对系统中的所有资源进行管理,因此,当恶意进程获取了系统最高权限,就可以控制系统资源并进行恶意操作.同时,可加载内核模块(Loadable Kernel Module,LKM)机制的存在使Linux系统具有良好的扩展性,但其作为内核的一部分,拥有最高权限,可以通过对内存地址中的代码和数据进行修改实现恶意功能.

针对上述两种Linux系统的不安全因素,目前已经提出多种针对Linux内存的保护机制和方法.文献[1]提出3种内存保护模型:客户/服务器模型、进程/线程模型和服务体/执行流模型,这3种模型通过修改内存保护机制实现内存空间隔离,从而保护内存数据.文献[2]针对保护内存中的敏感数据问题,通过修改操作系统内核,改变进程虚拟地址和物理地址的映射关系,使包含敏感数据的页面只在处理器访问时才出现在进程地址空间,减少敏感数据暴露时间,增加攻击者窥视用户敏感数据的困难.文献[3]在解决利用动态随机存取内存的Rowhammer攻击方面,实现了一套在虚拟机监视器层面的Rowhammer感知的内存分配机制,能够在虚拟机监视器层面以虚拟机的粒度进行Rowhammer攻击的隔离防护,但该方法针对从虚拟机内部发出的攻击,防御效果不是很好.文献[4]利用硬件虚拟化技术保护应用程序,但都需要通过修改操作系统内核或应用程序实现保护功能,透明性不高.文献[5]针对代码复用攻击,将目标进程的代码页设置可执行不可读,使代码可以被处理器正常执行,但在读操作时根据被读物理页面的存储内容对读操作进行访问控制,从而阻止攻击者利用信息泄露漏洞恶意读进程代码页的方法搜索gadgets,但该方法需要逐条分析被读物理页面的内容,效率较为低下.文献[6]通过修改现有的CPU架构实现保护应用程序在物理内存中的隐私数据和功能代码,但该方法对特殊的硬件架构依赖性高,通用性不高.文献[7]依据协同认证的思想,在内存中加入一种具有计算功能的硬件部件,由处理器与该部件协同完成内存数据完整性校验,实现一种附加硬件的内存完整性保护方法.文献[8]针对内存泄漏攻击,通过修改应用程序,将秘钥等敏感数据从内存转移到CPU的寄存器中,寄存器的数量和容量导致该方法不能适用于敏感数据量比较大的场景.

在隔离物理内存方面,文献[9]提出内存隔离方案,能够提供通过编译器自动修改程序代码,隔离敏感数据与普通数据,能够达到细粒度(以内存区域为粒度)的保护,该方法增加的了程序运行前编译器的负担,针对大型程序,运行时间成本比较高.文献[10]利用虚拟机监控器的NPT地址转换机制,为被保护应用程序建立一个新的NPT页表,并将新NPT页表中的其他应用程序和操作系统内核页表项设置为不存在,将原来NPT页表中被保护应用程序页表项设置为不存在,从而实现对保护应用程序的物理内存进行隔离的目的,但当应用程序占用的物理内存空间过于庞大时,遍历被保护应用程序的物理内存会严重降低系统性能.

针对上述利用虚拟化技术实现内存访问控制方法和物理内存隔离方法中存在的缺点,本文提出一种利用Intel VT的EPT机制隐藏应用程序进程物理内存的方法,实现对内存数据和代码的保护.该方法分3个阶段:1)实时监控进程切换,进程级粒度跟踪所有进程对内存的访问操作;2)采用高效的Hash算法对被保护应用程序的物理内存实现动态隔离和访问验证;3)设置EPT页表项访问属性实现物理内存访问控制.根据上述3个实现过程,本文设计了物理内存隐藏原型PMM,并在Intel平台上对原型系统进行了测试验证,实验结果表明,该方法能够隐藏被保护的应用程序访问的物理内存,并且引入较少的系统性能开销.

2 EPT机制实现原理

2.1 EPT简介

EPT(Extend Page Table,扩展页表)是Intel在VT-x技术基础上增加的一种硬件辅助内存虚拟化技术(1)https://software.intel.com/content/www/us/en/develop/articles/intel-sdm.html.在处理器端,VMX架构通过引入EPT机制来实现VM物理地址空间的隔离.当客户机通过指令访问内存时,首先,客户机操作系统通过分页机制将线性地址(linear address)转换为客户机物理地址GPA(Guest-Physical Address),然后,通过定义在VMM中EPT页表将GPA转换为主机物理地址HPA(Host-Physical Address),从而访问真正的物理地址.

2.2 EPT地址转换

客户机应用程序通过线性地址访问物理内存,当虚拟机监控器开启EPT机制并建立相应的EPT页表结构后,线性地址到HPA的转换如图1所示,以Linux操作系统二级页表结构进行地址转换为例,其中CR3中保存的是客户页目录表的物理内存基地址,页目录中的页目录项保存的是客户页表的物理地址,页表中的页表项保存的是客户物理地址GPA的高位部分.

图1 线性地址到HPA的转换Fig.1 Linear address translates to HPA

上述整个转换过程需要进行3次EPT地址转换,而一次EPT地址转换需要经过4次页表转换.

3 物理内存动态隐藏方法

系统进程或内核模块实现恶意功能的关键在于修改内存中的代码或数据,本文结合恶意代码的该种攻击特点,并针对上述内存保护方法中存在的缺点,提出了一种利用EPT的动态物理内存隐藏方法.

3.1 原型概述

如图2所示,基于EPT机制实现的物理内存隐藏原型系统框架涉及到计算机系统的应用层、虚拟层和硬件层.应用层的通信模块负责与PMM进行交互,包括启动PMM对被保护应用程序的物理内存进行隐藏,以及显示PMM的监控信息和异常信息.本文通过执行VMCALL指令传递相应参数开启PMM的物理内存隐藏功能.当执行VMCALL指令时,触发VM exit,陷入PMM,在PMM中判断VM exit事件类型,如果是VMCALL指令,当传递的参数与预先设置的参数匹配时,则启动PMM的物理内存隐藏功能.PMM中的3个组件是该系统框架的核心,该部分在轻量级虚拟机监控器BitVisor1.4框架上实现,包括系统进程监控模块,GPA地址隔离与访问验证模块和EPT物理页属性设置模块,其中系统进程监控模块实现对系统进程切换的实时监控,并获取进程信息.GPA地址隔离与访问验证模块利用Hash算法对被保护应用程序的物理内存进行动态隔离,并在访问过程中进行访问验证,该模块是实现物理内存隐藏保护的关键.EPT物理页属性设置模块通过对EPT页表属性的切换实现对物理页的访问控制.具体的设计及实现细节见下文.

图2 物理内存隐藏原型系统框架Fig.2 Physical memory hiding prototype system

3.2 进程监控与信息获取

进程是应用程序的执行实体,实现对进程切换的监控是获取应用程序访问的物理内存的前提.文献[11]将寄存器CR3的更新操作作为系统进程切换的监控点,因为系统的每个进程在发生切换时都会将CR3更新为自己页目录表的物理内存基地址.但高版本的Linux为了提高进程切换的效率,在切换进程时,如果即将转入执行状态的进程的页目录表的物理内存基地址与上一个进程的不同,才会更新CR3,当两个进程共用同一块物理内存时,基地址相同,不需要更新CR3,所以监控CR3的更新操作不能获取全部进程信息.

本文通过分析与进程上下文切换相关的内核函数_switch_to发现,当该函数实现的上下文切换过程完成对thread_info的更新操作后,会执行一个CLTS指令清除CR0进程切换标志位—TS,而此时获得的进程就是即将转入执行状态的进程,而且每个进程切换都会执行该操作,同时CLTS指令的执行能够被PMM监控到,因此本文将CLTS指令的执行作为进程切换的监控点.而thread_info与内核堆栈stack以及进程描述符task_struct的结构关系如图3所示,thread_info与内核堆栈stack共用一块大小为THREAD_SIZE内存,因此可以通过内核堆栈栈顶指针esp的值和THREAD_SIZE的值确定thread_info的位置,由thread_info定义可知,thread_info的起始地址即为当前执行进程的进程描述符task_struct的首地址,然后根据task_struct变量的偏移值可以获取当前执行进程的详细信息.

图3 thread_info与task_struct关系Fig.3 Relation of thread_info and task_struct

3.3 物理内存动态隔离与访问验证算法

通过上述对系统进程监控的实现,能够获取被保护进程的详细信息,包括进程名(comm),进程号(pid)以及进程描述符task_struct的物理地址(task_struct),由该信息可以唯一定位一个系统进程,从而能够准确获取该进程物理内存信息.

本文实现的方法基于Intel VT的EPT机制,没有修改系统的内存管理结构以及增加新的页表映射机制,而是在GPA转换为HPA之前增加了对被保护应用程序的GPA地址进行隔离和访问验证.通过动态Hash映射机制,实现对被保护应用程序物理内存的动态隔离,并通过检测系统进程访问的GPA是否被Hash实现对物理内存的访问验证.

当客户机应用程序首次访问物理内存空间时,由于EPT对应的页表项不存在,会引起EPT violation,产生VM exit,陷入虚拟机监控器,EPT机制会为GPA分配物理内存HPA,并根据页属性建立相应的EPT页表项.本文通过系统进程监控模块获取的进程信息判断GPA的所属进程,将被保护应用程序的GPA与其他GPA进行分离.在Linux系统中,一个应用程序的正常执行通常需要大量的物理内存空间,因此采用一种可以动态匹配、快速查找的方式对物理内存地址进行组织是降低系统负载的关键,这种要求正好符合Hash算法的特点.而实现Hash算法的关键在于设计一个能够避免冲突、均匀分配关键字、计算简单的散列函数.本文设计了一种动态扩展Hash算法,能够实现动态扩展Hash表上限,为此,我们以ReHash()的方式对HashTableSize按素数长度进行扩展,然后,针对一个GPA采用3次Hash映射,降低Hash冲突.该算法包括初始化Hash表,动态扩展Hash表,Hash一个GPA,检测一个GPA是否被Hash等功能函数,算法如下.

算法1.将当前进程访问的GPA映射到Hash表

输入:Hash表HashTable[],当前进程访问的GPA

输出:当前进程访问的GPA是否被Hash,被hash返回1,否则返回0;

1. InitHashTable();

2. if(GPA)

3. {

4. If(TableUsed >=HashTableSize)

5. Rehash();

6. If(Hashed(GPA)==0)

7. return Hash(GPA);

8. else

9. return 1;

10.}

由于该算法能够实现动态扩展Hash表,所以实验中被Hash的GPA个数小于或者等于Hash数组的上限.结合实际情况,我们证明通过3次Hash,产生Hash冲突的概率在可接受的范围之内.可设应用程序被Hash的GPA个数为n,GPA的集合为G,任何一个GPA为g,且满足g∈G,Hash表的上限为m,Hash数组集合为M,M可对应一个1行m列的矩阵A=[1,2,3,…,m],且总是满足n≤m,Hash次数为q.我们证明当q=3时,通过该算法能够将Hash冲突降到可接受的范围内.

可得推导结果,由于m≤m2≤m3,因此,当q=3,对每一个GPA执行3次Hash,所有GPA产生冲突的概率最小,并且,在实际情况下当q=3时,没有产生冲突的情况,能够满足实际需求.

3.4 物理内存访问控制方法

当应用程序访问主机物理内存HPA时,如果EPT页表项的访问属性位bit2:0全为0、readable位为0、writeable位为0或executable位为0,能够引起EPT violation,并产生VM exit.因此,可以通过设置对应的EPT 页表项的属性位,实现对物理内存的访问控制.

实现流程如图4所示,当PMM监控到被保护应用程序的执行进程发生切换时,当应用程序第一次访问物理内存时,对应的EPT页表项不存在,会引起EPT violation,并且发生VM exit陷入PMM.此时,首先由GPA地址隔离与访问验证模块对当前的GPA进行Hash,并建立对应的EPT页表项,同时设置EPT页表项属性为readable,使任何进程对被Hash过的GPA对应的HPA进行访问都会产生一个EPT violation,并由PMM处理这次访问事件.

图4 物理内存访问控制实现流程Fig.4 Realization of physical memory access control

再次出现进程访问主机物理内存时,首先判断该进程是否为被保护应用程序的执行进程,若是,则判断当前访问的GPA是否被Hash,若没有被Hash,则进行Hash,并建立对应的EPT页表项,同时设置EPT页表项属性为readable,若已经被Hash映射,则修改当前的对应的EPT页表属性为可读、可写、可执行,允许被保护应用程序的执行进程访问主机物理内存.此时,我们通过程序指令级监控实现这个访存过程.指令级监控是利用EFLAGS寄存器的TF(Trap Flag)标志位实现,TF标志位是进程的跟踪标志位,用来控制CPU在单步调试模式下执行一条指令,当TF标志位被设置为1时,当前指令执行后会产生一个中断,当TF标志位被设置为0时,当前指令执行后不会产生中断.因此当被保护应用程序的执行进程访问已经被Hash过的GPA时,在PMM中将该进程EFLAGS标志寄存器的TF标志位设置为1,然后执行VMRESUME返回客户机执行内存访问操作,保证在客户机应用程序执行完访问物理内存的指令后再次产生VM exit,陷入PMM,然后将刚被访问过的物理内存对应的EPT页表项属性设置为readable,保证下次对该物理内存进行访问时仍能够产生EPT violation;若当前的访问进程不是被保护应用程序的执行进程,也要先判断当前被访问的GPA是否被Hash,若是,则表示当前进程正在访问被保护应用程序的GPA,为了阻止该访问,本文的解决方法是通过执行add_ip()函数跳过该访存指令;若不是,则允许访问.

4 实验与分析

本文对原型系统PMM功能和性能两个方面进行了测试.功能测试主要根据物理内存隐藏方法实现原理检测该方法能否对被保护应用程序的物理内存实现隐藏功能,即利用本文方法实现对被保护应用GPA的动态隔离和访问验证.性能测试用于测试在利用该方法隐藏被保护应用程序的物理内存时,PMM引入的监控开销,实验环境如下:客户机为Intel(R)Core(TM)i7-3770 @3.4GHz处理器,16GB内存,Ubuntu-12.04LTS64位操作系统,内核版本号为Linux 3.2.0-29-generic,虚拟机监控器为BitVisor1.4.

4.1 功能测试分析

功能测试主要包括3个功能模块测试:1)监控系统进程切换,获取被保护应用程序的执行进程信息,在这里假设被保护的应用程序是一个脚本程序start.sh,执行进程对应一个守护进程;2)利用本文设计的Hash算法动态隔离被保护应用程序的GPA,并进行访问验证;3)阻止非法进程非法访问被保护应用程序的物理内存地址.

4.1.1 监控系统进程

监控系统进程,主要用来获取被保护应用程序start.sh的执行进程信息,通过与在应用层执行“ps-e |grep start.sh”获取到的进程信息进行对比,测试在PMM中监控到的目标进程的准确性,实验结果如图5所示.

图5 目标进程的关键信息Fig.5 Key information of target process

4.1.2 动态隔离与访问验证

应用程序执行后首次访问物理内存时,由于EPT页表中没有对应的EPT页表项,会引发EPT violation,同时产生VM exit陷入PMM.此时,PMM中的GPA动态隔离与访问验证模块对被保护应用程序的GPA利用Hash算法进行动态隔离,并设置对应的EPT页表项属性为readable,实验结果如图6所示.

图6 利用Hash算法对GPA进行动态隔离Fig.6 Hash algorithm dynamic isolate GPA

当被保护应用程序访问已经被Hash的物理内存时,由于被Hash的物理内存对应的EPT页表项已经被设置为readable,因此,同样会引发EPT violation,陷入PMM.此时,首先设置EFLAGS的TF位,并通过执行VMRESUME命令实现单步访存操作,访存结束后再次陷入PMM,重新设置刚被访问过的GPA对应的EPT页表项属性为readable.而其他进程能够通过两种方式对被保护应用程序的物理内存进行非法访问:第1种是获取root权限,以特权进程的方式直接访问被保护应用程序的物理内存,第2种是通过操作系统漏洞,将被保护应用程序的物理内存映射到其他进程的物理地址空间,从而以任意权限访问被保护应用程序的物理内存,针对这两种方式,本文提出的方法首先判断当前的访问进程,然后判断当前进程访问的GPA,如果该GPA已经被Hash过,但是当前进程不是被保护应用程序的执行进程,则跳过该访存操作.因此,本文提出的方法能够有效隐藏被保护应用程序的物理内存,防止其他应用程序的非法访问.

4.2 性能测试分析

本文方法主要在两个方面会产生额外的系统开销:首先是利用该方法对每个系统进程访问的物理内存地址都需要进行Hash判断.当系统进程是被保护应用程序的执行进程时,还需要对未被Hash的GPA进行Hash,其次,如果当前系统进程是被保护应用程序的执行进程或者是其他进程时,当被访问的物理内存地址已经被Hash,还需要对GPA对应的EPT页表项属性进行相应设置,保证物理内存被安全访问,同时这两个方面会引起VM exit和VM enrty的发生.测试中使用lmbench3.0分别测试了原操作系统(Phys)和加载PMM后的操作系统(PMM)的在系统调用(null call)、I/O操作(null I/O)、信号处理(sig inst和sig hndl)、进程相关处理(fork、execve、ctxsw)、物理页处理(Prot Fault和Page Fault)、物理内存访问(Mem read,Mem write和Rand mem)以及文件操作(File create和File delete)等方面的性能,测试结果如图7所示,图中所有测试结果单位均为us,柱状条越高,说明带来的性能开销越大.

根据测试结果可知,由于PMM未对系统调用(NULL Call)、I/O操作(NULL I/O)及信号处理(Sig Inst和Sig Hndl)进行陷入和监控,均直接交由处理器执行,因此开启PMM后上述几点均未引入额外开销.由于PMM开启了对系统进程的实时监控,因此与进程切换相关的开销,如fork进程后再退出(Fork Porc)、执行execve后再退出(Exec Proc)和进程上下文切换过程(Ctxsw)等开销有所增加.由于本文利用EPT机制实现对被保护应用程序访问的物理内存进行访问控制,会涉及到页表属性设置以及缺页情况的处理,因此在页保护属性设置(Prot Fault)和缺页处理(Page Fault)等开销会有所增加.

图7性能测试结果Fig.7 Performance test result

除此之外,为了更加清楚的说明利用EPT机制实现对物理内存的访问控制所带来的性能开销,该实验增加了读、写1k物理内存时的性能测试以及物理内存随机访问性能测试,测试结果表明,开启EPT机制后执行以上3种操作会带来额外的性能开销.同时,当进程创建和删除大小为1k的文件时,同样会增加系统性能开销.

综上对性能测试结果的分析,与原物理机相比,利用EPT机制实现对被保护应用程序访问的物理内存进行访问控制会增加系统性能开销,但增加幅度均在10%以内.

4.3 测试结果分析

根据功能测试和性能测试结果可知,本文提出的基于EPT的物理内存隐藏方法能够有效的保护应用程序访问的物理内存空间,并且阻止其他应用对被隐藏物理内存空间的非法访问,同时该方法不影响客户机系统的正常运行,引入的系统开销在可接受的范围内.

5 总 结

本文首先分析了EPT内存虚拟化机制实现原理,应用程序访问的GPA需要经过EPT转换为HPA才能访问真正的物理内存,利用这种特点,能够在更底层实现对物理内存的访问控制.然后,利用本文设计的Hash算法实现了对被保护应用程序物理内存的动态隔离,同时对访问被保护应用程序物理内存的进程实现了访问验证.最后,通过设置EPT页表的只读属性位,实现对物理内存的访问控制,保证了对被保护应用程序物理内存的访问能够被PMM捕获和阻止.实验结果表明,该方法能够实现上述中的各项功能,并且引入较小的系统性能开销.

猜你喜欢

访问控制进程应用程序
一种跨策略域的林业资源访问控制模型设计
删除Win10中自带的应用程序
Dalvik虚拟机进程模型研究
谷歌禁止加密货币应用程序
云的访问控制研究
快速杀掉顽固进程
不留死角 全方位监控系统
云计算访问控制技术研究综述
中外民主法制进程专题复习
三星电子将开设应用程序下载商店