首页
社区
课程
招聘
[原创]Hyper-V拒绝服务漏洞CVE-2024-43633分析
发表于: 2小时前 295

[原创]Hyper-V拒绝服务漏洞CVE-2024-43633分析

王cb 活跃值
11
2小时前
295

引用

这篇文章的目的是介绍今年11月发布的的Hyper-V拒绝服务漏洞CVE-2024-43633分析.

目录

简介

文章结合了逆向代码和调试结果分析了CVE-2024-43633漏洞利用过程和漏洞成因.

复现环境

Win11 23h2

Win11 22h2

CVE-2024-43633漏洞分析

CVE-2024-43633是笔者今年7月向微软MSRC提交的Hyper-V拒绝服务漏洞,漏洞可在Win11 23h2上复现,漏洞致谢发布于11月,漏洞的成因主要存在于Hyper-V根分区的vmbusr.sys驱动未正确处理虚拟机重置后vmbus通道分区的引用与解引用次数不一致导致触发内核崩溃断言的拒绝服务结果.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
00 ffffcd04`0d0d7460 fffff800`872daeef     vmbusr!ChDereferenceChannelInternal+0x9c
01 ffffcd04`0d0d7490 fffff800`872b5173     vmbusr!ChServerChannelReleasedByClientLocked+0x57
02 ffffcd04`0d0d74c0 fffff800`872da012     vmbusr!ChpPartitionWaitChannelClosed+0xc7
03 ffffcd04`0d0d7500 fffff800`872d8c87     vmbusr!ChResetPartition+0x3e
void __fastcall ChDereferenceChannelInternal(__int64 a1, int a2, __int16 a3)
{
 IoQueueWorkItem(
        ChLocalOfferRemoveWorkItem,
        (PIO_WORKITEM_ROUTINE)ChDestroyChannelWorkItem,
        DelayedWorkQueue,
        0i64);
 
}
void __fastcall ParentReleaseInterruptResources(PVOID Channel)
{
//这里也会调用 XPartDeref
 XPartDeref(Channel);
}
void __fastcall ChpDestroyChannel(PVOID P)
{
  XPartDeref(*((_QWORD *)P + 26));
}
//通道析构时会对分区会加引用一次解引用三次
void __fastcall ChDestroyChannelWorkItem(PDEVICE_OBJECT DeviceObject, PVOID Context)
{
//加引用一次
 _InterlockedIncrement64((volatile signed __int64 *)(Channel + 0x88)) <= 1
//call ChDereferenceChannelInternal and ParentReleaseInterruptResources
ChpDestroyChannel(Channel);
 XPartDeref(Channel);
}
void __fastcall XPartDeref(__int64 Channel)
{
  signed __int64 v1; // rax
  bool v2; // cc
  signed __int64 v3; // rax
  //+0x88是引用计数字段
  v1 = _InterlockedExchangeAdd64((volatile signed __int64 *)(Channel + 0x88), 0xFFFFFFFFFFFFFFFFui64);
  v2 = v1 <= 1;
  v3 = v1 - 1;
  if ( v2 )
  {
  //
  导致最后的引引用次数会变成负数-1
    if ( v3 )
      __fastfail(0xEu); 
  }
}

