导语:在前几篇文章中,我介绍了SGX的内部和外部组件的构成,分析了SGX的安全特性,今天我们就来说说SGX可能遇到的攻击。

1533888772590542.jpg

在前几篇文章中,我介绍了SGX的内部外部组件的构成,分析了SGX的安全特性,今天我们就来说说SGX可能遇到的攻击。

边信道攻击(Side-channel Attack)

边信道攻击是一种对密码算法实现的有效的攻击,英特尔SGX多年来一直因其缺乏对各种边信道攻击的防御而被批评。虽然英特尔总是警告用户,必须以防止边信道攻击的方式编写enclave,但是一种完全安全的技术是不会对enclave开发人员施加这样的额外要求的。下面总结了对英特尔SGX的一些攻击,以便你可以了解到执行此类攻击所需的各种环境,以及执行这些攻击可以窃取哪些设备及系统信息。

英特尔SGX上的缓存攻击

为了在英特尔SGX enclave上执行缓存计时攻击,攻击者将两个内核线程固定到两个共享相同物理内核和L1缓存的逻辑内核(参见下图)。此时,受害者线程运行的算法版本容易受到enclave内部的缓存攻击。使用RDPMC指令完成对高速缓存行的探测,该指令要求计数器以管理员模式启动,这完全在SGX的安全模型中。

4.jpg

使用共享内存而不是ECALL / OCALL执行与enclave的通信,则不必从正在运行的enclave切换上下文,这就是攻击可能发生的环境。而ECALL / OCALL则会导致整个缓存被清除,从而阻止攻击的进行。

另外,攻击线程必须处于同一进程中,因为进程上下文切换需要更新页表(Page Table ,PT),因此必须更改包含PR的基址的CR3寄存器,这会触发TLB和L1缓存被刷新。

而SGX SDK的AES实现后,就不容易受到这种边信道攻击。

AsyncShock攻击:利用英特尔SGX Enclave中的同步漏洞

AsyncShock攻击的原理就是充分利用enclave内现有的同步错误,特别是,它有助于利用Use After Free(UAF)漏洞和Time Of Check Time Of Use(TOCTOU)漏洞。控制该平台的攻击者(在英特尔SGX的攻击模型中)可以随时中断enclave线程。

使用mprotect系统调用来中断线程,然后删除页面上的读取和执行权限。因为要在检查是否允许访问EPC页面之前执行传统的页面遍历,所以应用程序可以清除知道enclave访问了哪些内存页面(即使它无法查看页面包含的内容)。当线程退出enclave时,执行将在不受信任环境中的程序中恢复。

5.png

此时,应用程序启动允许执行的第一个线程,从包含free(3)函数的代码页中删除读取和执行权限。当线程调用free(3)函数时,发生访问冲突事件,导致应用程序捕获AEX和segmentation fault (即段错误,一般都是出现了非法的地址写法操作导致的)。在允许线程继续之前,将为此页面恢复权限,不过只删除包含调用指令的页面的权限。当下一个标记的页面被点击,则会导致另一个AEX和segmentation fault,此时会发出free(3)函数返回的信号。在信号处理程序中,权限被再次恢复。此时,第一个线程停止,第二个线程启动并进入enclave。此样本的代码可以在下面找到:

// Thread 1 enters the enclave
...
free(pointer);
// Thread 1 is interrupted, exits the enclave
pointer = NULL;
...
// Thread 2 enters the enclave
...
if (pointer != NULL) {
    // Thread 2 uses a pointer to freed memory
}
...

结合结构内部的函数指针和为新分配重用已释放内存的内存分配器,这些类型的漏洞有可能会允许攻击者实施远程执行代码(RCE)。TOCTOU漏洞可能允许在enclave中使用不正确的参数,这也可能具有巨大的安全隐患。这可以从以下的样本中看出:

...
/*  1 */ static int g_index = 0;
/*  2 */ static int g_value = 0;
/*  3 */ static int g_array[256];
/*  4 */
/*  5 */ void ocall_set_index(int index) {
/*  6 */     g_index = g_index;
/*  7 */ }
/*  8 */
/*  9 */ void ocall_set_value(int value) {
/* 10 */     if (g_index < sizeof(g_array)) {
/* 11 */         g_array[g_index] = value;
/* 12 */     }
/* 13 */ }
...

可能看起来无法使用无效的g_index访问g_array,因为第一个线程可以执行ocall_set_value函数的第9行和第10行,然后被中断。然后,第二个线程可以执行ocall_set_index的第5到第7行,以在第一个线程检查之后更改g_index的值。这样第一个线程就可以被恢复,并且将使用第二个线程设置的g_index的值完成第11行执行的访问,这就可以导致Out Of Bounds(OOB)访问。

不过这类攻击需要完全控制平台,知道enclave内运行的代码,并在其中发现同步漏洞。防止这种攻击的最佳方法是在enclave内禁用多线程,但这显然会妨碍程序的性能。另一种解决方案是加密enclave的代码,并使用远程认证过程为enclave提供解密其代码所需的密钥。

用分支追踪办法(Branch Shadowing)推断SGX enclave内部的详细控制流程

我们把进行分支预测的硬件称为Branch Predictor,也称之为Branch Prediction Unit(BPU)。BPU的主要作用是预测接下来执行的指令分支,也就是说BPU作用于pipeline的前端(front-end)。

