CVE-2024-56426 Exynos9830 Bootrom 漏洞利用 - SM-G985F
[!CAUTION] 当前的密钥包和生成的文件具备熔断(fusing)能力。一旦设备被熔断, eFuse 更改将不可逆,并且设备必须继续使用与该熔断密钥匹配的引导镜像和密钥材料。 由于熔断行为,使用这些文件或流程的风险自负; 所有后果均由运行它们的用户承担。在运行任何熔断流程之前,请核实 eFuse 文件、私钥、 已签名的 FWBL1、LK /
sboot.bin镜像以及目标设备。
| 路径 | 用途 |
|---|---|
bootLoaderFiles/ | 引导加载程序二进制文件、拆分后的引导加载程序部件、原始镜像、解密镜像和转储产物。 |
bootromNotes/ | Boot ROM 笔记、流程图和 USB 上下文偏移量。 |
exploit/ | Python 工具、漏洞利用运行器、拆分/合并脚本、payload 构建辅助工具和 SoC 数据。 |
exploit/extra/images/ | 漏洞利用流程所使用的工作引导加载程序镜像。 |
exploit/extra/payloads/ | 从 external/payloads/ 复制的已构建 payload 二进制文件。 |
external/ | Payload 源码、构建 Makefile、反编译笔记、共享密钥材料和辅助工具。 |
external/keys/exynos9830_crecker/ | 签名加载器流程所使用的共享 Exynos9830 / Exynos990 自定义密钥包。 |
exynos990reverseEng/ | Exynos 990 逆向工程项目文件。 |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu
brew tap messense/macos-cross-toolchains
brew install aarch64-unknown-linux-gnu
python3 -m pip install -r requirements.txt
requirements.txt 包含 coloredlogs、cryptography、hexdump、libusb、pyusb 和 pycryptodome。
在 Windows 上,BootROM USB 设备 04e8:1234 必须使用 WinUSB/libusb 兼容
驱动,PyUSB 才能打开它。参见 exploit/windows/README.md。
仓库在 exploit/windows/Exynos_USB_Device.inf 处包含一个 WinUSB 驱动包,
其匹配的目录文件和证书导入文件位于同一目录中。
sboot.binpython3 exploit/split.py bootLoaderFiles/originalSboot_K/sboot.bin -o exploit/extra/images
拆分脚本会将镜像部件和 split_manifest.json 文件写入输出目录。
LK 镜像必须为自定义密钥流程使用 ROM 安全启动密钥 2 命令 ID:
在 Ghidra 项目中应用 LK 补丁 TSV 时,辅助工具是通过 Ghidra headless 模式这样调用的:
GHIDRA=/path/to/ghidra_12.0.4_PUBLIC
REPO=$(pwd)
"$GHIDRA/support/analyzeHeadless" "$REPO/exynos990reverseEng" exynos990 \
-process lk.bin \
-noanalysis \
-scriptPath "$REPO/external/ghidra" \
-postScript ApplyLkPatches.java "$REPO/external/ghidra/lk_985_selected_patches.tsv"
将 32 字节的 eFuse 密钥嵌入 lk.bin 偏移 0x205008 处,替换原厂密钥:
dd if=external/keys/exynos9830_crecker/crecker.efuse of=exploit/extra/images/lk.bin bs=1 seek=$((0x205008)) count=32 conv=notrunc
xxd -g1 -s $((0x205008)) -l 32 exploit/extra/images/lk.bin
python3 exploit/merge.py exploit/extra/images Exynos9830
合并脚本会将 sboot.bin 写入当前工作目录。
构建 external/payloads/ 下的 payload 项目,并将生成的二进制文件复制到 exploit/extra/payloads/:
./exploit/build_payloads.sh
UFS 加载器和自定义密钥 payload 在构建时会嵌入 32 字节的 efuse 文件。
默认情况下,Makefile 读取 external/keys/exynos9830_crecker/crecker.efuse;
需要时可通过 CUSTOM_KEY_EFUSE=/path/to/crecker.efuse 覆盖。
由 exploit/exploit.py 运行的预检步骤会在每次签名运行前对
exploit/extra/images/ 中的 SBoot 镜像集进行就地重新签名。不会保留单独的签名
输出。签名步骤使用有意纳入版本控制的共享密钥包,位于 external/keys/exynos9830_crecker/ 下。
在仓库根目录对完整镜像集执行等效命令:
python3 external/tools/sign_sboot_images.py \
--images-dir exploit/extra/images \
--keys-dir external/keys/exynos9830_crecker
将签名以下镜像:
批量签名器为每个镜像传入十进制 23,并且不会重用
现有 footer 中已有的旧回滚值。
如需要,epbl.img 会先重新加密,再对最终字节进行签名。
如果 ldfw.img 和 tzsw.img 的 AVB 内容需要刷新,则仍需要外部 AVB 流程。
仅 FWBL1 的命令为:
python3 external/tools/sign_tool.py \
-i exploit/extra/images/fwbl1.img \
-o exploit/extra/images/fwbl1.img \
-k external/keys/exynos9830_crecker/crecker_private.pem \
-H external/keys/exynos9830_crecker/crecker.hmac \
-s 0x3000 \
-r 23 \
-ma 0x9830 \
-m 0x142 \
-e 11 \
-t external/keys/exynos9830_crecker/crecker_stage2_tee_pubkey.bin \
-re external/keys/exynos9830_crecker/crecker_stage2_ree_pubkey.bin
当 sign_tool.py、fwbl1.img 和 crecker_* 文件位于当前目录时的简短形式:
python3 sign_tool.py -i fwbl1.img -o fwbl1.img -k crecker_private.pem -H crecker.hmac -s 0x3000 -r 23 -ma 0x9830 -m 0x142 -e 11 -t crecker_stage2_tee_pubkey.bin -re crecker_stage2_ree_pubkey.bin
除非另有说明,请在仓库根目录运行命令。
观察到的 Exynos 9830 启动流程如下:
注意:mem.bin 转储 payload 仅在未安装可用 sboot 时才能使用。
通过 Heimdall 将 uh.bin 发送到引导加载程序:
heimdall flash --BOOTLOADER uh.bin
运行转储流程:
python3 exploit/exploit.py --dump
查看生成的 exynos990.bootrom.bin 转储。
本仓库中的部分 Python 恢复工具改编自 halal-beef/hubble。
该上游项目以 GNU GPL v2.0 发布,本仓库为兼容性保留 GPL-2.0 许可证。 参见 LICENSE 和 NOTICE.md。
external/payloads/exynos990_boot_custom_key/ 下的 Exynos990 自定义密钥 payload 基于
VDavid003/exynos-usbdl(
frederic/exynos-usbdl 的一个分支)的
boot-custom-key payload 框架和控制流思路。该 payload 已针对
Exynos9830 / Exynos990 GET_CONFIGURATION 链进行了大量重写和适配,并非上游
payload 的逐字复制。由于所引用的上游项目采用 GNU GPL v3.0 许可,此 payload
仅以 GPL-3.0 许可发布;参见 external/payloads/exynos990_boot_custom_key/LICENSE。
| 密钥 1 命令 | 值 | 密钥 2 命令 | 值 |
|---|
CMD_W_ROM_SEC_BOOT_KEY1 | 0x001 | CMD_W_ROM_SEC_BOOT_KEY2 | 0x016 |
CMD_W_USE_ROM_SEC_BOOT_KEY1 | 0x002 | CMD_W_USE_ROM_SEC_BOOT_KEY2 | 0x017 |
CMD_C_ROM_SEC_BOOT_KEY1 | 0x100 | CMD_C_ROM_SEC_BOOT_KEY2 | 0x114 |
CMD_R_USE_ROM_SEC_BOOT_KEY1 | 0x101 | CMD_R_USE_ROM_SEC_BOOT_KEY2 | 0x115 |
| Payload | 输出路径 | 用途 |
|---|
mem.bin | exploit/extra/payloads/mem.bin | Boot ROM 内存转储 payload。 |
loader.bin | exploit/extra/payloads/loader.bin | --ufs 使用的 UFS 路径 payload。 |
Exynos990_boot_custom_key.bin | exploit/extra/payloads/Exynos990_boot_custom_key.bin | --signed 使用的自定义密钥签名加载器 payload。 |
| 镜像 | 使用的密钥材料 | 回滚版本 |
|---|
fwbl1.img | BL1 私钥 + Stage2 TEE/REE 公钥 | 23 |
epbl.img | Stage2 TEE 私钥 | 23 |
bl2.img | Stage2 REE 私钥 | 23 |
lk.bin | Stage2 REE 私钥 | 23 |
el3_mon.img | Stage2 TEE 私钥 | 23 |
ldfw.img | Stage2 TEE 私钥,内部 + 外部 | 23 |
tzsw.img | Stage2 TEE 私钥,内部 + 外部 | 23 |
| 命令 | 模式 | 默认 payload | 说明 |
|---|
python3 exploit/exploit.py --ufs | UFS 路径 | loader.bin | 启动 UFS payload 流程。 |
python3 exploit/exploit.py --signed | 签名引导链 | Exynos990_boot_custom_key.bin | 重新签名 SBoot 镜像集,发送镜像。 |
python3 exploit/exploit.py --dump | Boot ROM 转储 | mem.bin | 接收 0x20000 字节并写入 exynos990.bootrom.bin。 |
| 步骤 | 说明 |
|---|
| 1 | 进入下载模式。 |
| 2 | 需要时使用 exploit/merge.py 创建或更新 sboot.bin。 |
| 3 | 使用签名自定义密钥流程进入 Crecker 模式,这是一种接受目标镜像流程的 ODIN 风格模式。 |
| 4 | 通过 ODIN、Heimdall 或其他兼容的发送工具发送新的 sboot.bin。 |
| 5 | 运行 UFS payload。 |
| 6 | 可选:为 One UI 7 和 Strong Integrity 工作流安装 CreckerRom。 |
| 7 | 可选:目标设置完成后锁定引导加载程序。 |
| 步骤 | 阶段 | 说明 |
|---|
| 1 | BootROM | 初始 ROM 执行。 |
| 2 | BL1 | 从 BootROM 完全交接。 |
| 3 | EPBL | 从 BL1 完全交接。 |
| 4 | EPBL | 设置一个最小的 SMC 处理程序。 |
| 5 | BL2 | EPBL 加载 BL2。 |
| 6 | BL2 | 部分交接给 BL2。 |
| 7 | LK | BL2 使用 EPBL 加载 LK,但 LK 不会立即执行。 |
| 8 | EL3 Monitor | BL2 使用 EPBL 加载 EL3 Monitor。 |
| 9 | EL3 Monitor | EPBL 解密 EL3 Monitor。 |
| 10 | EL3 Monitor | 完全交接给 EL3 Monitor。 |
| 11 | EL3 Monitor | 初始化并设置扩展 SMC 处理程序。 |
| 12 | LK | 执行跳转到 LK。 |
| 13 | LK / EL3 Monitor | LK 调用 EL3 Monitor SMC 处理程序以加载 TrustZone 部件。 |
| 14 | ODIN / 自定义目标 | 启动继续到 ODIN 或配置的目标。 |
| 部件 | 起始 | 结束 |
|---|
fwbl1.img | 0x0 | 0x3000 |
epbl.img | 0x3000 | 0x16000 |
bl2.img | 0x16000 | 0x82000 |
lk.bin | 0xDB000 | 0x35B000 |
el3_mon.img | 0x35B000 | 0x39B000 |
| 阶段 | 加载地址 |
|---|
BL1 | 0x02022000 |
EPBL | 0x02026000 |
BL2 | 0x15600000 |
LK | 0xE8000000 |
EL3_MONITOR | 0xBFE80000 |
_boot_device 源 ID | 引导源路径 |
|---|
1 | UFS 路径,共享 UFS 加载流程。 |
2 | eMMC/SDMMC 初始化路径,mmc_card_detect_and_init 流程。 |
3 | SDMMC/MMC 设备 0,mmc_read_blocks(0, ...)。 |
4 | USB 加载路径。 |
5 | SDMMC/MMC 设备 1,mmc_read_blocks(1, ...)。 |
6 | UFS 备用模式,与 1 相同的核心 UFS 流程,但使用不同的模式标志。 |
7 | 非 MMC/UFS/USB 的原始控制器读取路径。 |
0xB / 11 | USB 回退路径,然后使用与 4 相同的 USB 处理程序。 |
| 源 ID | 值 | 含义 |
|---|
1 | 0x20 | UFS |
2 | 0x14 | eMMC |
3 | 0x00 | SDMMC_CH2 |
4 / 0xB | 0x40 | USB |
| 致谢 | 贡献 |
|---|
| Chimera Tool | 大约在 2021-2022 年首次发现该漏洞。Chimera 在众多设备上提供高级 Exynos 维修服务能力,包括基于此漏洞的能力。 |
| CVE-2024-56426 | 本项目所基于的 CVE。 |
| Christopher Wade | 向三星报告了 CVE-2024-56426。 |
| kethily-daniel | 提供了用于 USB 数据包跟踪和样本提取的工具访问权限。 |
| BotchedRPR | 协助了 carte2 的初步研究和创建。 |
| VDavid003 | 通过数据包转储协助对 PoC 进行逆向工程,并在设备上亲自测试。 |
| halal-beef / hubble | 在研究周期内提供了 PoC 的初始 USB 数据包转储和分析、漏洞利用脚本使用的后端代码,以及拆分和合并脚本使用的 SoC 布局。 |
| VDavid003 / exynos-usbdl | 提供了 GPLv3 自定义密钥 payload 框架和 Exynos USB 下载参考流程,作为 Exynos990 自定义密钥 payload 的基础。 |
| R0rt1z2 | 协助了 payload 的创建;部分工作基于他的项目 kaeru。 |
| AntiEngineer | 分享了 ARM 知识、提示和研究支持。 |
| AA | 漏洞灵感来源,以及 Chimera 之外的首次使用。 |