摘要

ARM TrustZone 将系统划分为普通世界与安全世界,通过安全监控调用(SMC)实现切换。高通、联发科等厂商在实现 SMC 处理表时,常未严格验证调用 ID 范围,且允许在 EL2/EL1 特权下修改 SMC 表指针。攻击者可利用这些漏洞,劫持合法 SMC 调用,将其重定向至恶意处理函数,从普通世界读取安全世界内存(包括指纹模板、加密密钥),甚至将恶意载荷注入安全用户态(S-EL0)的可信应用(TA)中,实现持久化隐蔽后门。

SMC 指令与调用表

SMC 快速调用

在 TrustZone 架构中,普通世界(Normal World)的代码无论特权级多高,都无法直接访问标记为安全世界的物理内存或外设。唯一受控的跨域交互是通过 SMC(Secure Monitor Call) 指令。当普通世界执行 SMC #imm 时,CPU 陷入安全监控模式(Monitor Mode)或直接切换到安全世界的 EL3 固件。SMC 指令携带一个 16 位立即数,作为调用 ID,安全监控软件根据该 ID 查找预定义的函数表,执行相应的安全服务。

安全监控软件通常由 OEM 提供(如 Qualcomm 的 QSEE、MTK 的 Kinibi),运行在 EL3,充当 TrustZone 的看门人。其内部维护一个 SMC 调度表,每个条目包含一个调用 ID、处理函数指针以及参数个数等信息。

调用表的静态与动态注册

OEM 的 SMC 表通常分为两部分:编译期静态表(如高通 qsee_handle_smc)和动态注册表(用于后续加载的安全世界内核模块)。动态表的基址常存储在 EL3 固件的数据段中,可通过逆向固件或利用内存泄露漏洞获取。在某些实现中,动态表的尾指针未正确校验,导致调用 ID 可被恶意扩展,指向表中未初始化的条目甚至越界内存。

更危险的是,EL2 Hypervisor 或具有内核权限的 EL1 代码可以修改普通世界侧的异常向量表,拦截 SMC 陷入之前的控制流。或者,在 EL3 固件存在堆溢出/任意写漏洞时,可直接篡改 SMC 表的指针,将合法调用重定向至攻击者注入的代码片段。

SMC 调用表劫持的攻击面

未验证的调用 ID 范围

高通 MSM 平台的安全监控器(QSEE)在早期版本(如 Android 7-9)中,对 SMC ID 的范围检查仅限于表的上界,而下界和中间空洞未做校验。攻击者可以向一个未定义的 ID 发送 SMC,访问到表中偏移处的任意地址,该地址可能解析为攻击者控制的内存(如果 EL3 的全局变量恰好在表附近)。

联发科的 Kinibi OS 则暴露了一组“调试 SMC”,这些 SMC 本用于工厂测试,但在量产固件中未被移除。调用这些调试 SMC 可以读取任意安全世界物理地址、修改页表,甚至执行 EL3 任意代码。

通过 EL2 劫持 SMC 陷入路径

在虚拟化环境中,EL2 可以捕获普通世界发出的 SMC 指令(通过 HCR_EL2.TSC 设置)。Hypervisor 可以:

  • 截获 SMC,修改参数后转发给安全监控。
  • 直接模拟安全世界响应,欺骗普通世界。
  • 将 SMC 调用重定向至恶意代码,执行任意操作。

这种攻击在有恶意 EL2 的场景(如被攻破的宿主内核)下非常有效,因为普通世界的客户端无法区分真实的安全世界还是被 EL2 冒充的代理。

S-EL0 TA 注入

许多安全世界 OS(如 QSEE、OP-TEE)支持加载用户态可信应用(TA)。TA 位于 S-EL0,与安全世界内核隔离。如果 SMC 表被劫持,攻击者可以注入一个恶意 TA,并通过伪造的 SMC 调用将其映射到安全世界内存中。该 TA 可以持续窃取普通世界的敏感数据,或在安全世界内建立后门,绕过所有普通世界的安全检测。

劫持 QEMU 的 SMC 以泄露安全世界密钥

以下示例基于 ARM Trusted Firmware (ATF) 和 OP-TEE 在 QEMU 上的模拟环境。我们将演示通过修改 EL2 Hypervisor 的 SMC 陷阱来窃取 OP-TEE 的内部随机数。

环境搭建

使用 QEMU 模拟 ARMv8,ATF BL31 作为 EL3 固件,OP-TEE 作为安全世界 OS,Linux 作为普通世界。EL2 由一个自定义的 Hypervisor 小程序替代,捕获 SMC 并修改其行为。