当运行在虚拟机中的程序通过hypercall类型HvCallPostMessage向运行在Hyper-V根分区的vmbus通道提供程序Virtualization Service Providers (VSP)发送CHANNELMSG_INITIATE_CONTACT消息后,vmbusr.sys驱动为将要创建的vmbus通道创建一个新的vmbus通道分区XPart分配给虚拟机,在这之前虚拟机启动时自带的vmbus服务已经向vsp申请过分区,每个分区独立管理它所属的通道互相并不冲突,所有创建的通道通过一个链表结构维护在win11 23h2的虚拟机上下文偏移量为XPart+3b8,所有可以连接的通道必须是在Hyper-V根分区通过vmbus api向vmbusr.sys驱动申请分配的,一般是hyper-v集成服务的系统保留通道,或者是host端调用vmbuspiper.dll的api手动申请的通道,所有通道的CLASSID和INSTANCEID会在CHANNELMSG_OFFERCHANNEL回调sint消息中在synic_message页面通知虚拟机中的Virtualization Service Consumers(vsc)程序,之后vsc可以创建并映射gpadl共享页面和vsp建立vmbus通道通信,具体细节可以参考笔者之前的vmbus通道相关文章,复现此漏洞并不需要产生实际的通道通信,只需要建立通道并在uefi程序中调用__fastfail触发重置虚拟机就能复现漏洞,笔者使用的通道是hyper-v自带的集成服务Hyper-V Data Exchange Service (KVP)通道默认配置下启用可以复现,在默认情况下不管的通道的建立还是创建通信或者是销毁通道的相关操作引用与解引用次数都是对称的,当vsc客户端发送CHANNELMSG_GPADL_TEARDOWN和CHANNELMSG _CLOSECHANNEL消息以触发与通道关联的资源被释放时,通常会对通道进行解引用,当通道的解引用次数降为0后会调用通道销毁例程,在销毁例程会解引用通道所在的分区,分区的解引用次数降为0后会调用分区销毁例程,直到完成整个虚拟机资源释放,这里有个检查是当分区的解引用次数降为0继续解引用,这个引用次数会变成负数-1导致进入内核崩溃断言__fastfail的拒绝服务结果.一般情况下虚拟机退出时分区销毁例程调用完成后引用次数解引用为0,导致这个现象出现只存在于虚拟机重置后对分区的复用这个不安全的调用中,在win11 23h2及以下的版本中虚拟机重置后所有分配的分区并没有真正的销毁,也就是说没有移出虚拟机对象的分区链表,而是再次复用并调用一次多余的解引用,导致分区的引用与解引用次数不一致,在虚拟机重置恢复运行后这个复用的分区再次分配给虚拟机资源,但这些重新分配的分区和通道引用计数还是正常的受影响的还是那一次多余的解引用,当关闭虚拟机时所有的引用析构后这多余的一次解引用会将分区引用次数会变成负数-1导致拒绝服务.而在win11 24h2版本中虚拟机重置后所有分配的分区自动析构所有相关联对象并移出链表,这样就不存在复用和多余的解引用漏洞,因此笔者的漏洞不能在win11 24h2版本中复现.下面我们通过逆向代码了解一下漏洞的成因.

CVE-2024-43633漏洞逆向分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//在win11 23h2逆向代码
00 ffffbb0f`5a82ee30 fffff803`3e0b888b     vmbusr!XPartDeref+0x11
01 ffffbb0f`5a82ee60 fffff803`3e0d7f62     vmbusr!XPartRemovePartition+0x1bb
02 ffffbb0f`5a82eec0 fffff803`3e0d6bb7     vmbusr!ChResetPartition+0x5e
03 ffffbb0f`5a82eef0 fffff803`3e0aea6a     vmbusr!RootIoctlVdevReset+0xe3
04 ffffbb0f`5a82ef30 fffff803`26dfe7b8     vmbusr!RootIoctlDeviceControlPreprocess+0xea
//虚拟机重置会调用,关闭虚拟机也会调用
void __fastcall XPartRemovePartition(LIST_ENTRY *SubPartcreated, __int64 a2, __int64 a3)
{
bool __fastcall XPartIsSubPartition(__int64 a1)
{
  return *(_QWORD *)(a1 + 0x4F0) != 0i64;
}
  if ( SubPartcreated.SubPartition_4f0 )
  {
    if ( prevpartitionlinkptr )
      goto pengding;
  }
  else if ( prevpartitionlinkptr )
  {
    // (SubPart + 8)+0,prevpartitionlinkptr
    if ( prevpartitionlinkptr->Blink != SubPartcreated
      || (prevpartitionlinkptrnext = SubPartcreated->Blink, prevpartitionlinkptrnext->Flink != SubPartcreated) )
    {
LABEL_12:
      __fastfail(3u);
    }
    prevpartitionlinkptrnext->Flink = prevpartitionlinkptr;
    prevpartitionlinkptr->Blink = prevpartitionlinkptrnext;
    SubPartcreated->Flink = 0i64;
  }
  pengding:
  ...
  //解引用
   XPartDeref((__int64)SubPartcreated);
}
 
