root和BL锁有啥关系?
作者:卡卷网发布时间:2024-12-02 18:53浏览数量:97次评论数量:0次
我尝试用浅显的语言讲透 root 越狱、BL锁、ID锁、安全启动这些刷机原理,让你快速建立刷机相关的系统知识框架,轻松加入玩机大军,让你家长出更多旧手机、盒子和路由器。
如果你对手机安全感兴趣,你一定会喜欢下面这篇技术小说,它讲述了一个黑客如何步步为营盗走老板巨额资产的故事,读完你将对 root、BL 锁和 TEE 可信执行环境有更深刻的认识。
指纹识别/指纹支付安全吗?让我们先从 root 开始吧!
系统安全:控住 root 权限
所谓 root ,就是 root 权限(用户或组/角色),是 Linux 系统的最高权限,类似 Windows 的系统管理员。
在 Linux (其实 Windows 也类似)中,所有设备资源(如文件、设备等)都分用户、组(角色)进行管控,一般用户只能掌控自己的资源(增删改查),这意味着你不能修改或删除别人的文件,甚至你都看不到别人的文件(取决于别人是怎么设置权限属性的);当然你也不能终结别人的应用进程,除非你拥有相应的权限(管理员专门给你设置了操作该进程的权限)。但系统中有一个特殊的用户/角色,它能突破这些限制,访问所有文件,操控所有资源,它就是 root,通常系统程序就是以 root 用户运行的,以实现上帝般的管控权力。
在现代操作系统中(不管是Windows还是Linux),每个应用软件都是以某一用户的身份启动的,软件启动后,这个软件的进程就打上了该用户的标签。例如,当你输入用户名(Ayden)登录系统进入桌面后,这个桌面(当然也是一个进程)就打上你的标签,你在这个桌面运行的文件管理软件,也同样会继承 Ayden 的权限设置,如果在文件树中有一个别人创建的文件(假设设置了其他人不让改但让看),你运行的标记为 Ayden 的文件管理软件自然修改不了这个文件,操作系统会保证这一点。
也许你会疑惑,我的电脑/手机,就我一个用户,根本没其它用户啊,操作系统为什么还要搞这么复杂?答案是,为了保障你的信息安全,操作系统还搞了一个超级管理员帐号(root)和许多特定应用程序专用的用户,并不是只有你一个用户。很多系统相关的软件,比如设备驱动、系统文件、服务进程等,就是以 root 帐号运行的,只有 root 用户(或拥有 root 角色的普通用户)才能操作它们。
现在的设备几乎时刻联网,假如你一不小心多点了几个,就可能启动了某个恶意网页脚本或流氓软件,因为你是以普通用户登录的,这些恶意软件最多也就拥有与你一样的权限,能干的事情终究有限。但假如你是以 root 登录的,这些恶意软件也会继承 root 权限,那它可做的事情就多了,比如它可以作为系统后台服务进程,一直监控你的键盘输入窃取密码,或者远程偷偷开启你的摄像头和麦克风。当然,为了方便使用者,普通用户登录时,还是可以通过 sudo 临时提权或 su 临时切换到 root 用户运行某一程序的,这需要输入用户或root用户的密码,恶意软件想获得 root 权限也没那么简单。
Windows 比较奇葩,创建的帐号默认就是管理员角色(相当于 Linux 的 root),大家正常使用电脑都是以管理员的身份登录的,这给Windows带来了巨大的安全隐患。为了防止恶意程序肆意破坏,微软不得不搞出一个 UAC(用户帐户控制)机制,当某个应用程序尝试做些系统级别的操作时,需要先提升(管理员)权限,这时 UAC 会弹出一个窗口通知用户,如下图,让用户有机会批准或拒绝。UAC 机制相当于 Linux 中的 sudo 提权。
然后你会问,我都不用 Linux,我甚至不用电脑,这些跟我有什么关系?
当然有关系,你只是不知道而已。安卓系统本身是基于 Linux 的,所有你运行的安卓应用软件,在底层操作系统层面,都是一个个 Linux 的进程,受 Linux 权限系统管控。苹果的 iOS 在原理上也是类型的,底层系统 MacOS 就是 UNIX 的分支,而 Linux 也是一个类 UNIX 系统。
不管是苹果和还是安卓,手机厂商为了保障用户的信息安全,只给你普通用户的权限,不会给你 root 帐号(直接禁止root登录)。所以,当你输入口令(人脸识别本质上也是口令)进入桌面后,你是以普通用户的身份登入的,你的所有操作,包括安装 app、拍照、打电话、浏览网页、刷知乎刷抖音等,都是操作系统开放给普通用户的权限。恶意软件想安装一个全局的后台服务程序监听你的一举一动,或者想拦截所有 app 的消息,门都没有,因为它没有 root 权限,既改不了操作系统的底层配置文件,也不能替换现有的系统文件伪装成无害的良家妇女——它动不了操作系统层面的任何资源!
越狱:突破系统限制
对于大多数用户来说,手机厂商不开放 root 用户的做法绝对是明智之举。手机不像电脑这样的生产力工具,不需要 root 完全可以很好的工作。
但对于(少数)技术狂热份子来说,不开放 root 就意味着动不了操作系统层面的任何东西,意味着不灵活、不方便。虽然安全,但也像一座监狱一样,囚禁了极客们无处安放的技术点子。他们希望对操作系统进行必要的改造,实现一些对自己无害有益的功能,比如接管安卓的后台管理彻底扼杀那些不良软件的悄悄启动(黑阈/冰箱)、清除系统预装(但用不上)的app以释放更多空间、拦截微信消息防止消息撤回、移除手机和软件的广告、解除某些app的区域限制等等。
但手机厂商绝不愿为这么一小波极客开一道口子,而给庞大的普通用户群带来潜在的威胁,所以厂商们是坚决不开放 root 权限的!
但是,操作系统上的所有文件,都明明白白地存储在 Flash 的文件系统中,任何对 FS 稍有了解的人,都可以修改任何一个文件。手机厂商根本没办法阻止极客们修改手机上的系统文件,进而以 root 权限运行极客们的程序!
虽然厂商们阻止不了用户修改系统文件,但可以检测文件系统的异常状态,从而加于限制,比如安卓系统可以通过 SecureLock 安全锁定、SafetyNet 等机制,来限制已 root 系统的正常运行,迫使用户放弃 root。
道高一尽,魔高一丈。新一代越狱工具 Magisk 采用了更加隐蔽的方式,通过挂载独立的文件系统(避免直接修改 System 分区)及其它一些伪装措施,来欺骗 Android 系统的 root 检测,实现更为隐蔽的越狱。
那具体怎么样获取 root 权限呢?
root 核心原理
在常规的 Linux 中,普通用户提升 root 权限有两种方式: su 和 sudo 。sudo 是临时提权,用户本身需要先授权 sudo 权限才能操作。su 的方式更为简单,就是切换用户的意思,如果不指定目标用户,默认就是切换到 root 用户 —— 当然需要用户输入 root 的密码才能成功切换。
如果我们对 su (开源)进行修改,去掉输入密码的过程,那么,普通用户环境下(不管是 shell 还是桌面),只要启动一个进程运行 su,这个进程就会自动切换为 root 权限,以后由该进程启动的任何应用(包括安卓应用),就都拥有了 root 权限,就能做一些系统级别的事情,无论是干坏事还是干好事,目的不同而已,方式都一样。
为什么一个进程运行 su 后,就能更改执行的用户了呢?如果我们在 Linux 查看 su 和 sudo 这两个程序文件的权限设置,会发现 “执行权限” 标识中出现了 s,而非常规的 x (有执行权限)或 - (无执行权限),如下图:
-rwxr-xr-x. 1 root root 41504 Nov 17 2020 md5sum
-rwsr-xr-x. 1 root root 32128 Feb 3 2021 su
---s--x--x. 1 root root 151424 Oct 14 2021 sudo
执行权限为 s 的意思是,任何一个用户如果执行了这个文件,都会拥有与该文件所有者同样的权限。因为 su 的所有者就是 root ,所以不管是谁执行了 su,都立即拥有了 root 权限,这是由 Linux 内核保证的。
所以,要怎么越狱,就变得简单清晰了。既然安卓不带 su 程序,我们就自己改造编译一个不用输入密码的 su,然后执行越狱三步骤:
- 把 su 拷贝到系统目录:
cp /tmp/su /system/bin/
- 更改 su 的所有者为 root:
chown root:root su
- 给 su 追加 s 权限(已有x的基础上):
chmod u+s su
以后,安卓应用(JNI 或 Java)就可以创建进程运行 su ,然后以 root 身份执行 shell 命令实现某些目的了。当然,安卓应用本身仍然运行在普通模式,通常只做些本份的事情,脏活累活都靠 shell 命令去干。
root 授权管理
root 权限是系统的最高权限,不能谁想要都可以直接提权吧,Windows 还有 UAC 来让用户把关呢。所以一般的越狱工具(如 SuperSU 和 Magisk),都会带有一个 root 授权管理程序,让用户明明白白有哪些应用要尝试执行 su,要不要给它放行。
越狱工具带的 su 自然不是普通的 su,它会截获执行它的应用程序信息并及时告知用户,只有在用户同意的白名单中的 app ,才允许真正执行 su。白名单自然由授权管理程序维护,它是一个普通权限的安卓应用程序。
越狱的常用方法
上面提到,越狱要做的事情仅仅只有三步:拷贝su到系统目录、更改所有者和追加 s 权限。但这三步的每一步,都需要 root 权限。
这似乎是一个死循环,你想提升 root 权限,但首先你得是 root 权限!所以,常规手段自然是不行的!
在安卓早期,越狱相对容易点,很多一键Root软件(如360一键Root、Kingroot等)都是利用 Android 系统的漏洞,获得某个具有 root 权限的进程,然后利用该进程实现越狱三步。
比如 adb 的 RageAgainstTheCage 漏洞。adb 是安卓的重要调试工具,用户开启了 adb 调试后,会在安卓系统中运行一个 adbd 的后台守护进程,用户通过上位机连接 USB 线缆,调用 adb 实现众多调试或管理功能。
adbd 是由 init 进程启动的,而 init 本身就是以 root 的身份运行的,adbd 自然继承了这点。为了限制 adb 的权限,adbd 在启动过程中,自行降权,切换为普通的 shell 用户了。如果我们有手段,让 adbd 的切换用户的操作失败,那么,adbd 就将保持 root 身份,我们通过 adb shell,就能让 adbd 执行越狱三步了!
RageAgainstTheCage 漏洞就是通过 adb 执行 ratc,让其一直创建子进程又立即退出产生很多僵丝进程,当进程数达到 linux 允许的最大数目时,重启 adbd,这时 adbd 就没法创建新进程来切换用户了,切换虽然失败,但程序员因为没有写 “失败终止” 的代码,adbd 将继续以 root 身份运行。
厂家堵漏洞是很容易的。随着 Android 的发展,很多漏洞已经被堵上,这类一键Root软件就失去了用武之地。
现在要获取 Android 的 root 权限,更常用的方式是刷入第三方的 Recovery,然后再借助 Recovery 注入 su 实现越狱三步。
Recovery 是一个独立的 Linux 小系统(kernel + ramdisk),与安卓主系统完全隔离(独立分区),由 bootloader 直接引导运行,主要作用就是维护主系统,比如Android系统出现无法开启的故障时,就需要引导到该系统实现恢复出厂设置等操作。大多数设备厂商都会让用户按住特殊的按键组合开机,让 bootloader 引导到 Recovery 系统,如下图:
因为 Recovery 本身就一个独立、完整且 root 登录的 Linux 系统,我们既可以挂载主系统的根文件系统实现任何文件操作,也可以展开 boot.img 、修改其中的文件并重新打包成镜像烧录回 boot 分区中。它相当于一台可以随意操作 Flash 分区的外部电脑,执行越狱三步再简单不过了。当然,为了让小白也能操作,Recovery 可以做得很傻瓜很智能。
TWRP (TeamWin Recovery Project ) 就是这么一个第三方 Recovery,直接支持触控,操作简便,功能强大。像安装 root 程序(如 SuperSU 或 Magisk)到系统分区,都是常规的操作。
Recovery 还只是一种常规的通过独立系统来修改主系统文件的方式。事实上,任何能用的刷机手段都可以操作(读写) Flash 存储器中的数据,最终实现越狱三步。
伪装
为了应对越狱设备的潜存风险,2015年9月末,新发布的 Android 6.0 新增了 SafetyNet 程序。SafetyNet 本质是系统完整性检测程序,它会自动检测系统文件是否有被修改(例如注入su文件、修改系统文件、刷入第三方ROM等)。一旦未通过 SafetyNet 检测,设备就无法通过验证,从而导致刷机的用户无法使用 Google Play、Netflix 等使用了 SafetyNet 功能的应用,也无法获得任何OTA更新。
为了绕过 SafetyNet 监视,越狱工具显然还需要做必要的伪装,让系统认不出 root 状态。
Magisk 就是这么一个新型的越狱工具,区别于传统越狱工具,它会挂载一个与系统文件相互隔离的文件系统,来加载自己的内容。Magisk 的改动都发生在这个独立的文件系统中,不会影响到 Android 系统本身的文件,从而避免被检测。
丰富多彩的刷机方式
刷机手段并不是极客们发明的,而是厂家本来就提供的、方便自己开发、调试和测试的重要手段,极客们只是借用而已。
分析 CPU 的启动链,我们可以了解到所有能用的刷机方式。记住,这些方式都是厂家为了方便研发调试/售后维修/小批量生产烧录留的“后门”,目标是做到不依赖于外部硬件工具,仅靠主板自己就能烧录或修改 Flash 芯片(Nand/eMMC/UFS)中的数据(文件),厂家一般称之为在线烧录(准确来说是在板)。
CPU 的启动流程如上图蓝色箭头所示。
SoC 内部集成有只读存储器(iROM,也称 Boot ROM,用于存储PBL程序)和静态RAM(iRAM,在DDR工作前加载和执行 bootloader),受限于 CPU 金贵的硅面积,它们的容量都很小,因此,iROM 中的 PBL (初级引导)程序一般不会很复杂,主要就是初始化 Flash 控制器并引导 Flash 中的 SBL(bootloader 之一)。但为了方便烧录和售后救砖,PBL 一般还带了 EDL 功能(如高通的 9008 模式)。SoC 上电后,PBL 会首先检查某些引脚的状态,如高通会检查 USB 口的 D+ 和 D- 有没有短接(工程线中的按钮功能)在一起,若发现短接,PBL 就不往下引导,而是初始化 USB-CDC 模拟串口,等待上位机的指令。此时电脑上会看到一个虚拟串口,通过厂家提供的 EDL 软件,能够驱动 PBL 对整块 Flash 进行读写操作。因为 PBL 在 CPU 内部,不管 Flash 有没有数据,Flash 中的 bootloader 是否破坏,都不影响 PBL 的执行。所以 EDL 工具能做到终极救砖,只是一般不提供给普通用户。
能做到终极救砖的还有 JTAG 仿真。CPU 都会集成一个 Debug 模块,通过 JTAG 接口连接电脑的仿真调试套件。Debug 模块是一个独立的阉割版处理器,在 CPU 的任何执行状态,Debug 都能同时监控和操作包括 CPU 在内的很多硬件模块,功能非常强大,操作 Flash 控制器实现闪存的读写只是小菜一碟。但是,因为 JTAG 的管脚比较多,不但会占用 CPU 的 IO 资源(一般是复用管脚),还会占用板卡的面积,所以通常只用在初始开发阶段,产品上一般是不用的,所以通常这条路走不通。
正常使用场合,PBL 会加载闪存 boot 分区中的 bootloader (通常不止一级)到 iRAM后,CPU 执行权交给了 bootloader。
不像 PBL,bootloader 位于 eMMC 或 UFS 中,可持续升级改进,功能自然会比 PBL 强。bootloader 通常会利用 CPU 的主 UART (TTL电平的串口)跟上位机电脑(串口调试助手)通信,为用户提供命令行操作接口。用户通过执行 bootloader 开放的命令,可以实现许多调试功能,操作 Flash (如修改分区表、备份或烧录数据)自然不在话下。因为 bootloader 运行在 iRAM 或 DDR 中,通常整个 Flash 空间都是可以操作的。
但是,bootloader 开放 UART 命令行接口仍会占用 CPU 的 IO 管脚和电路板的 Layout 面积(到少要提供 GND、TXD、RXD 三个焊盘),有些厂家或产品并不会引出 UART 管脚。即使提供了,要拆开外壳连接电路也挺麻烦的。所以厂家一般会用外接的 USB 口,实现与上位机烧录工具(如 Fastboot)的通信,借助这些工具,用户就可以轻松访问或烧录 Flash 数据。正常情况,bootloader 会引导主系统(如 Andoird),但跟 PBL 一样,bootloader 也会通过检测某些引脚的电平状态(如按钮组合或线路短接)或 UART 的 RX(键盘按任意键)数据,来决定是否要停留在 bootloader 状态,还是要进入 fastboot 模式 ,或者要引导 Recovery 系统。通过 bootloader 刷机的前提条件,自然是 bootloader 程序没有被破坏,否则只能回溯到上一级 EDL 救砖了。
当用户通过特殊的管脚状态或显式的 bootloader 指令(如串口命令、主系统的自动更新指令标记、Reboot_to_LibreELEC.apk 标记)指定进入 Recovery 系统时,CPU 就会加载执行功能更强大的、独立分区的、与主系统同启动等级的 Recovery 系统。
Recovery 作为一个完整的 Linux 系统,可以借助已有的生态,轻松开发出强大的功能,就像TWRP,提供了复杂的 GUI 界面,不需要借助外部电脑即可完成复杂的操作,所以最为常用。但 Recovery 处于上电启动链的最末端,如果启动链中任何一级 bootloader 出错(通常是错误操作Flash分区或刷入错误的 bootloader 镜像引起的),都进不了 Recovery,更不用谈刷机或 root 了。
除了这些在线烧录方式,还有更硬核的离线烧录方式,一般也称生产烧录方式,是通过专门的一对多 Flash 烧录器,一次性同时烧录多片 Flash 裸片,烧写成功后再贴片焊接到主板上。
手机维修店一般也有生产烧录的软硬件,能够对拆焊下来的 Flash 芯片轻易读出数据或烧录镜像。维修店的烧录器通常是一对一的,结合各种封装的座子夹具,能应对各种闪存芯片。作为一个合格的极客,自然也会配置这些,淘宝上价格也不贵。
有趣的是,维修界一般称 Flash 芯片为字库芯片,年轻的工程师听到字库二字,可能会一脸懵逼。这是历史遗留下来的习惯叫法,大家也不要嘲笑人家,你较真反而显得你无知。
Bootloader 之战:BL 锁与解锁
知道了这么多 Flash 读写方式后,是不是再也不能阻止极客们刷机或修改系统提权了?
非也,对于设备(手机)厂商们来说,还有一个大招,不仅可以大幅度提升 root 的难度,还可以阻止用户刷第三方系统,妥妥地把设备做成一个全封闭的系统。
极客们要实现 root 提权,必然要修改 Android (Linux) 的系统文件,这些文件最终被打包成一个镜像烧录在 Flash 中。如果我们有办法检测系统镜像被第三方修改那怕一丁点,就拒绝启动系统,不就可以斩绝刷机越狱的后路了?因为操作系统的引导程序 —— bootloader, 就是厂家自己开发的,想怎么检测系统分区、要不要引导下一级系统,全由厂家说了算。
实现这个想法也不难,使用数字签名即可。大致流程是,厂家发布的系统镜像,都先经过了厂家自己的签名。bootloader 拒绝引导任何没有签名或者签名不对的系统镜像。而极客们修改过的系统镜像(不管是 boot.img 还是 recovery.img)和第三方出品的 ROM,是不可能通过 bootloader 的签名验证的,这就给设备加了一把强大的锁,即我们常说的 BL 锁。
那 bootloader 的签名验证是怎么实现的?为什么能实现烧录镜像的精准授权?
完整性保障:数字签名
数字签名是现代信息安全的基石,能实现比传统手写签名更好的效果(不可抵赖性更强)。每个人都可以申请一个数字证书,其中包含一对密钥:对外公开的公钥和私人密藏的私钥。这对密钥的神奇之处在于,用其中一个密钥加密的密文,只能通过另一个密钥解密。即是,如果签名者用私钥加密一份文档,任何人都可以通过公开的公钥解密出来,而且因为私钥只有签名者自己知道,全世界有且只有签名者能整出这么一份密文出来,因此具有不可抵赖性。又因为别人不可能修改文档(修改后就解密不出来了),还具有完整性(权威性)。
数字签名和验证的过程如下图所示,中间增加了哈希算法,因此具有签名大文档的能力。哈希算法是这么一个神奇的算法,它可以对任意长度的文档,快速计算出一个简短的指纹码(即哈希码)。说它是指纹码,是因为目前很难找出另一份内容有所不同、但拥有完全相同哈希码的文档(即使有也是乱码)。
有了哈希算法的加持,签名一个文档,只需要对这份文档的指纹码进行加密了,签名的效率大大提升。一份已签的文档,会包含原始文档以及签名码(即私钥加密过的哈希码)。当某人想验证这份签名文档的权威性时,只需要分离出原始文档和签名码,然后分两路计算出两个哈希码,只要两个哈希码相等,就可以认为,这份已签文档是完整的(中间没有人修改过),且一定出自签名者。
BL 锁原理
BL 锁就是借助数字签名,来实现安全引导(完整性验证)的。
作为设备厂家,我们首先要创建一对(非对称)密钥,有没有给数字证书的权威机构备案都没有关系。对于私钥,打死都不要拷贝给任何人,最好把它私钥加密并做进一个基于HASH算法的签名软件中,任何人都看不到私钥的内容,只有签名软件能读取调用。
当我们开发好一个系统镜像后,运行签名软件对整个镜像进行签名,最后会生成一个签名码,我们把这个签名码串接在系统镜像后即可,这么一个串接了签名码的镜像,就是一个授权镜像,任何没有经过我们签名软件处理过的镜像,都是非法镜像。因为只有我们的签名软件能读取私钥,第三方根据不可能计算出正确的签名码。
然后,我们把公钥放到 bootloader 代码中,并让 bootloader 在引导系统镜像之前,先做签名验证,即用HASH算法重新计算系统镜像的指纹码,并用公钥解密镜像所附的签名码,解密出来的码值理应与刚计算出来的指纹码一致,不一致就说明镜像有更改,就拒绝引导。
eFuse 与安全引导
聪明如你,一定发现了一个严重的问题。
因为我们的公钥保存在 bootloader 中,攻击者完全可以把 bootloader 中的公钥换成它们的公钥,然后用他们的私钥来签名第三方镜像。或者更简单点,直接编译一个没带数字签名的 bootloader,烧录替换掉我们的 bootloader ,不就可以引导任何系统了?
事实上也是如此,某些手机直接用高通的 EDL 工具(通过工程线让手机进入 9008 模式)烧录无锁的 bootloader,即可把 BL 锁去掉。
问题的关键在于,不管是 bootloader 还是公钥,都存储在可被擦写的 Flash 中。如果我们能把 bootloader 和公钥都存储在不可改写的 ROM 芯片中,攻击者就无计可施了,除非把 ROM 芯片换掉,换成无锁 bootloader 的ROM芯片。而 ROM 芯片引脚少价格便宜,更换还是很容易的。
更保险的做法是,把 bootloader 和 公钥做到 CPU 中 Boot ROM 中,或者说,把第一级的引导程序 PBL 就加上签名验证功能,这样的话,攻击者唯一的手段就是换上一片同型号无锁(PBL 没带签名验证)的 CPU。这个成本是很高昴的,因为一台手机的主要成本就集成中 CPU 身上,而且 CPU 引脚密集,更换的难度较大。
但这个方案有一个大问题,就是 CPU 厂家不止服务于一家手机厂商,难道要为每个厂家都推出一个特定公钥的版本出来,仅仅是因为公钥不同?
解决方案是在 CPU 内部集成一种特殊的存储器 —— 一次性可编程存储器(OTP,写入一次即变 ROM),比如 eFuse —— 电子保险丝,一种熔丝性器件,属于一次性可编程存储器。其原理如下图,集成了保险丝一样的电阻 Rsense,CPU 出厂后,这片 eFuse 空间内所有比特全为“1”。如果向一位 eFuse 单元写入“0”,在较高电压的作用下,这个单元的电阻 Rsense 就会融断,那么就彻底变为 0 值了,再也无法回到 “1” 了。
借助 eFuse,CPU 厂家只管出一个版本(Boot ROM 中的 PBL 完全一样),手机厂家拿到 CPU 后,自己在 eFuse 中烧入公钥即可。这个公钥一旦被烧录,eFuse 自动变为 ROM,从而实现了与全 ROM 一样的效果。
某些设备厂家不需要授权管控(安全引导)怎么办?CPU 厂家可以在 eFuse 中选取一位作为开关标志(Secure Boot),出厂状态是未融断,PBL 启动时读取这个开关的融断状态决定是否要做签名验证。如果厂家不想要安全启动,就不要融断这个开关,想安全启动,就往这个位写入 0 即可。当然,开关一旦被融断,就再也不能回到无锁状态了,CPU 厂家也无法帮你。
eFuse 的容量是很有限的,有些甚至都不能完整保存下整个公钥。业内的通常做法是,eFuse 保存公钥的指纹码(较短)即可。完整的公钥可保存在容器巨大的 Flash 中,PBL 在签名验证时,会先验证 Flash 中的公钥是否被篡改(其指纹码是否与 eFuse 中的一样),只有未被篡改,才会继续往下执行签名验证。
安全引导链
我们知道,为了灵活性,PBL 不会直接引导主系统,而是引导 SBL(二级 bootload),SBL 再引导 ABL(LK,三级 bootload),ABL 才最后引导主系统。在这一级级的引导中,是否依然可以实现最后的安全引导?
以高通 CPU 为例,如下图,绿色部分为实现安全启动的关键机制。
SoC 的 eFuse 中固化有厂家的根CA证书公钥的哈希码,可对下一级启动程序(SBL)内容进行完整性验证——这通过验证 SBL 的数字签名实现的。在手机生产之前,厂家已经把自己的 SBL 程序用自己的私钥签名了,生产烧录时,会把 eFuse 对应的公钥、 SBL 及其签名码一并烧录到 bootloader 分区。当手机启动时,PBL 会先验证公钥的完整性,再用公钥去验证 SBL 的可信度(是否出自高通)和完整性(是否修改过),只有验证通过才会正常启动 SBL。
SBL 会做另一些初始化的工作,最后又会尝试引导下一级的 bootloader —— Little Kernel (LK)。当然,这之前需要验证下一级 BL 是否可信且完整,即是否出自 SBL 自己证书(私钥)的签名。
LK 跟 SBL 或 PLB 类似,也同样带了自己证书的公钥,因此在引导下一级系统镜像( 无论是 boot.img 还是 recovery.img)之前,也得验证镜像的可信度和完整性,只有经过自己证书签名的系统镜像,才会回正常启动。
从破解的思路看,我们把LK自带的公钥改掉,改成自己的,再用自己的私钥对系统镜像进行签名,不就可以正常启动后级系统了?不行!因为你改了LK,无论是改了其中的公钥还是改了其中程序,就会被上一级的 SBL 觉察,根本不会启动你改过的 LK。
可以看到,一级一级 bootloader(BL)构成了信任链,只要保证最初的 PLB 所用的公钥的哈希码不可更改(ROM是改不了的),就能保障最后启动的系统镜像是可信的(厂家发布的)且未经第三方修改。这种一级一级BL启动链的信任传递过程,构成了完整的 Secure Boot,也即大家口中的 BL 锁。
综上,BL 锁(Secure Boot 安全引导机制)的目的,是为了保证最终能用的操作系统一定出自厂家官方,杜绝任何非授权的系统。有了 BL 锁的加持,极客或黑客的 root 越狱提权行为才能从根源上得以杜绝,是系统安全的重要保障。BL 锁不但让越狱提权变得困难重重,也阻止了极客刷第三方系统的可能性。
不但移动设备上实现了 Secure Boot,传统的 PC 界,在 UEFI BIOS 时代到来后,也迎来了 Secure Boot 的供应链升级。只是,主板 BIOS 上的 Secure Boot 开关通常是可以关闭的。
BL 解锁
虽然 SoC 的 eFuse 中可以一次性固化手机厂家的证书公钥(指纹),经过一级级的安全传递,手机厂家仍可以牢牢控制系统镜像的授权,但某些较温和的厂家(比如小米),仍然可以在最后一级的 BL 中放弃对最终系统的完整性验证,这就是官解 BL 锁。
一般情况下,设备的 BL 默认都是开了安全启动的(带锁),用户若想解开 BL 锁,需要按照厂家的规则提出申请,比如在没有 ID 锁定的情况下,把手机绑定一个帐号,等待若干天厂家同意后,通过厂家提供的软件,可以烧录一个不验证系统镜像签名的 BL 版本。解锁成功后,这个 BL 可以启动任何系统镜像(不局限于安卓)或第三方 Recovery。
聪明如你,一定也想到了官解 BL 锁的隐患。假如你向厂家申请了解锁,你将得到了一个官方授权且无锁的 bootloader。你把这个 bootloader 从 Flash 中提取出来,公开上传到搞机论坛上,那么,其他人也能轻易把这个 bootloader 刷到他们的手机,整个 Secure Boot 机制就这样被你轻松搞崩了!
厂家当然不会允许这种事情发生。事实上,你申请的官解 bootloader,仅在你手机上能用,其它手机大概率是用不了的。厂家只要在官解的 bootloader 中植入解锁手机的 ID(可以是 CPU ID、IMEI、MAC 或组合),上一级的 SBL 在验证完这个官解 BL 的完整性后,再查验里面的 ID 是否跟手机硬件上的 ID 一致,只有完全一致才会引导它。你手动改别人 bootloader 的 ID,改为自己手机的,就会破坏完整性,签证验证都通不过。可见,厂家也不容易,他要单独为你的 bootloader 做一次签名,还不能把签名功能放在客户端,得放在服务器才安全。一般厂家可能也不会为了给用户解锁 BL,专门弄出这么一套比较复杂的分布式程序,所以也不要骂厂家不厚道了。
还有些手机厂家出于某些目的,并没有打开 SoC 上的 Secure Boot 开关,只是在最后一级的 bootloader 上了 BL 锁。这种锁并不彻底,没有完全保证,攻击者只需要把这个 bootloader 换成无锁的 (通过更上一级的 EDL 刷机工具,如高通 9008),即可轻易破解。
如果你的设备厂家根本不支持官解,而且 CPU 也打开了 Secure Boot 开关(eFuse 不可能再关闭),还有没有办法强行解锁?
通过分析 BL 锁的原理可知,整条 BL 启动的信任链虽然设计得很巧妙,但绝非无懈可击。只要是软件,就会有 bug,毕竟程序员不可能考虑到所有场景的所有可能性;有 bug 就能充分利用,就能想尽办法绕过数字签名的验证过程,直接引导后级 BL 或系统,从而瓦解整条信任链。
整条安全启动链,要经过三级引导,只要有一级 BL 出现 bug,我们就能攻破 BL 锁跳过签名验证,直接引导无签名的系统,实现第三方系统镜像的刷机或 root。这就是传说中的 BL 锁破解。
例如 iOS 上著名的 checkmate 漏洞,就是 Boot ROM 中的代码有 bug,利用这个 bug ,就可以绕开签名验证,最终引导另外一个非苹果管控的操作系统(比如魔性版 iOS 甚至 Android)。联发科的芯片,也曾经出现过不少 BootROM 漏洞,比如 amonet 和 kamakiri 漏洞。
而后两级的 Bootloader,虽然太多都是闭源代码,且跟特定硬件绑定,很难进行逆向工程,但也不是完全牢不可破。比如高通旧版的 LK 系统,就存在 CVE-2014-9798 漏洞。
加州大学圣芭芭拉分校的研究人员研究了多家主流芯片厂商的安卓 bootloader ,从中发现了多个漏洞,如下表,这些漏洞可导致引导信任链被攻破,启动任何未授权的系统。他们甚至还开发了一个名为 BootStomp 的扫描工具,来专门甄别各家 BL 的潜在漏洞。
不可否认,随着一个个已知漏洞被陆续封堵,功能单一的 Bootloader 被变得越来越安全,破解 BL 锁将变得越来越费劲。
ID 锁与防盗
严格说来,ID (帐号)锁与 root 和 bootloader 无关,但经常会被普通用户混淆。
ID 锁的核心任务是解决设备丢失(盗抢)的问题。当用户遗失了一部手机时,他最关心的是:
- 手机中的秘密(密码笔记、艳照)不要被任何人获得,最好 FBI 都不能破解;
- 通过各种手段(如定位)追回;若不能追回,也要锁定手机,让手机变砖彻底失去价值;
手机厂商是怎么解决这些问题的呢?
信息安全
私人信息泄密的问题很好解决,只要把专门存储用户文件的分区进行全盘加密即可。当你设定了一个登录口令(数字/图案码、人脸、指纹都是口令)后,系统会根据主要口令(数字/图案码)自动生成一个密钥(加解密是同一密钥),然后用这个密钥加密所有用户文件!不用担心效率损失,CPU 通常集成了硬件加密算法,对于一般用户来说几乎是无感的。
当别人捡到你的手机后,因为他不知道你的口令,就无法生成解密密钥,即使他有能力从你的 Flash 存储盘中提取所有数据,那也是一堆乱码。基于目前主流加密算法的安全性,他唯一的解密方法,就是猜测你的密码(常用密码库撞库),或者通过社会工程的手段骗取你的密码,最后的手段就是暴力破解,一个一个尝试所有可能的密钥组合。
如果你不想泄露你的信息,请设置一个足够复杂的密码,但一定要记得住。如果你忘记了你的复杂密码,FBI 也很难给你解密恢复,你只能恢复出厂设置,含着泪丢失手机上的所有数据,所以,重要的数据请及时备份!
这里说下生物口令(指纹、人脸等)和主口令(数字/图案码)的区别。主口令就是加密密钥的源口令,生物口令最终都是要转化为主口令,再 Hash 出密钥,来解密用户分区的所有文件。为了避免用户忘记主口令,一般都要定期提醒用户使用主口令,如果一直用生物口令(太方便了),用户很可能会忘记主口令,万一传感器损坏或保存的对照数据出错,那用户再也不能解密出他的所有数据了。这也是为什么不选用生物口令做主口令的原因,毕竟使用数字或图案码作主口令,系统可以不保存口令,更安全更可靠。
ID 锁
锁定手机的前提是,你的手机登录了厂家的云帐号。登录云帐号后,系统你把你的帐号 ID 加密保存在 Flash 的各个隐秘角落,攻击者很难一一找出并正确修改,这就是 ID 锁的由来。
此外,登录云帐号,系统还会自动上传手机的关键信息(主要模块的唯一 ID)到云,所以,在厂家的数据库服务器中,保存了这么一条信息:帐号X 拥有一台手机,手机的主要零部件为: CPU-ID为444、IMEI 码为111、硬盘ID为222、WIFI/ETH/BTH MAC为333 …… 目前处理保护状态。
当你的手机丢失后,尽快通过另一台设备登录云帐号,锁定手机。如下图为小米的开启丢失模式:
手机中有一个防盗程序(暂时这么叫),以系统服务的形式一直在后台悄悄工作,正常使用时,你几乎感觉不到它的存在。
但手机在云中被标为丢失后,丢失的手机一旦联网,防盗程序很快就会知道丢失事实,迫使整个系统进入锁定状态,即禁用手机的所有功能 —— 除了显示解锁界面,让失主有机会输入云帐号解锁外。同时防盗程序还会持续上报 GPS 信息,让失主可以在云端查看手机的最后定位。如果之后网络被拾者禁掉,系统还会动用短信息,持续上报定位。这就是所谓的 ID 锁,与 BL 锁或 root 无关。
手机一旦进入锁定状态,防盗程序还会在 Flash 的其它分区记录锁定标记,即使破解者进入 Recovery 模式恢复出厂设置,系统依然知道手机处于锁定状态,失主的ID帐号是什么。
破解 ID 锁
我们现在以破解者的身份,来考虑怎么有效破除 ID 锁。
我们手上的这部手机,Flash 中保存了失主的身份 ID 及锁定标志,显而易见的方案是清掉这些信息。
我们拿出手头上的所有工具,经过一番折腾,终于干掉了 Flash 上的所有数据,然后重新刷入同型号未登录帐号的手机的 BL 及系统,或者直接换一片同型号的 Flash 芯片(所谓的拆字库硬解),是否可以彻底清除手机的 ID 锁,让这台手机恢复正常?
这取决于防盗程序的设计。如果手机厂商狠一点,比如苹果,防盗程序还会检验主要硬件模块的 ID,如 CPU 的 ID(eFuse 可写入唯一编号)、eMMC的 ID(通常会带OTP区域用于一次性写入ID和Secure Key)、WIFI/ETH/BTH 的 MAC 地址、基带的 IMEI 码等,只要有唯一ID的部件都将被拿来作为身份标识使用,这些硬件 ID 在之前失主登录云帐号时,已经关联到了失主的 ID,所以防盗程序只要联网一查,就知道这台手机是失主的,并且失主已经标识丢失了,所以防盗程序又会让系统进入锁定状态,重新在 Flash 中记录失主 ID 和丢失标记。
基于主要零部件已被标记的事实,破解者只能把这些零部件统统换掉,破解成本非常高,这些带ID标记的零部件在二手市场一文不值。
幸运的是,有些厂家并没有做得苹果这么彻底,仅仅是在系统升级或者登录云帐号时,才会联网验证零部件的 ID 进而触发锁机,所以换掉 Flash 芯片后,用户只要不升级不登录,也能正常使用。
另一个破解思路就是直接把防盗进程干掉或冻结掉,来应对防盗程序联网查验零部件ID再次锁定手机。这需要利用某一系统进程的漏洞,取得 root 权限才能操作,在日益完善的系统面前,难度越来越大。也可以更改系统文件,把防盗程序从系统中彻底删掉。这意味着我们需要改变系统镜像,而带 BL 锁的 bootloader 将拒绝引导我们更改过的系统。我们只能寄希望于破解 Secure Boot 引导链,难度可能比攻破系统进程(取得 root 权限)还大。从这个角度看,BL 锁让 ID 锁更牢固。
当然,如果手机不带 BL 锁(如申请官解过),或者没有全链条启用 Secure Boot,我们还是能轻易引导无防盗程序的破解系统或某一个第三方系统的。无 BL 锁的 ID 锁形同虚设。
第三种破解思路是,先一步拦截并丢弃防盗程序的网络请求,或者伪装一个服务器告诉防盗程序一切正常。这可以通过修改手机中的 DNS,让其指向一台屏蔽或劫持了厂家域名的 DNS 服务器,代价自然是不能访问厂家的任何服务。但这不适合一般的用户,更简便的做法是,通过设置手机的 VPN 连接,让所有网络请求都通过本机的一个代理软件中转,我们可以在代理软件中屏蔽或劫持防盗程序的网络请求。甚至还可以把代理 app 的图标隐藏起来,让一般用户看不出这是一台破解机。这种破解方法的优点是不需要改动系统文件,所有操作都是合规的操作(普通用户权限),缺点是一不小心代理软件挂掉,系统可能被重新锁定。
最后一种破解思路是从云帐号突破。云帐号注册时一般要求输入手机号和邮箱,以求用户在忘记登录密码的时候,还有途径来重置密码。如果我们能想办法获取到手机号和邮箱帐号,就可以通过短信或邮件的形式,诱骗用户点击到我们的钓鱼网站,自愿输入密码。我们一旦获取了密码,就可以以失主的身份解锁手机,退出云帐号。这种方案虽然成功概率很低,但一旦成功,效果极佳,能彻底实现无锁化,让手机重归一台合法的无锁机。
后记
如果你对手机安全感兴趣,你一定会喜欢下面这篇技术小说,它讲述了一个黑客如何步步为营盗走老板巨额资产的故事,读完你将对 root、BL 锁和 TEE 可信执行环境有更深刻的认识。
指纹识别/指纹支付安全吗?技术文章创作不易,如果本文对你有帮助,请点赞收藏加关注,我是折腾总匠,喜欢从第一性原理讲解一些有趣的技术,欢迎关注,让我们一起探讨学习,一起驰骋于浩瀚的知识海洋。
版权所有,禁止任何形式的转载!
本文参考自:
- Bootloader unlocking - Wikipedia
- BootStomp: On the Security of Bootloaders in Mobile Devices
- 引导加载程序概览 | Android Open Source Project
- Android Root原理分析及防Root新思路_android7 防止root-CSDN博客
- 手机的bl锁是什么意思? - 知乎 (zhihu.com)
- 浅析Android Root - 知乎 (zhihu.com)
免责声明:本文由卡卷网编辑并发布,但不代表本站的观点和立场,只提供分享给大家。
相关推荐

你 发表评论:
欢迎