利用Spectre(幽灵)实现Meltdown攻击
Meltdown攻击通过利用Intel微处理器结构的设计缺陷,通过乱序执行时的计算痕迹建立信道,从而实现越界访问,进而攻击内核空间的地址。然而朴素的Meltdown攻击由于会频繁触发缺页错误,导致攻击程序提前退出,无法持续的对靶地址进行持续的访问。所以,常见的解决方式包括:
- 使用自定义的SEGV处理函数,接住系统抛出的异常,从而不退出攻击程序
- 利用Intel的TSX,建立事务同步扩展,在子线程里完成攻击,子线程退出后仍然不终止攻击
对这两种感兴趣的话可以看:
在这篇笔记中,主要介绍第三种处理异常退出攻击的方式:Spectre(幽灵)攻击。具体的说,通过处理器分支预测算法的设计缺陷,在错误的分支预测被系统发现之前的间隙,完成meltdown攻击。
分支预测
分支预测是Spectre攻击(准确的说是Spectre_v1
)的核心。简单来说,为了提升性能,系统不会等到分支条件语句的计算结果得出后,再开始执行之后的代码。相反的,处理器会预测一个(或多个)分支的可能结果,并且提前准备它们的执行。如果随后验证发现预测正确,那么就节省了等待的时间,反之,如果预测失败,那么处理器会消除之前运行的痕迹,并且从头执行正确的指令,相反降低了效率。虽然分支预测算法有利有弊,但是实际中,由于用户的代码中的分支结果其实很容易被预测,比如for循环10000次,只会在最后一次分支的时候跳出循环,所以简单预测“不跳出循环”即可获得99.99%的准确度。诸如此类。也正是因为分支预测带来的性能提升,处理器公司不会选择主动放弃它带来的市场优势,即便在知道算法背后的安全隐患。
那么如何利用分支预测攻击呢?以下代码为例,secret和addr分别是攻击者的目标信息和目标地址。直接对地址进行访问(*addr
)会触发系统警报,甚至可能直接退出程序,因为用户没有取得这个信息的权限。但是,如果我们对外层套一个分支的壳子作为伪