​二进制漏洞分析-18.华为TrustZone TEE_EID漏洞
2023-12-8 08:2:40 Author: 安全狗的自我修养(查看原文) 阅读量:12 收藏

 

二进制漏洞分析-5.华为安全监控漏洞(SMC MNTN OOB 访问)

二进制漏洞分析-10.华为TrustZone TEE_SERVICE_VOICE_REC漏洞

华为TrustZone TEE_EID漏洞

此通报包含有关以下漏洞的信息:

  • CVE-2021-40028 漏洞CVE-2021-40028 Encap_tlv_for_hash_zip 函数中的 OOB 访问

  • CVE-2021-40018 漏洞 get_sec_image_zip 函数中的 OOB 访问

  • CVE-2021-40021 漏洞 check_xxx_params函数中的参数指针信息泄漏

  • CVE-2021-40025 漏洞 堆指针 eid_malloc、eid_free、malloc_eid_buffer 和 free_eid_buffer 函数中的信息泄漏

函数中的 OOB 访问get_sec_image_zip

函数中有一个 OOB 访问:get_sec_image_zip

int get_sec_image_zip(void *ibuf0_addr, unsigned int *ibuf0_20028, unsigned int *ibuf0_20038, void *obuf3_addr) {
// [...]
img_buf = g_img_buf;
// [...]
for (int x = ibuf0_20028[0]; x <= ibuf0_20028[1]; x++) {
for (int y = ibuf0_20028[2]; y <= ibuf0_20028[3]; y++) {
*(uint8_t *)(eid_buf.addr + ...) = *(uint8_t *)(img_buf + x * 0x1E0 + y);
}
}
// [...]
}

g_img_buf存储在局部变量中,然后在许多循环中使用该变量,而无需检查它是否已被分配。如果确实未分配,则循环中的访问将是 OOB。img_buf

我们通过概念验证触发了此 bug,并获得了以下崩溃:

[HM] [ERROR][2171]vmem_as_ondemand_prepare failed
[HM] [ERROR][2496]process 1f00000028 (tid: 40) data abort:
[HM] [ERROR][2498]Bad memory access on address: 0x0, fault_code: 0x92000006
[HM]
[HM] Dump task states for tcb
[HM] ----------
[HM] name=[TEE_EID] tid=40 is-idle=0 is-curr=0
[HM] state=BLOCKED@MEMFAULT sched.pol=0 prio=46 queued=1
[HM] aff[0]=ff
[HM] flags=1000 smc-switch=0 ca=7253 prefer-ca=7253
[HM] Registers dump:
[HM] ----------
[HM] 32 bits userspace stack dump:
[HM] ----------
[HM] <get_sec_image_zip+0x200/0x360>
[HM] <?>+0x0/0x0
[HM] <proc_sec_zip_cmd>+0x34/0x48
[HM] <tee_task_entry>+0x398/0xcd4
[HM] Dump task states END
[HM]
[HM] [TRACE][1212]pid=48 exit_status=130

函数中的 OOB 访问Encap_tlv_for_hash_zip

这是函数中的另一个 OOB 访问:Encap_tlv_for_hash_zip

int Encap_tlv_for_hash_zip(int hash, int hash_len, int zip, int zip_len, uint8_t *hash_tlv) {
// [...]
*(uint32_t *)(hash_tlv + 0) = 2;
SLog("%s: Tlv hash type = %u\n", "[Trace]", 2);
*(uint32_t *)(hash_tlv + 4) = hash_len;
SLog("%s: Tlv hash_len = %u\n", "[Trace]", hash_len);
if (memcpy_s(hash_tlv + 8, 0x1FFF8, hash, hash_len)) {
SLog("%s: memcpy_s err size is %d, len is %d\n", "[Error]", 0x1FFF8, hash_len);
return -1;
}
printHexWithTag("Sm3 hash", hash, hash_len);

*(uint32_t *)(hash_tlv + hash_len + 8) = 1;
SLog("%s: Tlv zip type = %u\n", "[Trace]", 1);
*(uint32_t *)(hash_tlv + hash_len + 0xc) = zip_len;
SLog("%s: Tlv zip_len = %u\n", "[Trace]", zip_len);
if (memcpy_s(hash_tlv + hash_len + 0x10, 0x1FFF0 - hash_len, zip, zip_len)) {
SLog("%s: memcpy_s err size is %d, len is %d\n", "[Error]", 0x1FFF0 - hash_len, zip_len);
return -1;
}

return hash_len + 0x10 + zip_len;
}

的值上限为 0x1FFF8,因为第一个 。但对于介于 0x1FFF1 和 0x1FFF8 之间的值,可以观察到以下行为:hash_lenmemcpy_shash_len

  • TLV 类型 (1) 在偏移处的写入可以是 OOBhash_len + 8

  • TLV 长度 () 在偏移处的写入可以是 OOBzip_lenhash_len + 0xC

  • at 偏移量的目标可以是 OOBmemcpy_shash_len + 0x10

  • ()的大小可以下溢memcpy_s0x1FFF0 - hash_len

该函数将检测负大小,因此无法利用此行为。TLV 类型和长度的 OOB 写入将发生越界,但它们不会使 trustlet/分配器崩溃。我们怀疑这是因为分配是 mmap 的,并且大小(包括元数据)是页面对齐的,导致分配后出现填充。memcpy_s

尽管如此,通过使用概念证明触发此错误,我们可以看到负大小 (-4),证明 TLV 类型和长度 OOB 写入访问:

