再过不到12个小时,2024年欧洲杯就要拉开大幕了,不知道我们的读者中有多少球迷,又有多少人经历过21世纪以来一届又一届经典的欧洲杯(特别是2004年的希腊神话)。希望这个夏天,足球带来欢乐,世界能够和平。
虽然荷兰曾经是欧洲足坛劲旅,但是它现在也还是欧洲足坛的劲旅(语病之中透出了对荷兰足球人才凋零的无尽哀叹),我们今天要介绍的这篇论文也来自荷兰,研究人员通过发掘Replay Protected Memory Block(RPMB)的安全缺陷,成功地实现了对一些本来不允许普通用户随意覆盖重写的关键日志记录(比如手机密码登录失败次数的记录)的修改。
首先说一下RPMB,此RPMB并非RMB,不要想歪了,它是一种在闪存(不管是eMMC还是UFS或者NVMe上)常见的受保护的存储区域,这个区域没有什么保密性,大家都可以去读,但是要往里面写入内容就需要特定的权限,而实现这种访问控制的机制是要求对RPMB区域写入数据的同时,提供相关数据的HMAC,只有知道生成HMAC所需要的secret key,才能写入任意数据。RPMB的这个特性,比read only memory(ROM)更好用,不仅可以保存一些持久的数据,还可以更新。比如很多智能手机会用RPMB来存储一系列的anti-rollback counter,这些极计数器保存的都是很关键的记录,举个例子,现在的手机(不管是Android还是iOS)一般都不允许固件降级,那么系统就可以把固件的版本号保存在RPMB里面,然后每次升级固件的时候去检查一下此前保存的RPMB,如果使用了旧的固件,升级程序就会拒绝执行,而如果待更新的固件版本号更高,那么在升级完毕之后,就更新RPMB,把新的版本号写入进去(HMAC的key一般都会在特权级别中使用)。这样就实现了防止固件降级攻击。
可想而知,如果能够破坏RPMB这个机制,现在的大量系统的安全性很可能遭到非常严重的破坏,而现实世界中主流的破解攻击,一般都采用的是故障注入攻击这种技术手段,也就是人为去干扰硬件的运行,通过改变电压、制造毛刺(glitch)、引入电磁脉冲(electromagnetic pulse)等各种物理黑魔法,试图破坏RPMB的写入校验,让攻击者能够修改其中的数据内容。本文的技术主要采用了电磁脉冲故障注入(EMFI)这种手段,针对eMMC(embedded Multi-Media Card,但是目前手机哪怕是比较便宜的千元机好像也不怎么用这种比较“低端”的闪存了),作者实现了在不知道HMAC密钥的情况下,成功绕过了RPMB的写入authentication机制。
我们先看看作者这个攻击的一些前提,首先作者假定攻击的目标——eMMC是可以被攻击者完全控制的,也就是说,可以把它焊接到攻击者自己准备的PCB上(如下图所示),也可以完全操控eMMC控制器的核心电压(Vddi)和内存总线的核心电压(Vcc):
上面的图中最核心的设备是一个叫做ChipSHOUTER的组件(下图),这是一个加拿大公司开发的电磁脉冲故障注入设备,网页上标价是4125美刀,我们的读者可以赶紧去下单了(然后咸鱼上低价卖给我们)。
除了准备相关的故障注入实验设备,作者也汲取了一些前人的研究工作的智慧,其中提到了2017年的CCC大会上的工作eMMC hacking, or: how I fixed long-dead Galaxy S3 phones(https://media.ccc.de/v/34c3-8784-emmc_hacking_or_how_i_fixed_long-dead_galaxy_s3_phones 好像现在访问ccc.de也需要翻墙了),借助这项研究工作,作者掌握了一些私有的可以和eMMC进行通信的命令,然后可用一台JTAG设备(作者这里又带货了:https://z3x-team.com/products/easy-jtag-plus-activation/ Easy JTAG Plus)来提取eMMC的固件。基于这些知识,我们虽然在本文中看不到下表中的芯片(也是本文的实验对象)的厂商信息(应厂商要求),但是可以推测这应该是三星的eMMC产品。
实际上一块eMMC产品可以认为是一个独立的SoC,里面包含了一颗Cortex-M MCU,应该也是用这颗MCU来负责处理和外界的数据通信交互。在本文的攻击实验中,作者用一块树莓派来和eMMC进行I/O通信,同时用ChipSHOUTER同步引入干扰,作者还说,在实际分析中,想要观察相关的物理信号,只需要普通的4通路(four channel)示波器(带宽200MHz)就够了,比如PicoScope3000系列(我们淘宝查了一下,PicoScope3000系列也就4000-8000块钱左右)。
好,接下来就正式进入到实验环节,作者首先搞了一套自动化测试流程,把整个待测试芯片分成一平方毫米为单位的网格,让ChipSHOUTER在芯片表面移动,然后又利用了eMMC上的MCU的简单内存管理特性(没有启用内存页映射机制,直接按照默认的memory mapping方式管理,因此作者可以知道怎么写入代码到内存并令其执行),写入了一个如下所示的代码,可以观察ChipSHOUTER在任一特定位置上引入干扰的时候,eMMC这个系统的执行情况。
作者将引入干扰时eMMC的工作状态分为了normal、crash和glitch三种情况,而glitch(也就是MCU的执行受到了数据出错的影响,但是还没崩溃,代码可以继续执行)正是作者想要的状态。经过分析,作者找到了引入glitch的最佳位置:
作者还给实验对象进行了X光扫描,然后对比刚刚引入glitch的最佳位置,结果发现对于设备I和设备III,引入glitch的最佳位置就是controller所在的位置(如下图所示),但是设备III可能因为电磁屏蔽做得更好,即使对准controller,成功干扰eMMC的概率也低于10%,而设备I就能达到大约30%的干扰成功率。而对于设备II,最佳的干扰策略并不是对准controller的位置,而是去对键合引线(bonding wire,想要了解这个知识,可以看看海力士官网上的一篇科普文章 https://news.skhynix.com.cn/wire-bonding-a-way-to-stitch-chips-to-pcbs/ 对wire bonding的介绍)进行干扰。
对eMMC的MCU进行干扰只是绕过RPMB的必要条件,要想精确地让RPMB authentication过程失效,还需要更为深入地理解eMMC的运行,而正是对eMMC固件代码的深入分析,才揭示了后续攻击成功的关键:
作者通过逆向eMMC固件(通过内存dump,并且根据默认的memory mapping策略定位到相关区域),最后定位到了RPMB authentication的一段核心检查函数,如果你对软件逆向和破解有很好的sense,那应该立刻就看出来这个函数的脆弱之处——我们可以用好几种不同的修改方式来绕过检查:
让输入参数
length
变为0;让返回值(保存在
r0
寄存器)变为非0;让
rpmb_check_hmac
这个函数的执行直接略过(因为执行该函数前,r0
寄存器保存的是hmac
那个指针,肯定是非0);
实际上接下来要做的,就是去研究到底用EMFI能不能以上述三种方式之一对rpmb_check_hmac
这个过程进行破坏。这里有一个对攻击者很有利的条件——对RPMB的写入实际上是有标准的,在The JEDEC eMMC Electrical Standard中规定了如何写入RPMB:每次写入一个512字节的packet,里面包含了数据和HMAC,同时控制指令按照下图所示的顺序去通知eMMC,就能触发eMMC去执行对数据的HMAC校验(也就是调用rpmb_check_hmac
函数)。
既然能够搞清楚RPMB写入的工作机制,作者就可以用示波器去监控整个写入过程,然后定位到rpmb_check_hmac
可能的执行时间,最后就想办法去干扰eMMC的MCU在这一段时间的执行流程。
作者实验表明,在写入RPMB的packet之后大约110微秒之后,引入EMFI就可以干扰rpmb_check_hmac
(注意到EMFI的干扰持续周期为100微秒),不过这个攻击似乎对设备II无效(设备II是比较新的eMMC 5.1型号),只能成功攻击设备I和III:对设备I的攻击只需要在写入命令之后117.72到118.30微秒之间启动EMFI即可成功,而对于设备III,在写入命令之后112.30到112.50微秒后启动EMFI即可。由于RPMB写入操作之后,有一个寄存器会标记写入操作是否成功,作者通过读取这个寄存器确认了写入操作成功,然后也通过读取RPMB上的数据验证了破解效果。
最后作者还很细致地做了另一个验证工作:验证了在EMFI攻击过程中,除了RPMB之外,会不会意外地破坏eMMC存储的其他数据。通过把整个eMMC中的数据进行逐一比对,作者确认这个攻击只会改写RPMB,而没有产生什么副作用,太棒啦!
读完了这篇论文,感觉学到了很多东西,写作思路清晰,实验也做得很棒,虽然人家是WiSec论文,难道你敢说CCS论文就一定比它好?!
论文:https://dl.acm.org/doi/pdf/10.1145/3643833.3656114
代码:https://github.com/topig/RPMB_Glitching (又是一个骗子Repo,什么都没有,我们要自主可控!)