今天分享的是一篇发表于TDSC 2018的paper 《Building a Trustworthy Execution Environment to Defeat Exploits from both Cyber Space and Physical Space for ARM》。
由于已有的基于TrustZone的安全技术,其安全服务的API和普通操作系统完全不同,并且相对独立。为此,本文提出了TrustShadow,利用TrustZone,来安全的运行未更改的应用程序。一方面,TrustShadow支持已有的代码;另一方面,支持TrustZone的设备非常广泛。因此,TrustShadow可以立即部署在现实世界,并保护已有的、不需要修改的代码。
TrustShadow的基本思想是,可信的进程仍然由普通世界的Linux内核来创建和管理,但是,其运行必须在安全世界中。显然,可信进程所使用的物理内存必须是安全资源,这样可以防止Linux内核对其进行访问。可信进程在安全世界的运行环境,比如页表的创建、系统服务由安全世界的一个轻量级运行时来维护。 为了减小其TCB,安全运行时并不直接参与这些服务,而是把他它们转发到正常世界的Linux内核,然后,验证其行为是否可信。显然,验证一个行为正确性的复杂性远远低于实现它,因此,安全运行时可以保持很小的TCB。通过这些验证机制,确保可信进程的以下安全特性:
1.运行过程中,可信进程和普通操作系统隔离,普通操作系统不能访问可信进程的数据和代码。
2.载入阶段,保证可信进程的代码的完整性。
3.验证系统调用的返回值,来抵抗Iago攻击。
4.加密文件操作,使得写入磁盘的数据是密文,防止不可信操作系统的访问。
以缺页中断为例:
当进程由于访问.text而发生缺页,安全运行时把该异常转发给普通世界的Linux内核,Linux找到对应的文件缓存页N-page,安装页表,同时给可信进程分配一个安全的物理页S-page。安全运行时接管后,首先验证S-page是否真的安全资源,其次验证S-page是否和别的物理内存存在double-mapping,只有在安全验证都通过以后,安全运行时才安装可信的页表,并把N-page的text段内容复制到S-page。最后,使用储存在安全世界的元数据来验证该代码页是否经过篡改,如果没有,则返回可信进程继续执行。至此,普通Linux不能对改代码页进行任何修改。
当然,把进程运行在安全世界,如果有漏洞,则可能被攻击者利用,反过来攻击普通世界的Linux内核,因为安全世界的权限大于普通世界。在TrustShadow的设计中,作者利用以下几点来防止这一隐患。第一,TrustShadow支持未经修改的程序,并不意味着所有程序都可以在安全世界运行。TrustShadow对可信进程进行严格审查,通过审查的程序,需要绑定一个签名的manifest,安全运行时检查该manifest的有效性来判断是否允许其在安全世界运行;第二,由于可信进程运行在用户空间,即使其有漏洞,也需要进一步exploit安全运行时,才能构成有效攻击;第三,安全运行时进行了极简的设计,其对可信进程暴露的接口很少(仅仅转发异常和检查系统服务返回值)。而且,5000+的代码量,也使得形式化验证成为可能。
作者在NXP的i.MX6q开发版上实现了以上设计,并成功运行了Apache、Nginx等大型程序。
原文始发于微信公众号(COMPASS Lab):《论文分享》TrustShadow