//在win11 24h2逆向代码
void __fastcall XPartRemovePartition(LIST_ENTRY *thispart, __int64 a2, __int64 a3)
{
if ( thispart->Flink )
  {
    // removeentryPLIST_ENTRY
    if ( thisFlink->Blink != thispart )
      goto LABEL_13;
    thisBlink = thispart->Blink;
    if ( thisBlink->Flink != thispart )
      goto LABEL_13;
    thisBlink->Flink = thisFlink;
    thisFlink->Blink = thisBlink;
  }
   }
  // +378parentpart
  // bool __fastcall XPartIsSubPartition(__int64 a1)
  // {
  //   return *(_QWORD *)(a1 + 0x378) != 0i64;
  // }
  parentpart = thispart[0x37].Blink;
  if ( parentpart )
  {
    linkpart368ptr = (_LIST_ENTRY *)((char *)parentpart + 0x368);
    linkpart368ptrFlink = linkpart368ptr->Flink;
    if ( linkpart368ptr->Flink->Blink == linkpart368ptr )
    {
      thispart->Flink = linkpart368ptrFlink;
      thispart->Blink = linkpart368ptr;
      linkpart368ptrFlink->Blink = thispart;
      linkpart368ptr->Flink = thispart;
      goto pendging;
    }
LABEL_13:
    __fastfail(3u);
  }
  pengding:
  ...
  //解引用
   XPartDeref((__int64)SubPartcreated);
}

通过上面的逆向代码可以看出在win11 23h2版本中与虚拟机重置后移除分区的逻辑如果要移除分区SubPartition_4f0是个有效的指针,会直接跳出if和else代码块,并没有进入后面的else分支将当前分区没有移出分区链表,导致虚拟机重置后时会再次调用这个函数对复用的分区再次分配给虚拟机,并再次调用XPartDeref多解引用一次导致分区的引用与解引用次数不一致.而在win11 24h2中XPartRemovePartition直接将当前分区移出链表尽管有对子分区的判断,但是因为分区已经被移出链表了,就不存在复用的情况,自然也不存在多余的解引用漏洞.

CVE-2024-43633漏洞调试分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//先下断点
3: kd>bp  vmbusr!XPartDeref; ba w1 rcx+88  " r;k;r $t1=rcx+3b8;r $t2=$t1; dc $t2-3b8+88;r $t1=poi($t1); .for(r $t3=0;$t1 > $t2 or $t1 < $t2;r $t3=$t3+1){r $t1=poi($t1); };.printf \"%p Channel count %p\r\n\",$t2-3b8+88, $t3;gc"
 
//正常析构时分区引用次数为通道的数量*2次引用次数数加上分区本身的一次引用1e=e*2+1+1
rax=ffffe60151627928 rbx=ffffe60151627850 rcx=000000000000001d
rdx=ffffe60151627928 rsi=ffffe6014ff9c0e8 rdi=ffffe6015125a000
rip=fffff8033e0b1a76 rsp=ffffbb0f55517200 rbp=0000000000000000
 r8=fffff8033e0c6780  r9=ffffe60151627928 r10=fffff8033e0b1a20
r11=0000000000000000 r12=ffffe6012e9f43b0 r13=ffffe6012ff8d000
r14=fffff8033e0b1a20 r15=fffff80322403980
iopl=0         nv up ei pl nz na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040206
vmbusr!ChDestroyChannelWorkItem+0x56:
fffff803`3e0b1a76 48ffc1          inc     rcx
 # Child-SP          RetAddr               Call Site
00 ffffbb0f`55517200 fffff803`22403a80     vmbusr!ChDestroyChannelWorkItem+0x56
01 ffffbb0f`55517250 fffff803`22552315     nt!IopProcessWorkItem+0x100
02 ffffbb0f`555172c0 fffff803`22554d07     nt!ExpWorkerThread+0x155
03 ffffbb0f`555174b0 fffff803`2261ae24     nt!PspSystemThreadStartup+0x57
04 ffffbb0f`55517500 00000000`00000000     nt!KiStartSystemThread+0x34
//分区引用计数
ffffe601`5125a088  0000001e 00000000 00050000 00050003  ................
ffffe601`5125a098  00000000 00000000 00000000 00000000  ................
ffffe601`5125a0a8  00000000 00000000 b0cad258 000019fe  ........X.......
ffffe601`5125a0b8  4fae8000 ffffe601 4ff8fd60 ffffe601  ...O....`..O....
ffffe601`5125a0c8  00020101 000002e0 00000000 00000000  ................
ffffe601`5125a0d8  00000000 00000000 4ea30000 ffffe601  ...........N....
ffffe601`5125a0e8  00000000 00000000 00000000 00000000  ................
ffffe601`5125a0f8  00000000 00000000 00000000 00000000  ................
//通道引用计数
ffffe6015125a088 Channel count 000000000000000e
 