EL2 层的 SMC 劫持代码

// smc_hijack_el2.c
// 运行在 EL2 的简单 SMC 劫持示例
#include<stdint.h>

#define SMC_HCR_TSC (1 << 19)   // HCR_EL2.TSC 位

voidel2_entry(){
uint64_t hcr;
asmvolatile("mrs %0, hcr_el2" : "=r"(hcr));
    hcr |= SMC_HCR_TSC;         // 启用 SMC 捕获
asmvolatile("msr hcr_el2, %0" :: "r"(hcr));

while (1) {
// 等待 SMC 陷入
uint64_t esr_el2, elr_el2, x0, x1;
asmvolatile(
"mrs %0, esr_el2\n"
"mrs %1, elr_el2\n"
            : "=r"(esr_el2), "=r"(elr_el2)
        );
uint32_t imm = (esr_el2 >> 5) & 0xFFFF; // SMC 立即数

// 读取调用参数
asmvolatile("mov %0, x0" : "=r"(x0));
asmvolatile("mov %0, x1" : "=r"(x1));

if (imm == 0x1234) {  // 目标 SMC ID
// 修改参数,使安全世界返回错误或泄露额外数据
            x0 = 0xdeadbeef;  // 攻击者控制的返回地址
            x1 = 0xcafebabe;  // 附加数据
asmvolatile("msr x0, %0" :: "r"(x0));
asmvolatile("msr x1, %0" :: "r"(x1));
        }

// 转发 SMC 到 EL3
asmvolatile(
"msr elr_el2, %0\n"
"mov x0, %1\n"
"eret"
            :
            : "r"(elr_el2), "r"(imm)
            : "x0", "x1"
        );
    }
}

说明:该代码运行在 EL2,捕获所有 SMC 调用。如果调用 ID 匹配目标(如 0x1234),则修改参数寄存器,再转发给 EL3。这可以使正常的安全世界调用返回被篡改的结果,导致普通世界的数据泄露。

OP-TEE 侧获取安全世界密钥

在 OP-TEE 中,密钥派生通常通过 TEE_GenerateKey 或直接调用硬件唯一密钥(HUK)。如果我们劫持了读取 HUK 的 SMC,就可以将 HUK 提取到普通世界。具体实现需要逆向特定 OEM 的 SMC ID 和参数结构,这里仅给出概念:

// op-tee_patch.c (在安全世界注入后使用)
// 将 HUK 读取并复制到共享内存
#include<tee_internal_api.h>
#include<utee_defines.h>

voidsteal_huk(void){
    TEE_Result res;
    TEE_Attribute attrs[2];
uint8_t huk[32];
    TEE_ObjectHandle hkey;

// 假设 SMC 被劫持后,攻击者已在 S-EL0 加载了此 TA
// 并且可以访问安全世界内存
    res = TEE_GenerateKey(NULL, 256, NULL, 0, &hkey);
if (res == TEE_SUCCESS) {
        TEE_GetObjectBufferAttribute(hkey, TEE_ATTR_SECRET_VALUE, huk, sizeof(huk));
// 将 HUK 复制到安全世界与普通世界的共享内存
// (通过映射物理地址实现)
    }
}

检测与防御

监控与审计

  • 普通世界侧:使用 SMC 调用计数器异常监控,短时间内大量不同 SMC ID 的调用可能为攻击。
  • EL2/Hypervisor 完整性:使用安全启动校验 Hypervisor,防止恶意 EL2。
  • 安全世界侧:定期审计 SMC 表的完整性,检测未授权的条目或指针偏移。

硬件与系统加固

  • 锁定 SMC 表:将 SMC 表放置在只读内存中,并在 EL3 初始化后通过 MPU/PMP 锁定。
  • SMC ID 范围严格校验:检查调用 ID 是否在白名单内,且对应的表条目是否经过签名。
  • 禁用调试 SMC:在量产固件中移除或通过 eFuse 永久禁用调试 SMC 调用。
  • TA 签名强制:仅允许执行经过 OEM 签名的 TA,防止注入未授权代码。

结语

TrustZone 的安全依赖于安全监控固件的完整性,而 SMC 调用表则是这道防线上的闸门。一旦闸门被来自 EL2 或 EL3 内部的攻击者劫持,安全世界的所有秘密——从指纹模板到硬件唯一密钥——都将如流水般倾泻至普通世界。防御者必须将 SMC 表视为与安全世界内核同等重要的攻击面,从固件设计、调用校验到运行时完整性监控层层布防。在硅后门被彻底封堵之前,TrustZone 仍只是一个脆弱的信任孤岛。