MSR利用
摘要
在给cpu添加新特性时,cpu制造商引入一个受限的cpu配置手段(model-specific registers---MSR)来保证处理器的后向兼容。MSR种类繁多,提供很多特性,比如调试、性能监控和一些安全保障。目前来看,许多MSR被document了,但是仍然存在大量的MSR没有被document,或者document的不完全(指该MSR寄存器的某些bit没有被document)。因此,在数以百计的MSR(每个提供多达64比特的配置选项)中,寻找特定的配置项是乏味的。
我们的研究表明:
- Intel和AMD处理器上,可以自动检测某个MSR和对应的配置比特。我们引入了一个能够检测特殊比特的框架---MSRevelio,它能够自动检测影响指令行为的特殊比特,半自动检测BIOS设置中修改的特殊比特。
- 一些之前忽视的比特位,可以用来防御部分微架构攻击,比如Medusa, CrossTalk和软件预读取攻击
- 一个特定的undocumented比特位,能够在运行时关闭AES-NI,强制mbedTLS的AES部分“回退”到一个容易遭受缓存攻击的版本。在一个SGX enclave中利用这个“回退”,我们完整恢复了enclave使用AES密钥。
- 在对潜在漏洞进行公开陈述前,我们可以提前检测到用microcode更新的安全措施。
- Xen对MSR的处理存在缺陷,游客能够访问undocumented和unhandled的MSRs,and fingerprint specific Xen versions。
- Xen游客能够访问的一个undocumented的比特位,与CPU的时间戳计数器相关。基于此,我们实现了一种Foreshadow攻击。因此,对于那些和CPU经常交互的特性,透明度是很重要的。
1. Intro
前三段,对MSR的用途、基于MSR的攻击、基于MSR的Mitigation的相关工作进行了介绍。
第四段,介绍一个自动化的检测工具---MSRevelio,检测MSRs,对其分类为documented, partly documented, undocumented三类,分析检测到的undocumented的MSR,使用概率分析来寻找undocumented MSR和documented MSR之间的相关性。
第五段,介绍基于 MSRevelio来半自动化检测不同的BIOS版本中,受到BIOS设置影响的MSR。并且给出了6个相关的安全case studies。
第六段,介绍MSR影响指令行为,可以用来mitigate一些攻击,也会造成一些安全问题。
第七段,针对不同的CPU microcode版本,作者发现可以提前检测到不同版本间的区别,知道厂商部署了什么安全措施。在漏洞和补丁,公开之前。
第八段,Xen使用一个block list来避免游客访问部分MSR,允许其访问剩余的所有MSR(已知的+未知的)。这造成两个问题,根据block list,攻击者可以迅速得到Xen的版本号,而且旧版本由于没有禁用新版本增加的MSR,游客使用旧版本的Xen可以潜在地访问host系统的那些安全相关的MSR。
第九段,MSR会直接影响到系统的安全性。如果用户能够修改某些MSR,那么他们很有可能可以使得一些mitigation失效。当然,使用MSR,也可以对一些软件层面的漏洞进行防御,比如prefetch-based攻击。我们建议对于那些处理器漏洞,应该用配置MSR来作为短期方案,之后在硬件层面进行解决。
第十段,就是说一下作者的贡献,主要都是摘要里面的“研究表明”部分。
2. Background
A. Model Specific Register(MSR)
MSR寄存器的地址为32位,大小为64位,使用两个特权指令rdmsr
和wrmsr
来读取和写入。
Hypervisor(虚拟化技术)通过限制可访问的MSR,避免guest系统控制host系统。
B. Intel SGX
Intel SGX是一个用来提供Intel CPU上的可信执行环境的指令集扩展,假定OS、管理员和特权软件都有可能被欺骗,执行恶意代码。所以,它把所有受信任的代码存储在一个特定的区域---enclave。enclave的程序运行在一个加密、被隔离的区域,从而OS和物理攻击这也没办法访问其内容。Intel认为,enclave出现漏洞,一定是因为enclave开发者本身的问题。或者是类似于条件竞争的软件bug。常规应用程序可以调用enclave,OS能够在任意时间点中断enclave。
C. Micro-op Performance Profiling
乱序执行的引入增加了CPU的复杂性,传统方法难以分析正在执行代码的实际行为,CPU厂商引入一些 Performance Monitor Counters(PMCs),用于更精确地检测代码的执行过程,但是因为CPU还会把指令分解为微操作,所以PMC观测到的事件和指令难以进行对应。
NanoBench,可以解决上述问题,寻找到某个指令实际对应的PMCs。它能够减少外部影响(噪音),对指定的代码片段进行compile处理,并且使用一个已知的state来填满 CPU pipeline,为所有的测试过程提供相同的测试环境。也就是说,可以使用这个工具得到某条指令的实际行为。
D. Transient-execution Attacks
乱序执行和推测执行使得CPU会经历瞬态执行的一个阶段,收集微结构层次的痕迹,就可以泄露秘密信息。
E. Microcode
用于CPU的安全机制更新,是一个抽象层,位于实际的物理硬件和 Instruction Set Architecture之间。
3. MSRevelio
该机制的目的是找到影响系统安全性的undocumented MSR的比特位。
大致的工作流程为,扫描可能的MSR的地址空间(整个32bit的地址空间,两个十六进制数来表示),然后进行不断分类。
- read-only, write-only, read-writable
- 就是用rdmsr, wrmsr尝试读和写,看看会不会引发GPF中断错误
- documented, undocumented, partly documented
- 下载官方的document(PDF),开发一个PDF解析器,将检测到的MSR和官方文档的MSR进行自动对比
- Dynamic, static
- Dynamic。进行cpu压力测试,观察undocument MSR bits和documented bits的相关性
- static。通常为配置项,在相同环境下,反复执行某一个片段,修改其值,观察区别。
然后,修改BIOS的某一项配置,观察MSR的变化
A. Detecting Undocumented MSRs
该阶段对完整的32bit的地址空间进行扫描,完成前两项分类工作。
关于:GPF
一般保护错误,是一种错误或者说是,因为错误而被引发的中断。如果程序(用户程序或内核程序)违反了处理器的保护措施,会引发这个中断。一次的话,会关闭进程,告知用户;如果处理GPF过程中,引发二次GPF,会蓝屏;如果三次,会自动关闭处理器。
关于:SMM 模式
SMM mode,系统管理模式。它是intel引进的,对OS透明,操作系统完全不了解处理器什么时候进入了SMM mode,甚至不清楚处理器曾经进入过SMM mode。intel在CPU上增加一个管脚,其为高电平时,CPU进入PMM模式,屏蔽一切中断,只能在系统管理内存(SMRAM)执行SMM程序(只能由BIOS等硬件实现),只能通过执行RSM指令推出SMM模式。
在具体实现上,有一些需要注意的细节,作者在这一部分进行了列举。
MSRevelio is implemented as a Linux kernel module with an additional user-space library. It uses the rdmsrl_safe and wrmsrl_safe kernel functions to catch GP faults when reading and writing MSRs.
B. Classifying MSRs
见A.设计的第三步
该阶段完成第三项工作、第四项工作的前半部分:
- 上面提到的分类工作的最后一项。dynamic, static
- dynamic, 随着CPU,基本上一直在变。比如计数器、传感器的值
- static, 基本上没什么变化,比如一些配置选项
- 针对undocumented dynamic MSR bits,分析 undocumented MSR bit和documented MSR bit 之间的相关性
- 执行一个CPU的压力测试,记录这些MSR的归一化后的值
- the Spearman and the Pearson coefficient来分析相关性
项目地址,在实现的时候,clone下该仓库以后,进行以下三步:
- Building the tools
- 主要在 ./msr_scanner目录下
- 用管理员权限加载到kernel一个模块,具体来说,就是在./msr_scanner/modules 目录下,make一下,将生成的 msrs.ko 插入到 kernel modules 中
.ko
(kernel object),比.o
多了个kernel,可以加载到内核中的驱动模块
- ./msr_scanner/tools 目录下,make一下,得到三个可执行文件
- msrs_detect - this can be used to trigger a scan
- msrs_ls - prints all found MSRs
- msrs_sample - can be used to sample MSR values
- Run MSR detection
- 主要在 ./msr_scanner/tools/build/bin/ 目录下,运行一下 msrs_detect开始扫描,扫描结束后,使用msrs_ls将扫描结果存储在一个msrs.log文件内。
- Analyze MSR list
- 主要在 ./scripts/sampling 目录下。
- 运行一个sample_all.sh(调用上面生成的msrs_sample工具)
- 运行一个msrs_analyze.py,看看哪些MSR是随时间变化的。 绘图,寻找dynamic MSR之间的相关性。
C. Impact on Instruction Behavior
该阶段完成第四项工作的后半部分,研究undocumented MSR bits对指令行为的影响(相同测试环境内,运行 a set of instructions),对undocumented static MSRs进行处理,因为波动的MSR bits一般不会成为 feature-control bits,配置选项。
但是,存在一个问题,就是我们如何确定,造成指令行为变化的MSR bits,是某一个MSR中单个反转了的bit,还是某个MSR中部分bits共同组成了一个配置选项。
MSR寄存器的地址为32位,大小为64位
一般的方法是,针对每个MSR中可写的bits,迭代地反转每一个比特,毫无疑问,这样做,得出来的结果更加全面,但是工作量很爆炸。
因此,作者提出 optimized flipping masks(反转掩码,64比特长度,做异或进行反转)。他只考虑长度不大于 W 的比特组(可能的配置选项),采用2W次的写入,遍历一遍,看看PMC的变化。当然,这样得出的结果是不全面的,但是具有更高的效率。
具体原因有两个:一个是工作量;另一个是作者假设,这些配置选项之间不存在相互影响。
It is not beneficial to have one bit for enabling a feature and another for disabling it again.
实现: MSRevelio是基于nanoBench的,前文提到过,它对代码片段进行compile,杜绝外部影响,在构造的相同的测试环境中多次重复compile后的代码片段。
面对庞大的搜索空间,nanoBench需要调用的次数是极为频繁的,所以,MSRevelio基于 undocumented bits的行为,对其进行了三个阶段的预筛选。
- Phase 1: Detecting Writable Bits.
- 对所有undocumented MSR bits,尝试读出值,然后将反转后的值写入,再尝试读出值,看看反转是否成功。将结果记录下来
- 因为MSR bits的修改经常会造成系统故障,还要记录出一个blocklist of such MSRs。
- 该过程可以使用一个远程控制的power switch实现自动化(引用文献24)
- Phase 2: Initial Recording of the Changed States.
- 使用相同的 instruction groups ,测试长度不大于4比特的所有可能区域造成的影响。
- 假设:多个undocumented enum MSR fields对指令行为的影响是相互独立的。所以,该阶段作者没有控制变量,每次只测试一个enum MSR field,而是对一个MSR的所有可能enum MSR fields同时测试。
- 所以,才会有 i5-4570 中,177个MSR中共3612个undocumented writable bits,第一次测试,逐个MSR进行16次测试,也就是 177 x 16 = 2832次
- 找到特定的那个MSR之后,64个bit的空间,对于所有可能的enum MSR field,因为上一步已经测试了一部分(也就是从头到尾恰好16组),剩下的组不交叉的部分也可以同时测试。关于需要进行31 x 16 次数,这里有一个疑问。
- Phase 3: Finding the Origin of the Effects.
- Phase 2后会得到一个对指令行为有明显影响的MSR的候选列表。
- 本阶段,针对候选项中的每一个MSR,顺序测试所有bit,从而将PMC观察到的影响和特定的enum字段进行对应。