//虚拟机重置后引用次数比正常少了1
rdx=0000000000000001 rsi=ffffe6014ea30000 rdi=0000000000000000
rip=fffff8033e0b7795 rsp=ffffbb0f5a82ee30 rbp=0000000000000000
 r8=ffffe6014e9c419c  r9=0000000000000014 r10=fffff8032245e560
r11=00000000000099b0 r12=0000000000000000 r13=0000000000000000
r14=ffffe6014e967b48 r15=ffffe601516760f0
iopl=0         nv up ei pl nz ac po cy
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040217
vmbusr!XPartDeref+0x11:
fffff803`3e0b7795 4883e801        sub     rax,1
 # Child-SP          RetAddr               Call Site
00 ffffbb0f`5a82ee30 fffff803`3e0b888b     vmbusr!XPartDeref+0x11
01 ffffbb0f`5a82ee60 fffff803`3e0d7f62     vmbusr!XPartRemovePartition+0x1bb
02 ffffbb0f`5a82eec0 fffff803`3e0d6bb7     vmbusr!ChResetPartition+0x5e
03 ffffbb0f`5a82eef0 fffff803`3e0aea6a     vmbusr!RootIoctlVdevReset+0xe3
04 ffffbb0f`5a82ef30 fffff803`26dfe7b8     vmbusr!RootIoctlDeviceControlPreprocess+0xea
05 ffffbb0f`5a82ef60 ffffe601`4dc4fb20     0xfffff803`26dfe7b8
06 ffffbb0f`5a82ef68 00000000`0000000e     0xffffe601`4dc4fb20
//分区引用计数
ffffe601`5125a088  0000001d 00000000 00050000 00050003  ................
ffffe601`5125a098  00000000 00000000 00000000 00000000  ................
ffffe601`5125a0a8  00000000 00000000 b0cad258 000019fe  ........X.......
ffffe601`5125a0b8  4fae8000 ffffe601 4ff8fd60 ffffe601  ...O....`..O....
ffffe601`5125a0c8  00020101 000002e0 00000000 00000000  ................
ffffe601`5125a0d8  00000000 00000000 4ea30000 ffffe601  ...........N....
ffffe601`5125a0e8  00000000 00000000 00000000 00000000  ................
ffffe601`5125a0f8  00000000 00000000 00000000 00000000  ................
//通道引用计数
ffffe6015125a088 Channel count 000000000000000e
 
//虚拟机关闭
rdx=ffffe601513a9701 rsi=ffffe6014ea30000 rdi=0000000000000000
rip=fffff8033e0b7795 rsp=ffffbb0f56f76dc0 rbp=ffffe6014e967a00
 r8=000000000000054b  r9=0000000000000000 r10=fffff8032245e560
r11=000000000000a5b0 r12=fffff8033e0c2100 r13=0000000000000000
r14=0000000000000000 r15=ffffe60147a57760
iopl=0         nv up ei pl nz na po cy
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040207
vmbusr!XPartDeref+0x11:
fffff803`3e0b7795 4883e801        sub     rax,1
 # Child-SP          RetAddr               Call Site
00 ffffbb0f`56f76dc0 fffff803`3e0b888b     vmbusr!XPartDeref+0x11
01 ffffbb0f`56f76df0 fffff803`3e0b9073     vmbusr!XPartRemovePartition+0x1bb
02 ffffbb0f`56f76e50 fffff803`3e0b8843     vmbusr!ParentCleanupPartition+0x73
03 ffffbb0f`56f76e80 fffff803`3e0d69c1     vmbusr!XPartRemovePartition+0x173
04 ffffbb0f`56f76ee0 fffff803`3e0aea4d     vmbusr!RootIoctlVdevPowerOff+0x12d
05 ffffbb0f`56f76f30 fffff803`26dfe7b8     vmbusr!RootIoctlDeviceControlPreprocess+0xcd
06 ffffbb0f`56f76f60 ffffe601`4ed13de0     0xfffff803`26dfe7b8
07 ffffbb0f`56f76f68 00000000`0000000e     0xffffe601`4ed13de0
//分区引用计数
ffffe601`5125a088  00000010 00000000 00050000 00050003  ................
ffffe601`5125a098  00000000 00000000 00000000 00000000  ................
ffffe601`5125a0a8  00000000 00000000 b0cad258 000019fe  ........X.......
ffffe601`5125a0b8  4fae8000 ffffe601 4ff8fd60 ffffe601  ...O....`..O....
ffffe601`5125a0c8  00020101 000002e0 00000000 00000000  ................
ffffe601`5125a0d8  00000000 00000000 4ea30000 ffffe601  ...........N....
ffffe601`5125a0e8  00000000 00000000 00000000 00000000  ................
ffffe601`5125a0f8  00000000 00000000 00000000 00000000  ................
//通道引用计数
ffffe6015125a088 Channel count 0000000000000008
 
