Microsoft Hyper-V虚拟TPM设备漏洞分析

admin 2024年2月17日00:52:51评论9 views字数 5254阅读17分30秒阅读模式
写在前面

2023年10月微软发布的安全更新中,修复了2个由笔者报送的Hyper-V虚拟TPM设备漏洞。

本次修复的Hyper-V虚拟TPM组件的漏洞可以通过远程访问虚拟机的方式触发漏洞,造成宿主机拒绝服务或者远程代码执行,对宿主机上的其他虚拟机或业务造成损失。

01
背景介绍

Hyper-V的虚拟TPM组件旨在为虚拟机提供模拟的TPM设备,虚拟TPM设备可以为依赖TPM设备的服务或者操作系统(例如Windows 11)提供支持。

漏洞位于vmsp.exe进程中的TpmEngUM.dll二进制文件中,本次介绍的两个虚拟TPM组件的漏洞就是位于TpmEngUM.dll这个二进制文件中。

vmsp.exe进程与vmwp.exe进程相似,都是一个虚拟机实例启动一个进程。但是不同的是vmsp.exe进程是隔离用户模式(IUM)进程,也就是说vmsp.exe进程无法在windows用户态下被正常attach。所以在调试上,针对vmsp.exe进程的调试就需要额外的“手脚”,这里我们引用Quarkslab博客的文章《Debugging Windows Isolated User Mode (IUM) Processes》,感兴趣的读者可以去了解并实践下,这里不做讨论。

02
环境搭建

虚拟TPM组件漏洞的触发需要在Hyper-V虚拟机设置中的“安全”设置中,勾选“启用受信任的平台模块”。

Microsoft Hyper-V虚拟TPM设备漏洞分析

03

漏洞分析CVE-2023-36717

该漏洞是一个拒绝服务漏洞,当这个漏洞被触发时会导致宿主机vmsp.exe进程进入死循环,并占用大量CPU计算资源。由于vmsp.exe进程是IUM进程,所以当漏洞被触发后,管理员无法从用户态结束掉这个进程,这种情况下除非重启宿主机操作系统否则计算资源一直无法被释放。

这个漏洞位于TpmEngUM!TPM2_ECDH_KeyGen函数中。

__int64 __fastcall TPM2_ECDH_KeyGen(unsigned int *a1, __int64 a2){  OBJECT *v3; // rax  OBJECT *v4; // rsi  unsigned int v5; // eax  unsigned int v6; // ebx  unsigned __int16 v8[28]; // [rsp+20h] [rbp-58h] BYREF  v3 = ObjectGet(*a1);  v4 = v3;  if ( v3->public_type != 0x23    || (v3->public_objectAttributes & 0x10000) != 0    || (v3->public_objectAttributes & 0x20000) == 0 )  {    return 0x19Ci64;  }  while ( !(unsigned __int16)cpri__GetEphemeralEcc(                               (unsigned __int16 *)(a2 + 104),                               v8,                               v4->public_parameters_Detail_keyBits) )  {    *(_WORD *)(a2 + 0x66) = TPMS_ECC_POINT_Marshal((_BYTE *)(a2 + 104), 0i64, 0i64);    v5 = CryptEccPointMultiply(           (_WORD *)(a2 + 2),           v4->public_parameters_Detail_keyBits,           v8,           (__int64)&v4->public_unique_ecc_x);    v6 = v5;    if ( v5 == 0xA7 )      break;    if ( v5 != 0x154 )      goto LABEL_9;  }  v6 = 156;LABEL_9:  if ( !v6 )    *(_WORD *)a2 = TPMS_ECC_POINT_Marshal((_BYTE *)(a2 + 2), 0i64, 0i64);  return v6;}

TpmEngUM!TPM2_ECDH_KeyGen函数中v4->public_unique_ecc_x成员可以从Guest中被控制,如果v4->public_unique_ecc_x成员是一个NULL ECC Point的情况下TPM2B_ECC_PARAMETER.size为0x00,并且TPM2B_ECC_PARAMETER.buffer数组被0填充),TpmEngUM!CryptEccPointMultiply会一直返回错误码0x154,并不停的循环调用TpmEngUM!CryptEccPointMultiply函数,最终造成vmsp.exe进程死循环,导致宿主机拒绝服务。

04

漏洞分析CVE-2023-36718

该漏洞是远程代码执行漏洞,当这个漏洞被触发时会使用未初始化的栈空间变量。这个漏洞位于TpmEngUM!CryptSecretEncrypt函数中。