在CPU内部,BPU使用Branch Target Buffer(BTB)来记录对分支预测有用的信息。这导致需要大容量的Branch Target Buffer(BTB)来存储这些数据,不过实际上BTB的容量是有限的。虽然对分支预测有用的信息仅在处理器内部使用,但英特尔SGX在enclave模式切换期间不会清除其分支预测的历史记录信息。这就允许在enclave内获取(或不获取)的分支影响enclave外部的分支的预测。因为,我们就开发了一种被称为分支追踪办法(Branch Shadowing)的技术来推断正在运行的enclave控制流程。

分支追踪办法的原理就是在不受信任的环境中复制enclave程序的控制流程,然后仔细的选择映射此新代码的地址,以便在BTB内部引入冲突事件。首先在enclave代码内执行分支,然后在被跟踪的代码中执行分支,此时第二个分支的预测将受到第一个分支的结果的影响。要知道CPU预测的内容,最后一个分支记录( Last Branch Record,LBR)只能在不受信任的环境中使用,因为它对于enclave来说是禁用的。

为了使此攻击生效,必须尽可能频繁的中断enclave执行,以执行必要的安全检测,进而推断出enclave的控制流程。APIC定时器每隔50个周期就回去中断执行,如果需要更精确的数据,则禁用CPU缓存,这样APIC定时器每隔5个周期就回去中断执行。

以下就是在enclave内发生的条件分支的检测结果(绿色表示采用分支的情况,红色表示没有采用分支的情况):

8.png

1.如果执行enclave的条件分支指令( conditional branch instruction),则相应的信息就会存储在BTB内。由于这是在enclave内发生的,因此LBR不会报告此信息;

2.APIC计时器中断了enclave执行,并由操作系统获得控制权;

3.操作系统启用LBR并执行追踪代码;

4.如果占用了enclave中的分支,则BPU会精确地预测所占用的分支,即使目标地址无效,也可做到这一点,因为它位于enclave内。如果没有占用enclave中的分支,则BPU就无法会精确的预测所占用的分支。

5.通过禁用和检索LBR内容,操作系统可以通过检查被追踪的条件分支是否被正确预测来了解enclave分支是否被占用。

另外,我们提出的检测无条件分支和间接分支(目标地址无法通过攻击恢复)也大体是这个原理。此攻击需要完全控制平台,并了解在enclave内执行的代码。另外,它还引入了enclave可能能够检测到的显着运行减速(但它并不像执行RDTSC那么简单,因为在enclave内部不允许这样做)。

对SGX安全性的担忧

SGX用户担忧的第一个问题是,他们必须也不得不无条件地信任英特尔。值得注意的是,英特尔表示,它不会在每个CPU芯片的生产设备上重新设计 Root Provisioning Key。如果真像他们所说,则安全性将得不到保障。此外,由英特尔签名的enclave也获得了特殊的权限,比如被允许执行的Launch Enclave (LE)可以决定哪些enclave允许执行白名单。开发人员需要注册英特尔程序,才能签名发布版本的enclave。

第二个问题是,恶意软件可能会在enclave内执行其恶意代码,基本上没有任何约束。不过,enclave内的代码没有I/O,它完全依赖于其附带的访问网络、文件系统等应用程序等。因此,从技术上讲,分析应用程序可以告诉你关于enclave对系统影响的很多事情,减轻你的这个担忧。另一方面,缺乏可信I/O,也会导致用户信息保护乏力,不过因特尔并且已经在这个主题上下了一些功夫,设计了一个专有的解决方案,如受保护的音频视频路径(Protected Audio Video Path ,PAVP)和像SGXIO这样的方案。

第三个问题是关于Meltdown和Spectre对SGX enclave的影响。虽然不容易受到Meltdown的影响,但却很容易受到Spectre变体的影响,允许读取enclave内存和寄存器值。这使得平台的Seal Key能够恢复,进而导致认证密钥被恢复,这就有效地绕过了SGX提供的整体安全性措施。英特尔发布了代码更新补丁以防止这些攻击,并且根据安全版本号(SVN),用户还能够确保这些补丁是否已经被应用。2018年7月,加州大学河滨分校的研究人员发表了一篇论文,公布了命名为SpectreRSB的新Spectre漏洞。和已披露的其它Spectre漏洞类似,SpectreRSB利用了预测执行功能——这是所有现代CPU都包含的功能,通过提前计算操作和抛弃不需要的数据来改进性能。与其它Spectre漏洞不同的是,SpectreRSB利用了返回堆栈缓冲(Return Stack Buffer,RSB),能从预测执行中恢复数据。研究人员表示他们使用SpectreRSB恢复了其它进程的数据,甚至欺骗RSB泄露SGX的秘密。该攻击适用于英特尔、AMD和ARM的处理器。  

总结

虽然目前还有很多问题,但英特尔SGX是一项很有前景的技术,必定它才处于起步阶段。它满足了计算受信的安全需求,不仅允许enclave受到保护,免受平台上其他软件的攻击,而且还以特殊的方式避免运算性能的影响。它在执行安全保护的同时,给平台所有者一定程度的执行控制权限,以允许必要的资源管理。认证过程会以安全加密的形式发送到enclave,借助附加的SDK,开发支持SGX的应用程序就变得非常容易。

然而,目前的Intel SGX版本仍然存在一些问题。不幸的是,由于边信道攻击,使得平台的安全性受到了限制,这就迫使开发人员采用必要的措施,以确保他们的程序不能被攻击。而最理想的状态是,开发人员不需要担心这些攻击,SGX应该确保这些攻击是不可能发生的。因为,通过加密enclave的代码并通过远程认证认证密钥,就能防止这些攻击,但这个过程太麻烦了。

最后,我要说的是应该对Intel SGX抱有极大的信心。

源链接

Hacking more

...