[BL&EDL] 论刷机授权验证如何保障数据安全

前言

线刷需要“解锁”,稍有些经验的机友大概都听过这句话。

但疑问也随之而来:

虽然 BL 锁的存在保证了 FASTBOOT 下无法刷机,那么是否有办法绕过 BL 锁?

进一步地,还有什么手段防止刷机?

预备

在回答问题之前,我们先补充一点点知识。

我们常说的 FASTBOOT 在手机上是作为 Extensible Bootloader (XBL) 存在,但是,基于高通处理器的机型都有一个 Emergency Download Mode (EDL),即我们常说的 9008 模式。

该模式下,Primary Bootloader (PBL) 可以接管设备控制权,允许通过 Qualcomm Sahara 协议加载一个 ELF 文件,作为第二阶段引导加载程序(Secondary Bootloader)(SBL),从而实现对存储的刷写。该模式存在的初衷为了防止 SBL 损坏而设计的应急措施。注: XBL 可以看做是 SBL 的一个子集

我们知道,BL 锁,“锁”住的是 XBL。如果我们能想办法加载自己的 XBL,问题不就解决了吗?

分析

在早期,确实如此,我们可以通过 EDL 模式绕开 BL 锁,实现刷机。

这也就引出了我们的第二个问题——“还有什么手段防止刷机?”

AlpheSecurity & Qualcomm

2017 年,AlephSecurity 团队正式向高通方面报告了这样的一个漏洞(QPSIIR-909),指出了某些情况下,PBL 可以被利用,进而实现在设备上执行任意代码。

作为修复,高通方面则引入了安全启动 (Secure Boot) 以及 防回滚机制(Anti-Rollback)。

上述的机制通过一系列验证手段,来避免未签名的恶意程序被 PBL 加载。同时防回滚也确保了 SBL / ABOOT / TZ 等不会被降级至有漏洞的旧版本,从硬件层面堵上了恶意注入的漏洞。

安全启动主要通过密钥链对加载进设备的代码进行可信度验证,同时决定是否接收这些代码。为了优化存储空间以及处于拓展性的考虑,高通并未对整个 ELF 加密,而是将一些签名信息写入到 Hash Table Segment 之中

总体验证流程如下图。为了防止验证的某一过程被修改,下图的 Root CA Hash & Cert 被写死在硬件之中。

各层证书联系紧密, Attestation Cert 的签名由 Attestation CA Cert 的私钥生成,而 Attestation CA Cert 的签名由 Root CA Cert 的私钥生成,最终 Attestation Cert 对代码进行签名。

所有证书公钥及其签名都被刷写到手机,在加载代码时,会逐层用公钥对签名进行验证,一旦验证不通过,将会触发:“有内鬼!停止交易”(终止并报错)。

私钥则由高通公司及手机厂商严格保密保存,若是无法取得私钥,就无法生成各级证书签名,无法对代码签名,导致验证不通过。

Miflash & ELF file

时至今日,这套保护机制已经很完善了,我们结合具体情况来看看。

如果有小伙伴进入 EDL 模式进行刷机,若是用新版 Miflash 工具,则会提示需要登陆账号验证权限,若是有权限,刷机可以继续;若是无权限,则刷机终止。若是使用 20180528 之前旧版本的 Miflash,将会收到一条 miflash ERROR: Only nop and sig tag can be recevied before authentication. 这样的信息,从而无法继续刷机。

该信息从何而来?

在 EDL 模式下,Miflash 会调用高通提供的 QSaharaServer 程序将 prog_firehose_ddr.elf 刷写到手机作为 SBL。之后再通过 fh_loader 刷写镜像。正是因为 prog_firehose_ddr.elf 没有收到授权验证,拒绝了后续的刷机请求。

使用 IDA 逆向 prog_firehose_ddr.elf 即可相关看到相关逻辑。

View 中打开 Strings 视图,搜索字符串 Only

双击后按下 X 查看交叉引用,定位到函数 sub_14824FC4

双击跟进,即可看到验证逻辑,图中仅仅截取了一部分。小伙伴们从左下角的 Overview 窗口不难看出,实际上这套验证逻辑很复杂。

图中上面一个橙色框标识的就是 ELF 文件中引入的授权验证之一。由于我们并没有刷机权限,在标识处验证不通过,程序向 Miflash 回报了 Only nop and sig tag can be recevied before authentication 这样的错误信息,大致意思是,“在完成验证之前,只有签名信息和 nop 指令可以被接收(其他代码拒绝接收)”。

有的小伙伴也许会说,那么我们修改掉 ELF 中的判断逻辑不就可以了吗?

这并不可行。正如前文所述,所有引入设备的代码都需要经过签名验证。如果我们修改了这个 ELF 文件,由于我们无法获取签名所需的私钥,就无法生成正确的签名,会导致签名校验失败,刷机进程终止(上图中下面一个橙色框)。

用 16 进制文件编辑工具(或者记事本)打开 ELF 文件,就可以看到一些证书相关字段。例如 Xiaomi Attestation CA0XBL Sec Attestation Root CA

因此,无法通过逆向工程方法破解 ELF,来达到绕过授权验证的目的。

经过授权的刷机流程

结合个人经验,推断经授权的刷机流程如下:

  1. prog_firehose_ddr.elf 被加载到手机
  2. 代码执行到“要求进行签名验证”处(可能是小米加入的),向 Miflash 回报特定错误代码,新版 Miflash 将要求登录账号。
  3. 登录后,若服务器端判定“有刷机权限”,则在云端计算生成部分数据(推测是用私钥生成某阶段的 Signature)发回 Miflash.
  4. Miflash 使用这些数据作为参数,传递给手机,使得验证通过,之后可以正常加载刷机代码,接收文件。

小结

综上所述,进行验证的大致流程如下图所示。

验证流程

再整理一下思路:

  • 刷机需要解锁 BL,这需要账号与设备绑定以及云端验证。同时每台设备的解锁 Token 与硬件绑定,通过服务器运算得出。
  • 若想绕过 BL 锁,需要进入 EDL。而 EDL 的进入有一定难度(目前 EDL 几乎只能通过“拆机短接”进入。)
  • 即便进入了 EDL,在没有授权信息的情况下,ELF 镜像无法加载执行,无法刷机。授权信息也是在云端生成。
  • 虽然 “磁盘模式” 也可以刷机,但常规情况下需要执行 fastboot erase aboot & fastboot reboot 指令进入(而执行该指令需要解锁)。

正是在如此层层保护之下,才使得一个小小 “BL锁” 能够有效地 “锁住” 我们的安全。

利与弊

凡事总有两面性。不可否认,这些机制的引入,一方面极大地保护了我们的安全,但在另一方面,这也毫无疑问地提高了自行刷机(救砖)的门槛。

回想初次认识的小米手机,是某代号为 cancro 的 “板砖”,在那几年正是玩机乐趣的巅峰。

现在手里拿着新机型,一边感慨着 “9008”“磁盘模式” 的狂热褪去,“刷不死”“为发烧而生” 的时代落下华章;一边又赞叹着层层精妙严谨的设计,为崭新的信息时代构筑了安全后盾。

不管这么说,“限制权限、注重安全”总是发展的大方向,“世间安得两全法,不负如来不负卿”。

END

个人经验毕竟有限,若有错误还请各位不吝斧正。

文本原创首发于 小米社区 & 个人 Blog,转载请注明。