项目中相对应的介绍,
D. Results
我们在总共5个CPU上对未记录的MSR进行了彻底搜索。这些CPU的总体结果如表1所示。
我们在AMD和Intel CPU上发现了5890个未记录的MSR,其中大多数发现的MSR(4876)位于AMD CPU上。
然而,在AMD上发现的静态、可读可写、未记录的MSR中,96.8%在写入时不会引发GP错误,而是忽略写入值,从而限制了进一步的位行为分析。
我们也观察到54.1%的英特尔MSR有类似的行为。
我们分析了所有这些未记录的MSR与记录的MSRs的相关性。我们发现53个未记录的MSR暴露了与现有MSR相关的持续变化的值。例如,动态MSR(0x637)公开了一个与记录的计数器相关的单调计数器,我们在第V-F节中进一步探讨了这个计数器。
对于静态MSR,我们进行了enum字段搜索,以查找影响特定指令的位。我们发现1个未记录的位和6个部分记录的位影响cpuid和预取等指令。第五节分析了这些MSR位的影响。为了确定MSR的具体功能,需要手动分析。
4. Detecting OS-configurable BIOS features
本章节研究BIOS的设置会造成哪些 static MSRs发生变化。BIOS主要用于在boot时配置一些CPU的选项,比如采用哪些features,电源管理相关的。一些CPU的配置只能由BIOS在boot时设置,另一些选项能够由操作系统修改。许多BIOS版本仅向用户公开一小部分设置。MSLevelio模板化BIOS版本,以提示用户如何从操作系统重新启用解锁功能。此外,它还可用于分析未记录或描述不佳的BIOS功能是否会影响MSR。
A. BIOS Templating
提前准备一个 MSR列表和BIOS设置表,记录static MSR的初始值,尝试修改某一个 BIOS设置,观察这些 static MSR的值是否发生了变化。反复多次。
这里的static MSR bits包括 documented 和 undocumented。
B. Setup
评估了 5 个CPU,结果是发现了一些没有被官方文档记录的BIOS设置选项。
实现时,将所有BIOS设置为默认值,然后使用 MSRevelio来测试它是否可读、可写,然后更改特定设置,观察MSR的前后差异。
C. Results
1)Documented Settings
一些发现,比如其中一个MSR bit可以支持 fast-support string,从而防御 Medusa
2)Unofficial or Undocumented Settings
还有一个 0x7a 的MSR,有一个 bit 可以开启 Intel SGX。0x13c的MSR有一个bit可以用来关闭AES-NI
5. Case studies
本节介绍六个case,证明先前忽略的MSR位的安全影响。
显而易见,该文章尚未完成,哈哈,不好意思。