__int64 __fastcall CryptSecretEncrypt(unsigned int a1, _BYTE *a2_plabel, __int64 a3, __int16 *a4){  unsigned int v7; // ebx  OBJECT *v8_obj; // rax  OBJECT *v9_obj; // rdi  unsigned __int16 DigestSize; // ax  unsigned __int16 public_parameters_Detail_keyBits; // cx  __int16 public_nameAlg; // cx  void *v14; // [rsp+40h] [rbp-C0h] BYREF  __int16 v15[28]; // [rsp+48h] [rbp-B8h] BYREF  __int16 v16[56]; // [rsp+80h] [rbp-80h] BYREF  __int16 v17_Z_eccpointaftermul[56]; // [rsp+F0h] [rbp-10h] BYREF  v7 = 0;  v8_obj = ObjectGet(a1);  v9_obj = v8_obj;......  DigestSize = cpri__GetDigestSize(v8_obj->public_nameAlg);  *(_WORD *)a3 = DigestSize;......  if ( v9_obj->public_type == 1 )  {......  }  else  {    if ( v9_obj->public_type != 0x23 )    {......    }    public_parameters_Detail_keyBits = v9_obj->public_parameters_Detail_keyBits;    v14 = a4 + 1;    if ( (unsigned int)cpri__EccIsPointOnCurve(                         public_parameters_Detail_keyBits,                         (__int64)&v9_obj->public_unique_ecc_x) )    {      cpri__GetEphemeralEcc((unsigned __int16 *)v16, (unsigned __int16 *)v15, v9_obj->public_parameters_Detail_keyBits);      *a4 = TPMS_ECC_POINT_Marshal(v16, &v14, 0i64);      if ( (unsigned int)CryptEccPointMultiply(                           v17_Z_eccpointaftermul,                           v9_obj->public_parameters_Detail_keyBits,                           (unsigned __int16 *)v15,                           (__int64)&v9_obj->public_unique_ecc_x) )      {        v7 = 0x9C;      }      else if ( BitIsSet((unsigned __int16)v9_obj->public_nameAlg, (__int64)&g_toTest, 9u) )      {        public_nameAlg = v9_obj->public_nameAlg;        if ( public_nameAlg != 0x10 )          TestAlgorithm(public_nameAlg, 0i64);      }      cpri__KDFe(        v9_obj->public_nameAlg,        (unsigned __int16 *)v17_Z_eccpointaftermul,        a2_plabel,        (unsigned __int16 *)v16,        (unsigned __int16 *)&v9_obj->public_unique_ecc_x,        8 * *(unsigned __int16 *)a3,        (_BYTE *)(a3 + 2));    }    else    {      return 0x9C;    }  }  return v7;}

上面代码中的v17_Z_eccpointaftermul是一个栈上的数组(也可能是个结构体),v17_Z_eccpointaftermul的大小是0x70字节。代码中的v9_obj->public_unique_ecc_x成员可以从Guest中被控制,当v9_obj->public_unique_ecc_x成员是一个NULL ECC Point的情况下(TPM2B_ECC_PARAMETER.size为0x00,并且TPM2B_ECC_PARAMETER.buffer数组被0填充),TpmEngUM!CryptEccPointMultiply函数会返回一个错误码并将v7设置为0x9C。

设置完v7的值之后,程序继续走到要调用TpmEngUM!cpri__KDFe函数这里,此时v17_Z_eccpointaftermul是一个栈上未初始化的数组,并作为TpmEngUM!cpri__KDFe函数的第二参数进入到之后的TpmEngUM!cpri__KDFe函数的代码流程里。

TpmEngUM!cpri__KDFe函数后续的代码流程中,使用了未初始化的栈上的数据,导致越界读或者内存损坏。下面是崩溃时的现场:

(4afc.2f4c): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.TpmEngUM!SymCryptSha512AppendBlocks_ull+0xa7:00007ffb`38d9a42f 4d8b41f0        mov     r8,qword ptr [r9-10h] ds:00000000`00153ffe=????????????????0:000> k # Child-SP          RetAddr           Call Site00 00000000`0014ec80 00007ffb`38d99e01 TpmEngUM!SymCryptSha512AppendBlocks_ull+0xa701 00000000`0014eed0 00007ffb`38d99e59 TpmEngUM!SymCryptSha512Append+0x9502 00000000`0014ef10 00007ffb`38d87724 TpmEngUM!SymCryptSha384Append+0x903 00000000`0014ef40 00007ffb`38d66cd7 TpmEngUM!cpri__KDFe+0x1a404 00000000`0014f110 00007ffb`38d7c7cd TpmEngUM!CryptSecretEncrypt+0x14305 00000000`0014f2c0 00007ffb`38d70a54 TpmEngUM!TPM2_MakeCredential+0x7d06 00000000`0014f340 00007ffb`38d61c54 TpmEngUM!CommandDispatcher+0xa7807 00000000`0014f420 00007ffb`38d61313 TpmEngUM!ExecuteCommand+0x46008 00000000`0014f530 00000001`400c3862 TpmEngUM!VTpmExecuteCommand+0x73
05

总 结

借助此文简单的介绍了下Hyper-V虚拟TPM组件的两个漏洞,可以发现这两个漏洞都是Hyper-V虚拟TPM组件在处理Guest数据时发生了错误导致宿主机进程受到了影响。通过本文帮助读者更好地理解虚拟TPM组件漏洞的成因,以及希望能够在TPM组件的漏洞挖掘工作中帮到大家。

【版权说明】

本作品著作权归HongZhenhao所有

未经作者同意,不得转载。

Microsoft Hyper-V虚拟TPM设备漏洞分析
HongZhenhao

天工实验室安全研究员

专注于Windows、云、虚拟化领域漏洞挖掘。

曾多次获得微软 MSRC 最高漏洞赏金,荣登2019,2020,2022 微软MSRC全球最具价值安全精英榜。连续两年BlackHat USA世界黑帽大会Speaker。

Microsoft Hyper-V虚拟TPM设备漏洞分析

原文始发于微信公众号(破壳平台):Microsoft Hyper-V虚拟TPM设备漏洞分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月17日00:52:51
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Microsoft Hyper-V虚拟TPM设备漏洞分析http://cn-sec.com/archives/2151900.html

发表评论

匿名网友 填写信息