安全研究人员发现在英特尔PC上的Linux系统中可以利用某些种类的DDR DRAM芯片所存在的物理缺陷来获取系统最高权限。
该技术被称为“Rowhammer”,其可使最近一代的 DRAM 芯片多次访问内存导致相邻行发生“位翻转”,并允许任何人改变计算机内存中的存储内容。
什么是Rowhammer?
DDR存储器对数据进行行和列的数组排列,然后分配给各种服务器、应用程序以及大规模的操作系统。为了防止应用程序之间相互访问内存,通过“沙箱”将他们进行隔离。
但“沙箱”可以通过一些恶意软件对存储的第二部分中需要多次进行访问相邻行的内容使用比特翻转技术来绕过。因此,攻击两个相邻的内存区域很可能会导致电荷泄露或对其他部分造成干扰。
研究人员解释道:
“有足够的访问量就可以进行0到1或者1到0的改变,换句话说选择的zero区域很有可能转移给受害者”
位翻转技术首次出现是在卡内基梅隆大学发表的一篇学术研究报告中,该报告名为
《Flipping Bits in Memory Without Accessing Them: An Experimental Study of DRAM Disturbance Errors》
另外,位翻转技术不应该与缓冲区溢出以及use-after-free内存崩溃技术混淆。use-after-free内存崩溃技术是一种攻击者把恶意shellcode植入受害者电脑保护区域的技术。
原理解析
正如我们所知,DRAM芯片的生产规模会随着物理尺寸的减小而减小,而最新的技术对于内存容量的要求更高,使得芯片单元间的电子干扰很难被阻止。
目前Google Project Zero的研究人员 Mark Seaborn和Thomas Dullien已经成功的在x86-64的GNU/Linux平台上利用这个漏洞通过CLFLUSH指令和PTEs(page table entries)的某一位的变化(比如0到1)直接获得内核权限,研究人员认为在其他的硬件架构和操作系统上也有类似的方法可以达到这一目的,解决这个漏洞的修复可能需要BIOS更新针对内存控制器部分的操作。
在Yoongu Kim et al的论文中谈到了关键的原理:
code1a:
mov (X), %eax // Read from address X mov (Y), %ebx // Read from address Y clflush (X) // Flush cache for address X clflush (Y) // Flush cache for address Y jmp code1a
两个因素导致位的变化
1、地址选择:地址X和地址Y必须印射到内存的不同row但是又是在同一bank上。
每个DRAM芯片包含了很多行(row)的单元。访问一个byte在内存中涉及到将数据从row传输到芯片的"row buffer"中(放电操作),当读取或者写入row buffer的内容后,再把row buffer内容传输到原来的row单元里(充电操作)。这种”激活“一个row的操作(放电和充电)可以干扰到临近的row。如果这样做足够多的次数,临近row的自动刷新操作(一般是每64ms)可能会让临近row的位产生变化。row buffer作为缓存,如果地址X和Y指向相同的row,那code1a将会从row buffer中读取信息而不用任何”激活“操作。
每个DRAM的bank都有自己的"当前已激活的row",所以如果地址X和地址Y指向不同的bank,code1a将会从那些bank的row buffer中读取信息而不用反复的激活row。所以,如果地址X和地址Y指向同一bank上不同的row,code1a会导致X和Y不断的被激活,这被称为ROWHAMMERING。
2、绕过缓存:没有了code1a中的CLFLUSH指令的话,内存读操作(mov)只会操作CPU的缓存。CLFLUSH刷新缓存的操作强制让内存的访问直接指向DRAM,而这会导致不断有row被重复的激活。