内容简介:作者:Tommaso Frassetto, Patrick Jauernig, Christopher Liebchen, Ahmad-Reza Sadeghi单位:Technische Universität Darmstadt, Germany出处:USENIX Security 27th
作者:Tommaso Frassetto, Patrick Jauernig, Christopher Liebchen, Ahmad-Reza Sadeghi
单位:Technische Universität Darmstadt, Germany
出处:USENIX Security 27th
1. Abstract & Introduction
现在,研究者们已经提出了很多复杂的攻击技术,例如(JIT/blink)ROP、Counterfeit object-oriented programming。这些技术都能够使得攻击者达到任意代码执行、数据攻击的目的。与此同时,研究者们也提出了很多针对代码重用攻击的的防御方案,例如Control-flow integrity(CFI),Code-pointer integrity(CPI)。但是这些防御方案都依赖着较强的Memory isolation的保证,例如CFI的Shadow stack,CPI的Safe-region,以及一些随机化的秘密,都是需要进行隔离,不能被攻击者随意读写。由此可见进程内的内存隔离的重要性。
另外,进程内的内存隔离和进程间的内存隔离的区别从下图可以看出:
本文中,作者为Intel的x86 CPU设计了一个轻量级扩展IMIX,IMIX可以做到进程内的内存隔离。作者采取的办法是扩展x86的指令集架构,增加一个新的内存访问的权限,用来标识内存页是否是安全敏感。这些内存页只能被新设计的指令来访问。与之前的工作不同的是,IMIX并不是一个完整的防御方案,而是作为Primitive来使用。
2. Adversary Model
Memory corruption:作者假设已经存在了一个Memory corruption的漏洞,通过这个漏洞,攻击者能够重复地进行数据的读写。
Sandbox code execution:攻击者可以正常执行已经受保护的应用程序的代码,但是攻击者只能通过Memory corruption漏洞来影响应用程序。同时应用程序采用了CPI或者CFI以及代码随机化这样的技术来抵御任意代码执行。然而攻击者可以尝试通过Memory corruption漏洞来绕过这些缓解措施,并且假设要绕过缓解措施,需要破坏缓解措施中的metadata。
3. IMIX设计
如下图所示是IMIX的架构。 缓解措施的正常工作依赖于其本身的数据和代码的完整性。由于像CPI和CFI这样的缓解措施,需要将他们的metadata都保存在被保护进程本身的内存空间里,以避免过高的性能开销。因此攻击者可能会利用应用程序本身的Memory corruption漏洞来破坏metadata,从而绕过缓解措施。
传统的方法里,防御方案开发者通过实施W ⊕ X或Execute-only memory来保证代码的完整性,而数据完整性就依赖于其他的进程内内存隔离来保证。然而现有的内存隔离技术,例如Instrumentation和Data hiding,都需要使用者在高性能开销和安全性之间进行抉择。
作者设计的IMIX提供了高效率,安全性,基于硬件的进程内内存隔离方案。那些属于缓解措施本身的metadata会被分配到 isolated pages ,然后标上一个特殊的访问权限。只能用作者提出的 smov
指令来进行数据访问。除了 smov
指令,IMIX还包括内核扩展以及编译器支持。
3.1 Hardware
smov
指令重用了 mov
指令的逻辑。 修改了内存访问逻辑,下面情况会触发fault: 1. 除了 smov
以外的对隔离内存的访问 2. smov
被用来访问普通的内存
也就是说,访问普通内存用 mov
,访问保护内存用 smov
。这里需要注意的是为什么 smov
不能访问普通的内存,可以考虑在CPI方案下的这种攻击:攻击者修改了某个指针,这个指针本身应该指向Safe region,但是现在攻击者把他指到自己可控的一个buffer(在普通内存里),这时候假设程序已经采取了IMIX,然后程序尝试用 smov
去解引用指针,就是不允许的了,也就是能成功防御住这种攻击。
3.2 Kernel
内核态通过Page tables来进行虚拟内存和物理内存的映射,每个页在Page table里被描述为PTE(Page table entry),PTE里包含了一些metadata,metadata里描述了一些关于这个页的访问权限。用户空间的程序可以通过系统调用来请求修改这个页的访问权限。
作者在内核上的扩展就是提供了一个额外的IMIX保护的访问权限,
3.3 Compiler
IMIX提供了两个上层Primitive: 1. 分配保护内存 2. 访问保护内存
这些内存保护的Primitive既可以用在缓解措施上,也可以用在敏感数据的保护上。IMIX为这两种用途都提供了优化过的接口,例如: 1. 像CPI这样的缓解措施是作为LLVM的pass来实现的,工作在IR层。IMIX提供了一些IR primitive用来进行IR的修改 2. 对于应用程序开发者来说,IMIX提供了源码标注:特殊标注的变量会被分配在保护内存里,所有的对这个被保护的变量的访问会通过 smov
实现
4. Implementation
4.1 CPU Extension
作者将IMIX Protection flag放在PTE的第52个bit,因为这个bit没有被CPU保留,通常是被MMU无视的。CPU需要更新一下来支持IMIX的访问策略,非 smov
指令只能访问普通页, smov
指令只能访问隔离页,否则CPU就会抛出一个fault。这个逻辑的实现需要对下x86-64指令集架构进行修改。作者使用了一个硬件模拟器来展示他们的设计的。
作者想要选择Wind River Simics(全系统模拟器)来进行IMIX的模拟。但是Simics这个模拟器比较慢,没办法启动 Linux 内核。因此作者使用了Intel Simulation and Analysis Engine(SAE)add-on。之后的文字里就通过SAE来简单代表这两者的结合。SAE支持模拟完全的x86系统。对于CPU,内存,以及相关的硬件例如MMU的插桩,作者是使用 ztools 来实现。 ztools 是用C/C++实现的一个共享库。
为了对模拟的系统进行插桩, ztools 为一些特殊的hook注册了回调。作者首先通过注册Initialization hook的回调来确认 ztool 以及被初始化成功。然后注册一个回调,当新的指令被添加到CPU指令cache时就会执行。如果有 mov
或者 smov
访问内存的指令出现了,就会再注册一个指令替换的回调。这个注册的回调能够替换指令,或者选择执行原来的指令。在这个回调handler里,作者实现了IMIX的访问逻辑。 1. 检查指令所访问内存的的IMIX Protection flag 2. 如果是普通的指令尝试访问普通的内存,就会继续执行原来的指令,以防止指令Cache的修改;如果是 smov
指令尝试访问隔离页,就首先将指令从指令cache里去掉,然后执行 ztool 实现的指令。其他情况就会抛出一个fault。
4.2 Operating System Extension
操作系统需要做的事是为隔离页在PTE里标记出IMIX Protection bit。作者修改了Ubuntu 16.04 LTS发行版的默认内核(当时是4.10)。进程可以通过mprotect系统调用来请求内核对页进行标记(用PROT_IMIX这个flag)。这里需要注意,页一旦被标记为PROT_IMIX,要想去掉这个flag,就只能unmmap这段内存。
4.3 Compiler Extension
作者修改了LLVM 5.0(选择LLVM而不是GCC的原因是大部分的Memory-corruption防御方案用的都是LLVM),并且移植到了LLVM 3.3(CPI用的是LLVM 3.3),这个修改主要是在IR上,为CPI提供 smov
指令,以及x86的后端,用来生成机器码。另外,还设计了一个attribute,可以用来隔离单个变量,例如保护Cryptographic secret。
对IR的扩展:IR通常提供两种内存访问指令,即 load
和 store
, load
指令从内存读数据到Temporary register, store
指令用来把Temporary register的数据存到内存里。因此作者设计了两个IMIX对应的指令,即 sload
和 sstore
.
Attribute:Data-only attack通常很难防御,为了给开发者在源码级别有效的方法去防护敏感的数据例如Cryptographic keys,作者设计了一个IMIX attribute,可以在编程时通过对变量进行标注,从而使得其分配在隔离页。所有的队标注出来的变量的访问都会使用IMIX IR的指令。
对x86后端的修改:处理 sload
和 sstore
两个IR指令。
4.4 Case Study: CPI
作者将CPI进行了移植,使用上IMIX。CPI使用了Safe region特性来保证代码指针的完整性,以及抵御代码重用攻击。所有的代码指针,指向指针的指针等等,都会被移到Safe region,这样Memory corruption漏洞就没办法覆盖到它们了。返回地址会用Shadow stack来保护。CPI的安全性依赖于保护x86-64的Safe region不被修改,CPI将Safe region放在一个随机的地址处,并且将地址保存在Segment里(通过段寄存器%gs来获取)。在编译时,CPI的pass会将所有的代码指针和额外的关于边界的metadata移到Safe region。已经有研究表明CPI的实现是脆弱的,因为Safe region的位置是是可以爆破的。
作者将Data hinding的工作用IMIX来实现: 1. 修改CPI的内存分配函数,不仅仅是分配Safe region,还需要设置IMIX Protection bit 2. 修改Compiler runtime,提供对Safe region的访问( smov
)。
5. Security Analysis
攻击者想要访问被保护数据,就需要用 smov
来进行访问,因此作者只能依赖于代码注入或重用可信代码,或者操作数据流,或者访问IMIX的配置接口
5.1 Attacks on Trusted Cocde
IMIX假设代码注入攻击,代码重用可以用现有的缓解措施例如W⊕X、CFI、CPI来防御。这样攻击者就不能注入 smov
指令或者是访问重用可信代码了。
5.2 Attacks on Data Flow
数据流攻击通常是很难防御的,可信代码需要保证输入的数据是来源于由IMIX保护的数据,或者在使用数据前先进行过滤。
5.3 Attacks on Configuration
一个绕过缓解措施的普遍的访问就是把缓解措施关掉,例如想要绕过W⊕X,可以通过代码调用mprotect系统调用将数据段标为可执行。
攻击者有两种方法重新配置IMIX: 1. 利用操作系统的接口修改内存访问权限 2. 直接操作PTE
对于第一种方法,作者假设攻击者能修改mprotect系统调用的参数,但是由于接口已经保证IMIX页是不能取消IMIX标志位的,除非unmmap,所以是不可行的。
对于第二种方法,假设攻击者在内核里有Memory corruption的漏洞,作者认为内核也同样可以使用IMIX来进行保护,例如隔离页表。
6. Evaluation
实验环境:Ubuntu 14.04 LTS,Linux Kernel 3.19.0,Intel Core i7-6700 CPU、32GB RAM
测试数据集:SPEC CPU2006 benchmark suite
作者将IMIX的实现移植到了CPI上来隔离Safe region。
IMIX在性能上表现地相比MPK、MPX要出色。这里由于硬件是用模拟器模拟的,因此在跑数据集的时候很慢,作者就将smov里的指令都替换成了mov指令,在计算机上直接跑。
7. Related Work
如下是各个相关技术的一些特征的对比。 – Policy-based Isolation指的是内存保护本身是没办法通过任意内存读写绕过的。 – Fast Interleaved Access指的是频繁的访问隔离内存和非隔离内存不会带来额外的开销。 – Fails Safe指普通内存访问指令不能访问保护内存
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Algorithms on Strings, Trees and Sequences
Dan Gusfield / Cambridge University Press / 1997-5-28 / USD 99.99
String algorithms are a traditional area of study in computer science. In recent years their importance has grown dramatically with the huge increase of electronically stored text and of molecular seq......一起来看看 《Algorithms on Strings, Trees and Sequences》 这本书的介绍吧!