ARM TrustZone机制实战分析:转向安全世界
字数 1794 2025-08-23 18:31:24
ARM TrustZone机制实战分析:转向安全世界
一、ARM TrustZone基础概念
1.1 ARM TrustZone概述
ARM TrustZone是ARM v7-A和v8-A处理器内置的安全扩展功能,将硬件划分为两个独立部分:
- 普通世界(Normal World):运行常规操作系统如Android
- 安全世界(Secure World):运行可信执行环境(TEE)
1.2 相关术语
- TEE(Trusted Execution Environment):安全执行环境,包含小程序、库和操作系统
- Samsung Knox:三星提供的安全组件集合
- TEEgris:三星基于Exynos处理器的可信操作系统
- 可信小程序(Trusted App):在TEE中执行的应用程序
二、安卓系统与TEE交互机制
2.1 世界切换机制
- 通过
smc指令切换处理器状态 - EL0(用户空间)无法直接使用
smc,需要EL1(内核)支持 - 三星设备通过
/dev/tz_wormhole设备文件实现通信
2.2 可信小程序存储位置
在/system/tee/目录下,以UUID命名的文件包含32位ARM ELF格式二进制文件:
j3y17lte:/system/tee $ ls -l
00000000-0000-0000-0000-00000000dead
00000000-0000-0000-0000-000000534b4d
00000000-0000-0000-0000-0000534b504d
...
2.3 启动归档文件
/system/tee/startup.tzar包含安全执行环境用户空间文件:
startup_tzar
├── bin
│ ├── 00000004-0004-0004-0404-040404040404
│ ├── 00000005-0005-0005-0505-050505050505
│ └── ...
└── arm
├── libc++.so
├── libdlmsl.so
├── libmath.so
└── ...
三、GlobalPlatform TEE API分析
3.1 关键回调函数
可信小程序需要实现五个回调函数:
TA_CreateEntryPoint:创建时调用TA_DestroyEntryPoint:销毁时调用TA_OpenSessionEntryPoint:打开会话时调用TA_CloseSessionEntryPoint:关闭会话时调用TA_InvokeCommandEntryPoint:处理请求时调用
3.2 IDA逆向工程辅助
开发IDA专用类型库:
- 使用Hexrays的stilib工具生成
tee_arm.til - 使用pycparsert生成函数签名脚本
tee_arm.py
四、密钥管理器漏洞分析
4.1 漏洞发现
在密钥管理器可信小程序(KEYMST)中发现栈溢出漏洞:
__int64 hal_rsa_key_get_pub_exp(hal_rsa_key *a1) {
size_t pub_exp_size = a1->pub_exp_size; // 攻击者可控
char *v2 = (char *)&a1->content + a1->pub_exp_offset;
v4 = 0LL;
memcpy(&v4, v2, pub_exp_size); // 栈溢出
return v4;
}
4.2 漏洞利用条件
- 导入PKCS8格式RSA私钥
- 公开指数大小可控(最大512字节)
- 可覆盖栈上最多0x200-8=0x1f8字节
4.3 漏洞触发路径
TA_InvokeCommandEntryPoint:入口点tz_process_command和km_import_key:解析验证公钥参数km_rsa_key_get_pub_exp:最终触发漏洞
五、Qiling模拟器构建
5.1 模拟器设计
基于Qiling构建TEEGris模拟器的优势:
- Python编写,便于监控和控制执行
- 支持POSIX系统调用模拟
- 支持快照功能
5.2 系统调用分析
通过分析libtzsl.so确定系统调用约定:
- r7寄存器保存系统调用号
- 参数通过r0-r6传递
示例系统调用:
syslog:
PUSH {R4,R7,R11,LR}
MOV R7, #0x12 ; 系统调用号
ADD R11, SP, #0xC
SVC 0 ; 触发系统调用
CMN R0, #0x1000
...
六、ROP链构建
6.1 引导ROP链
- 保存寄存器到bss段
- 使用
mmap系统调用分配新栈(0xdead000, 0x8000字节) - 复制输入缓冲区内容到新栈
6.2 嵌入ROP链
使用Thumb2指令ldm.w实现栈转储:
ldm.w ip, {r0, r1, r3, r4, r5, r6, r8, sb, fp, ip, sp, pc}
七、可信驱动程序利用
7.1 STST驱动程序分析
驱动程序注册ioctl回调:
int TA_CreateEntryPoint() {
drv.open_f = drv_open;
drv.ioctl_f = drv_ioctl;
v2 = TEES_RegisterDriver(&drv);
...
}
7.2 任意读写原语
利用格式化字符串漏洞:
- 使用
%pU泄露地址 - 使用
%n实现任意写
7.3 自定义printf格式
利用register_printf_format实现代码执行:
int __fastcall register_printf_format(char a1, int a2) {
for (i = 0; i != 10; ++i) {
if (!custom_formats_tab[8*i+1]) {
custom_formats_tab[8*i] = a1;
custom_formats_tab[8*i+1] = a2;
return 0;
}
}
return 1;
}
八、ARM架构细节
8.1 T32指令集
- ARM指令:4字节
- Thumb指令:2字节
- Thumb2指令:4字节,扩展Thumb功能
8.2 多重加载指令
Thumb2的ldm指令允许设置pc,但ROP工具可能无法正确识别:
ldm r4, {r0, r1, r2, r3, r4, r5, r6, r7, r8, sb, fp, sp, lr, pc}
九、安全建议
- 启用栈保护(Stack Canary)
- 启用位置无关可执行(PIE)
- 启用只读重定位(RELRO)
- 严格验证输入参数
- 限制可信小程序的权限
十、影响版本
- KEYMST漏洞:影响Android P版本
- STST漏洞:影响Android P到R版本
- Android S及更高版本已修复