二进制漏洞分析-18.华为TrustZone TEE_EID漏洞

admin 2023年12月10日09:20:40评论13 views字数 4987阅读16分37秒阅读模式

二进制漏洞分析-18.华为TrustZone TEE_EID漏洞

华为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 = %un", "[Trace]", 2);
    *(uint32_t *)(hash_tlv + 4) = hash_len;
    SLog("%s: Tlv hash_len = %un", "[Trace]", hash_len);
    if (memcpy_s(hash_tlv + 8, 0x1FFF8, hash, hash_len)) {
        SLog("%s: memcpy_s err size is %d, len is %dn", "[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 = %un", "[Trace]", 1);
*(uint32_t *)(hash_tlv + hash_len + 0xc) = zip_len;
SLog("%s: Tlv zip_len = %un", "[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 %dn", "[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 %pnn", "[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 = %un", "[Trace]", addr, len);
    return addr;
}

void eid_free(void *addr) {
    SLog("%s: Eid_free, addr = %pn", "[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 = %un", "[Trace]", buf->addr, size);
    return 0;
}

int free_eid_buffer(eid_buffer_t *buf) {
    // [...]
    buf->size = 0;
    SLog("%s: Free_eid_buffer, addr = %pn", "[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-40028 2022 年 1 月
函数中的 OOB 访问get_sec_image_zip CVE-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 日 - 我们定期交换有关公告发布的信息。

原文始发于微信公众号(安全狗的自我修养):二进制漏洞分析-18.华为TrustZone TEE_EID漏洞

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月10日09:20:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   二进制漏洞分析-18.华为TrustZone TEE_EID漏洞http://cn-sec.com/archives/2278947.html

发表评论

匿名网友 填写信息