//导致最后的引引用次数会变成负数-1
rax=0000000000000000 rbx=ffffe6014e213960 rcx=ffffe6015125a000
rdx=0000000000000000 rsi=0000000000000000 rdi=ffffe6015125a000
rip=fffff8033e0b7795 rsp=ffffbb0f555171d0 rbp=0000000000000000
 r8=0000000000000000  r9=7ffffffffffffffc r10=fffff80322462170
r11=ffffe6014e213950 r12=ffffe6012e9f43b0 r13=ffffe6012ff8d000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei ng nz na po nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00040286
vmbusr!XPartDeref+0x11:
fffff803`3e0b7795 4883e801        sub     rax,1
 # Child-SP          RetAddr               Call Site
00 ffffbb0f`555171d0 fffff803`3e0b1b8c     vmbusr!XPartDeref+0x11
01 ffffbb0f`55517200 fffff803`22403a80     vmbusr!ChDestroyChannelWorkItem+0x16c
02 ffffbb0f`55517250 fffff803`22552315     nt!IopProcessWorkItem+0x100
03 ffffbb0f`555172c0 fffff803`22554d07     nt!ExpWorkerThread+0x155
04 ffffbb0f`555174b0 fffff803`2261ae24     nt!PspSystemThreadStartup+0x57
05 ffffbb0f`55517500 00000000`00000000     nt!KiStartSystemThread+0x34
//分区引用计数
ffffe601`5125a088  ffffffff ffffffff 00050000 00050003  ................
ffffe601`5125a098  00000000 00000000 00000000 00000000  ................
ffffe601`5125a0a8  00000000 00000000 b0cad258 000019fe  ........X.......
ffffe601`5125a0b8  4fae8000 ffffe601 4ff8fd60 ffffe601  ...O....`..O....
ffffe601`5125a0c8  00020101 000002e0 00000000 00000000  ................
ffffe601`5125a0d8  00000000 00000000 4ea30000 ffffe601  ...........N....
ffffe601`5125a0e8  00000000 00000000 00000000 00000000  ................
ffffe601`5125a0f8  00000000 00000000 00000000 00000000  ................
//通道引用计数
ffffe6015125a088 Channel count 0000000000000000 
 
//bsod
rax=ffffffffffffffff rbx=0000000000000000 rcx=000000000000000e
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
rip=fffff8033e0b77a5 rsp=ffffbb0f555171d0 rbp=0000000000000000
 r8=0000000000000000  r9=7ffffffffffffffc r10=fffff80322462170
