一、实验内容:
幽灵攻击于2017年发现,并于2018年1月公开披露,它利用关键漏洞进行攻击,存在于许多现代处理器中,包括Intel、AMD和ARM处理器。漏洞允许程序突破进程间和进程内的隔离,以便恶意程序可以读取来自无法访问区域的数据。硬件保护不允许这样的访问机制(用于进程间的隔离)或软件保护机制(用于进程内的隔离),但CPU设计中存在漏洞,可能会破坏保护。因为缺陷存在于硬件中,很难从根本上解决问题,除非更换CPU。幽灵和熔断漏洞代表了CPU设计中的一种特殊类型的漏洞,它们还为安全教育提供了宝贵的一课。
本实验的学习目标是让学生获得幽灵攻击的第一手经验。攻击本身非常复杂,因此我们将其分解为几个小步骤,每个步骤都是易于理解和执行。一旦学生理解了每一步,就不难理解了把所有的东西放在一起进行实际的攻击。本实验涵盖了以下内容:
•幽灵攻击
•侧通道攻击
•CPU缓存
•CPU微体系结构内的无序执行和分支预测
二、实验步骤与结果
Tasks 1 and 2: Side Channel Attacks via CPU Caches
Task 1: Reading from Cache versus from Memory
编译并运行程序。
运行十次之后,观察到,主存的访问大致在500次CPU时间以上,缓存的访问时间大致在300个CPU时间以内。所以我们为了确定读取的是缓存,将阈值设置位300。
Task 2: Using Cache as a Side Channel
编译并且运行代码。
Task 3: Out-of-Order Execution and Branch Prediction
编译并运行代码:
注释掉标星的代码:
再次编译执行,执行的结果如下:
可以看到,代码没有执行预测分支,这是因为缓存中的size数据没有被清除,导致程序直接访问缓存非常迅速,没有执行分支预测的时间。
取消掉注释,将训练的代码修改为如下代码。
再次编译执行,结果如下:
可以看到,程序也没有成功执行分支预测,这是因为将传入的值修改为20-29之后,分支语句多次执行false,导致训练的结果是CPU会预测执行false语句,所以没有执行我们想要的分支。
Task 4: The Spectre Attack
编译并运行代码,结果如下:
将参数0-9传入函数中,训练CPU执行true分支,然后清除缓存,使用和task3相同的方法,访问到了不能访问的部分。此处我们访问到了S的值(83)。
Task 5: Improve the Attack Accuracy
运行代码,结果如下:
发现结果错误,这是因为当分支返回判断语句返回false时会返回0值,这个值被当成读取的secret的值,所以会造成结果错误。
将代码做如下修改:
再次执行代码,可以看到结果正确。
注释掉下面这一行代码,执行代码,可以看到攻击失败。
尝试修改usleep()的值为,100,1000,10000,可以看到,hit的值开始降低,因为时间变长之后,判断语句可能已经返回结果,不需要进行分支预测。
Task 6: Steal the Entire Secret String
进行17次幽灵攻击,每次窃取不同的值,并保存在字符数组中,即可得到所有的secret内容。
修改代码如下:
运行代码,成功输出了secret字符串的值。