-------------------------SgxPectre-------------------------
基本原理:转移猜测提供瞬态执行窗口+微架构侧信道。
【Spectre V1:一开始多次读取合法数据,会执行分支跳转,然后使得多次分支预测训练为Token,突然来一个非法数据读取,但是分支预测器仍然预测Token,从而出现瞬态指令执行窗口,也就是说本来没有能力读取的数据被猜测执行,被加载到缓存的非法数据能被攻击者利用侧信道窃取。通过加上lfence使得分支判断条件执行完(load指令执行完)才能执行分支里面的load数据的代码。】
【SgxPectre原理类似Spectre V1,但是前者场景是窃取内核秘密,SgxPectre场景是窃取SGX秘密。】
如下是受害者Enclave的部分代码(/enclave/enclave_attack.c)。其中值得注意的是secret是”The Magic Words are Squeamish Ossifrage”。另外,原POC中没有加入sgx_lfence函数(可以利用sgx_lfence防御)。
进入POC目录,执行./sgxspectre main_test。可以发现秘密被逐bit的窃取。
防御
使用sgx_lfence函数来保证当前依赖于秘密的分支不会“转移预测”,也就说sgx_lfence要求前面分支的判断条件的load指令执行完毕才能进入分支执行语句。这种方案能够防止SGXSpectre攻击,但是会带来性能开销,并且需要开发人员或编译器及时的写上sgx_lfence。
修改代码,重新编译。防御效果如下,敌手无法知道具体秘密了
-------------------------Foreshadow(CVE-2018-3615)-------------------------
基本原理:乱序执行(清P位页错误产生瞬态执行窗口)+L1缓存侧信道。
【Meltdown在指令执行过程中发生异常(比如说页错误)时,会提供后续指令的瞬态执行窗口。内核数据泄漏到缓存中被缓存侧信道窃密。缓存侧信道比如Flush+Reload等。】
【Foreshadow原理大致与Meltdown类似。但是SGX的引入了中止页面语义。处理器访存会先判断页错误,然后判断中止页面语义。当访问SGX数据时,如果没有触发页错误,中止页面语义会拒绝访问(比如读取的话返回-1),但并不触发异常,因此没有了瞬态执行的窗口。解决方法是通过撤销数据所在页表项的标志位(Present位),从而使得操作系统错误以为当前页不在内存中,发生缺页中断,提供了瞬态执行的窗口。秘密加载进缓存被攻击者用Reload探测。】
由于目前Intel处理器已经被打上了微码补丁,为复现攻击效果,需要在grub中关闭dis_ucode_ldr。启动sgx-step内核模块,然后进入foreshadow目录make run。效果如图,共4列,左边两列一组,右边两列一组,每一组的左边列是秘密猜测值,右边列是秘密真实值(参考值)。发现这一次攻击中64字节均猜测成功。
防御
在grub中取消dis_ucode_ldr,也就是启用微码更新(Intel的这个微码更新会在进出Enclave时刷新L1D缓存,从而防御Foreshadow),重新执行Foreshadow,发现成功防御了,效果如下。
【微码的概念是说Intel的CISC为了模仿RISC指令集精简带来的高频率优势,Intel自己做了一个微码概念,会将原有CISC指令翻译为微码概念,就有一层从CISC指令到微码的一个类似于编译器的概念。微码补丁是在一个块进行相关的工作。】
*原著中的讨论
瞬态攻击针对猜测执行乱序执行,传统针对非特权敌手攻击特权内存。本文针对SGX这种非层次化(APP和Enclave同属于用户态)的地址空间隔离,需要研究进一步的防御机制,KAISER无法防御Foreshadow,页表隔离方法也被淘汰,因为SGX中,OS也是不可信的,并且Enclave的线性地址也在宿主进程的地址空间中。
Foreshadow利用了微架构漏洞,但是不会影响SGX和TEE它们的整体架构设计(仍然十分有价值)。现代处理器超出了作者的理解程度,希望以后研究社区发展可替代性的软硬结合的协同设计,以后发展开源的可检测的TEE使得更方便地定位、缓解、防御漏洞。
已有方法不治本,依赖TSX检测可疑的页错误和中断率。但很多平台不支持TSX,另外EGETKEY指令不能放在TSX事物中,再者,就算不适用SGX-Step这种高中断率方法,也可用偷窃型Foreshadow(相邻逻辑核窃取),ELDU指令可以不需要受害Enclave执行(无法软件层面防御。
Intel针对幽灵熔断在硅上改。希望对Foreshadow也硅上改。SGX通过在所有度量中引入CPU SVN实现TCB恢复,以后希望有微码更新来缓解Foreshadow。
未来可用微码更新缓解Foreshadow(像幽灵那样),考虑到问题本质乱序执行,因此微码升级不能根源上解决问题。Foreshadow利用L1秘密,所以可以让同一Enclave独占物理核;Enclave退出时刷新L1(这一点微码补丁已经实现了).
-------------------------BranchScope-------------------------
基本原理:共享分支预测器+影子分支与受害者分支地址碰撞,使得影子分支使用同一个预测器来推测受害者的分支方向。
【受害者和攻击者共享分支预测器PHT,攻击者一开始让PHT处于临界状态(两位饱和计数器,01、10)。执行受害者的if分支,如果Token,则PHT下次会预测Token,如果No Token,则PHT下次预测No Token。然后攻击者执行一个if分支,地址设计的刚好和受害者的那个if分支碰撞(PC低位相同),目的是能够刚好用刚才提到的PHT去预测攻击者的if分支,然后这个预测结果可以用PMC(原著是用影子分支)提取出来(比如判断是否猜测错误,比如根据分支判断条件Token的,猜测错误说明预测No Token)。一旦攻击者知道预测的情况,就知道PHT被训练成什么样子,进一步,就知道受害者是执行怎么样的分支使得PHT被训练成那样。也就是说攻击者这边的预测结果反映了受害者的实际执行结果。】
安装驱动。执行spy进程窃听victim进程(左),然后启动victim进程(右)。发现除了第一位预测错误外,其余均预测成功。
防御
通过修改编译器层面,在受害者if分支前随机的增加若干个NOP指令,让受害者的if分支和攻击者的if分支没法地址碰撞(PC低位相同),也就是两者没法使用PHT的同一项。
*原著中的讨论
1. 软件方面缓解
通过算法移除依赖于秘密数据的分支结果,这种技术被称为if-conversion,是一种编译器优化技术。它使用条件指令(如cmov)将条件分支转换为顺序代码,有效地将控制依赖关系转化为数据依赖关系。通过移除条件分支指令,从而缓解BranchScope攻击。然而,将这种保护机制应用于大型代码库是很困难的,只能局限于使用敏感数据的程序的关键部分。
2. 硬件防御
通过对分支预测器的结构进行重新设计也可缓解这个攻击,具体的缓解措施包含:
2.1 PHT随机化
BranchScope需要在PHT(模式历史表,pattern history table)中创建可预测的冲突(例如,基于虚拟地址)。为了防止这种冲突,可以修改PHT索引函数作为该软件实体唯一的输入数据。这可以作为SGX硬件状态的一部分,也可以是进程生成的一些随机数(也就是进程和PHT项一定意义上的绑定)。一次随机化容易受到探测攻击,因此可使用周期性的随机化(这会牺牲一些性能),这个解决方案类似于将缓存映射的随机化作为防止侧信道攻击的保护。尽管这种缓解技术具有负面的性能开销,但它为大多数安全敏感分支提供了完美的安全保护。
2.2 移除敏感分支的预测
指定某些敏感的分支不采取BPU(branch prediction unit,分支预测单元)猜测,而是采取静态猜测(总是猜测正确或错误)等方法
2.3 BPU分区
BPU分区可使攻击者和受害者不共享相同的结构。如,SGX代码可使用不同于普通代码的分支预测器,或者结构支持BPU私有分区,通过分区,攻击者失去了与受害者产生冲突的能力。
2.4 其它解决方案
除了以上的缓解措施,也可通过移除或增加性能计数器的噪声或测量时间来消除攻击者测量分支结果的准确能力。另一种方案是更改有限状态机(FSM,FiniteState Machines),使其更随机,从而干扰攻击者推断受害者分支方向的能力。最后一种解决方案主要在于探测攻击的痕迹,如果检测到正在进行的攻击,可冻结或者杀死攻击者的进程。在SGX中攻击者如果已经破坏了操作系统,这样就比较难办,检测到攻击程序正在进行时,需要SGX代码重新映射自身或停止执行。
2.5 以前的防御措施
幽灵变体1、2的某些缓解措施可能也能一定程度缓解BranchScope
-------------------------SGX-PTE-------------------------
攻击
基本原理:缓存侧信道反推被加载进缓存的PTE,进一步反推页地址链及控制流
*原著中的讨论
传统页错误利用撤销PTE权限引发页错误然后统计页错误来攻击。sgx-pte使用页表属性和未受保护的页表内存的缓存行为来推测Enclave访存。利用页表项的属性位来泄露,也就是说监视未受保护的页表来推测Enclave内存访问,而不需触发页错误。
- T-SGX使用基本块的连续事务中断数量这种启发式方式来防御。SGX-PTE可以绕过这个,因此需要更好的启发式防御。
- 一种方法是使用TSX特性保护线程不能被OS悄悄中止,并检测AEX数量是否异常的高。但这种启发式方法不能根本解决秘密泄露。
- 轻量级的PMA(受保护模块架构)在单地址空间实现(页表的)硬件隔离。高端PMA让敌手无法触摸到页表。但是这种想法在云环境下可能做不到(云提供商必须能够快速调节不同的云用户对包括EPC内存的稀缺的平台资源的争夺,因此很难隔离,或者说隔离严重影响效率。)
- Sanctum(一种低端PMA)将页表移入Enclave,OS通过漫长协议完成虚、实地址转换。在SGX(高端PMA)中,尽管可能实现类似的防御,但敌手仍然可以建立扩展页表,依然能实现页表属性的泄露。
- A、D(访问、脏)位屏蔽的方法,这种方法依然没法防止缓存泄露,同时这还会干扰正常的OS决策机制。
- 编译器优化
- 好的编程习惯(分支不依赖于秘密)
(按作者的说明,似乎目前没有什么好方法)