r11=ffffe6014e213950 r12=0000000000000000 r13=0000000000000000
r14=0000000000000000 r15=0000000000000000
iopl=0         nv up ei ng nz na po nc
vmbusr!XPartDeref+0x21:
fffff803`3e0b77a5 cd29            int     29h
Resetting default scope
 
EXCEPTION_RECORD:  ffffbb0f55516f98 -- (.exr 0xffffbb0f55516f98)
ExceptionAddress: fffff8033e0b77a5 (vmbusr!XPartDeref+0x0000000000000021)
   ExceptionCode: c0000409 (Security check failure or stack buffer overrun)
  ExceptionFlags: 00000001
NumberParameters: 1
   Parameter[0]: 000000000000000e
Subcode: 0xe FAST_FAIL_INVALID_REFERENCE_COUNT
 
PROCESS_NAME:  System
 
ERROR_CODE: (NTSTATUS) 0xc0000409 - <Unable to get error code text>
 
EXCEPTION_CODE_STR:  c0000409
 
EXCEPTION_PARAMETER1:  000000000000000e
 
EXCEPTION_STR:  0xc0000409
 
STACK_TEXT: 
ffffbb0f`55516508 fffff803`22767092     : ffffbb0f`55516670 fffff803`224bdda0 ffff9781`82511180 00000000`00000001 : nt!DbgBreakPointWithStatus
ffffbb0f`55516510 fffff803`22766753     : ffff9781`00000003 ffffbb0f`55516670 fffff803`2262fd20 00000000`00000139 : nt!KiBugCheckDebugBreak+0x12
ffffbb0f`55516570 fffff803`22615db7     : ffffe601`2b0ff040 00000000`00000000 ffffe601`4e213960 00000000`00000000 : nt!KeBugCheck2+0xba3
ffffbb0f`55516ce0 fffff803`2262bc29     : 00000000`00000139 00000000`0000000e ffffbb0f`55517040 ffffbb0f`55516f98 : nt!KeBugCheckEx+0x107
ffffbb0f`55516d20 fffff803`2262c1f2     : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : nt!KiBugCheckDispatch+0x69
ffffbb0f`55516e60 fffff803`22629edb     : 00000000`00040246 fffff803`2253f0b3 00000000`0000000c ffffe601`2e5f1180 : nt!KiFastFailDispatch+0xb2
ffffbb0f`55517040 fffff803`3e0b77a5     : ffffe601`4e213960 ffffe601`4e213960 00000000`00000002 00000000`00000680 : nt!KiRaiseSecurityCheckFailure+0x35b
ffffbb0f`555171d0 fffff803`3e0b1b8c     : ffffe601`4e213960 ffffe601`2b0c94a0 fffff803`22403980 fffff803`3e0b1a20 : vmbusr!XPartDeref+0x21
ffffbb0f`55517200 fffff803`22403a80     : ffffe601`2e9f43b0 00000000`00000000 ffffe601`47a58450 00000000`00000000 : vmbusr!ChDestroyChannelWorkItem+0x16c
ffffbb0f`55517250 fffff803`22552315     : ffffe601`2b0c94a0 ffffe601`2ff8c040 ffffbb0f`555173c0 00020000`00000000 : nt!IopProcessWorkItem+0x100
ffffbb0f`555172c0 fffff803`22554d07     : ffffe601`2ff8c040 00000000`000000d8 ffffe601`2ff8c040 fffff803`225521c0 : nt!ExpWorkerThread+0x155
ffffbb0f`555174b0 fffff803`2261ae24     : ffff9781`82511180 ffffe601`2ff8c040 fffff803`22554cb0 11ef5c6a`588718e0 : nt!PspSystemThreadStartup+0x57
ffffbb0f`55517500 00000000`00000000     : ffffbb0f`55518000 ffffbb0f`55511000 00000000`00000000 00000000`00000000 : nt!KiStartSystemThread+0x34

使用如上脚本下断点调试,从结合CVE-2024-43633漏洞分析逆向代码可以得出一个结论,当通道销毁例程ChDestroyChannelWorkItem被调用时分区会加引用一次解引用三次,所有当通道没有析构时分区的引用计数正常数值为它包含所有通道的数量乘以2次引用次数数加上分区本身的一次这个引用计数也就是通道Channel count*2+1,调试看到的是XPartDeref调用引用次数减1之前的计数,这个是没有析构之前正常的引用计数.在虚拟机重置后由于存在多余的解引用分区的引用计数比正常的引用计数少了1和正常的引用计数并不匹配,导致虚拟机关闭最后的一次解引用后引用次数会变成负数-1,进入bsod内核崩溃断言.

漏洞复现

笔者漏洞poc采用uefi程序复现,出于安全原因笔者不能提供完整的poc代码,下图是笔者在打了8月补丁的Win11 23h2物理机上成功复现了CVE-2024-43633

结论

CVE-2024-43633漏洞的复现过程重现了虚拟机重置后虚拟机vmbus通道和分区的引用计数不匹配导致了hyper-v宿主机崩溃bsod的过程.

相关引用

vmbus相关文章1

vmbus相关文章2

CVE-2024-43633致谢

参与贡献

作者来自ZheJiang Guoli Security Technology,邮箱cbwang505@hotmail.com


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2小时前 被王cb编辑 ,原因: 1
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//