[TEE_EID-1] [Trace]: ------ TA_InvokeCommandEntryPoint ------
[TEE_EID-1] [Trace]: Recived the commond, id is 9
[TEE_EID-1] [Trace]: Recived the unsec zip message
[TEE_EID-1] [Trace]: Into the proc_unsec_zip_cmd function
[TEE_EID-1] [Trace]: Malloc_eid_buffer, addr = 0x375f010, len = 131072
[TEE_EID-1] [Trace]: Tlv hash type = 2
[TEE_EID-1] [Trace]: Tlv hash_len = 131060
[TEE_EID-1] [Trace]: Tlv zip type = 1
[TEE_EID-1] [Trace]: Tlv zip_len = 4096
[TEE_EID-1] [Error]: memcpy_s err size is -4, len is 4096
[TEE_EID-1] [Error]: Encap_tlv_for_hash_zip failed!
[TEE_EID-1] [Trace]: Free_eid_buffer, addr = 0x375f010

函数中的参数指针信息泄漏check_xxx_params

检查每个命令的输入参数的函数中存在信息泄漏,包括函数(在 0x71A8 处):check_common_params

unsigned int check_common_params(int paramTypes, TEE_Param *params) {
// [...]
if (params[0].memref.size != 4 || !params[0].memref.buffer) {
SLog("%s: Invalid param[0], size is %u, buffer address is %p\n\n", "[Error]",
params[0].memref.size, params[0].memref.buffer);
return 0xFFFF0006;
}
// [...]
}

当参数缓冲区地址的大小不正确时,所有这些函数都会打印参数缓冲区地址。这将显示缓冲区始终映射在同一地址。下面是一个日志消息示例:

[TEE_EID-1] [Trace]: Recived the commond, id is 6
[TEE_EID-1] [Trace]: Recived the id info message
[TEE_EID-1] [Error]: Invalid param[3], size is 2056, buffer address is 0x70004000

堆指针 、 和 函数中的信息泄漏eid_malloceid_freemalloc_eid_bufferfree_eid_buffer

分配和解除分配函数中存在信息泄漏,包括 、 、 和 :eid_malloceid_freemalloc_eid_bufferfree_eid_buffer

void *eid_malloc(int len, int hint) {
// [...]
addr = TEE_Malloc(len, hint);
SLog("%s: Eid_malloc, addr = %p, len = %u\n", "[Trace]", addr, len);
return addr;
}
void eid_free(void *addr) {
SLog("%s: Eid_free, addr = %p\n", "[Trace]", addr);
TEE_Free(addr);
}
int malloc_eid_buffer(eid_buffer_t *buf, int size) {
// [...]
buf->addr = TEE_Malloc(size, 0);
// [...]
buf->size = size;
SLog("%s: Malloc_eid_buffer, addr = %p, len = %u\n", "[Trace]", buf->addr, size);
return 0;
}
int free_eid_buffer(eid_buffer_t *buf) {
// [...]
buf->size = 0;
SLog("%s: Free_eid_buffer, addr = %p\n", "[Trace]", buf->addr);
return TEE_Free(buf->addr);
}

这些函数打印已分配/释放缓冲区的地址。在开发堆漏洞时,这可能是有用的信息。下面是一个日志消息示例:

[TEE_EID-1] [Trace]: Malloc_eid_buffer, addr = 0x375f010, len = 131072
...
[TEE_EID-1] [Trace]: Free_eid_buffer, addr = 0x375f010

受影响的设备

我们验证了这些漏洞是否影响了以下设备:

  • 麒麟990:P40 专业版 (ELS)

请注意,其他型号可能已受到影响。

补丁

名字严厉CVE漏洞补丁
函数中的 OOB 访问Encap_tlv_for_hash_zip危急CVE-2021-40028 漏洞CVE-2021-400282022 年 1 月
函数中的 OOB 访问get_sec_image_zipCVE-2021-40018 漏洞2022 年 1 月
函数中的参数指针信息泄漏check_xxx_params中等CVE-2021-40021 漏洞2022 年 1 月
堆指针 、 和 函数中的信息泄漏eid_malloceid_freemalloc_eid_bufferfree_eid_buffer中等CVE-2021-40025 漏洞2022 年 1 月

时间线

  • 2021年11月05日,华为PSIRT收到漏洞报告。

  • 2021年11月16日 - 华为PSIRT确认该漏洞报告。

  • 2022年1月1日 - 华为PSIRT表示,这些问题已在2022年1月的更新中修复。

  • 从 2022 年 11 月 30 日至 2023 年 7 月 19 日 - 我们定期交换有关公告发布的信息。

  • 二进制漏洞(更新中)

  • 其它课程

  • windows网络安全防火墙与虚拟网卡(更新完成)

  • windows文件过滤(更新完成)

  • USB过滤(更新完成)

  • 游戏安全(更新中)

  • ios逆向

  • windbg

  • 恶意软件开发(更新中)

  • 还有很多免费教程(限学员)

  • 更多详细内容添加作者微信


文章来源: http://mp.weixin.qq.com/s?__biz=MzkwOTE5MDY5NA==&mid=2247490442&idx=1&sn=a431ac86e40caceec9a658a7e6ef36b0&chksm=c13f28c3f648a1d5c29049695359fb572f590470833e126d24453562b9deeaa8aa5a0c66dd5f&scene=0&xtrack=1#rd
如有侵权请联系:admin#unsafe.sh