The Microsoft Windows kernel suffers from a 64-bit pool memory disclosure vulnerability via REG_RESOURCE_REQUIREMENTS_LIST registry values.
2105a0202148dd8d1c7d110f3ebe6dc8
Windows Kernel 64-bit pool memory disclosure via REG_RESOURCE_REQUIREMENTS_LIST registry values
CVE-2018-0900
We have discovered a Windows kernel memory disclosure vulnerability through the contents of "FilteredConfigVector" registry values (of type REG_RESOURCE_REQUIREMENTS_LIST), which can be found under HKLM\SYSTEM\CurrentControlSet\Enum\ACPI\*\*\Control\FilteredConfigVector. The vulnerability affects 64-bit versions of Windows 7 to 10.
The leak was originally detected under the following stack trace (Windows 7):
--- cut ---
# RetAddr
00 fffff800`0295c064 nt!memcpy+0x3
01 fffff800`02970c81 nt!CmpQueryKeyValueData+0x3ae
02 fffff800`02971237 nt!CmEnumerateValueKey+0x211
03 fffff800`0268d093 nt!NtEnumerateValueKey+0x256
04 00000000`772abe6a nt!KiSystemServiceCopyEnd+0x13
--- cut ---
and more specifically in the copying of the CM_RESOURCE_LIST structure:
--- cut ---
kd> db rdx rdx+r8-1
fffff8a0`049d5314 a8 00 00 00 0f 00 00 00-00 00 00 00 00 00 00 00 ................
fffff8a0`049d5324 aa aa aa aa aa aa aa aa-aa aa aa aa 01 00 00 00 ................
fffff8a0`049d5334 01 00 01 00 04 00 00 00-01 80 03 00 00 00 00 00 ................
fffff8a0`049d5344 01 00 00 00 aa aa aa aa-aa aa aa aa aa aa aa aa ................
fffff8a0`049d5354 aa aa aa aa aa aa aa aa-01 01 01 80 11 00 00 00 ................
fffff8a0`049d5364 01 00 00 00 01 00 00 00-60 00 00 00 00 00 00 00 ........`.......
fffff8a0`049d5374 60 00 00 00 00 00 00 00-01 01 01 80 11 00 00 00 `...............
fffff8a0`049d5384 01 00 00 00 01 00 00 00-64 00 00 00 00 00 00 00 ........d.......
fffff8a0`049d5394 64 00 00 00 00 00 00 00-01 02 01 80 01 00 00 00 d...............
fffff8a0`049d53a4 01 00 00 00 01 00 00 00-00 00 00 00 00 00 00 00 ................
fffff8a0`049d53b4 00 00 00 00 00 00 00 00 ........
--- cut ---
In the above example, the 0xaa values at offsets 0x10-0x1b and 0x34-0x47 are uninitialized bytes originating from a pool allocation made in nt!PnpFilterResourceRequirementsList.
If we dive deeper into the layout of the memory area, we can see that the first block of 12 consecutive leaked bytes corresponds to the "Reserved" array inside the IO_RESOURCE_REQUIREMENTS_LIST structure:
--- cut ---
typedef struct _IO_RESOURCE_REQUIREMENTS_LIST {
ULONG ListSize;
INTERFACE_TYPE InterfaceType;
ULONG BusNumber;
ULONG SlotNumber;
ULONG Reserved[3];
ULONG AlternativeLists;
IO_RESOURCE_LIST List[1];
} IO_RESOURCE_REQUIREMENTS_LIST, *PIO_RESOURCE_REQUIREMENTS_LIST;
--- cut ---
This is illustrated below:
--- cut ---
kd> dt _IO_RESOURCE_REQUIREMENTS_LIST fffff8a0`049d5314
ntdll!_IO_RESOURCE_REQUIREMENTS_LIST
+0x000 ListSize : 0xa8
+0x004 InterfaceType : f ( PNPBus )
+0x008 BusNumber : 0
+0x00c SlotNumber : 0
+0x010 Reserved : [3] 0xaaaaaaaa
+0x01c AlternativeLists : 1
+0x020 List : [1] _IO_RESOURCE_LIST
kd> dx -r1 ((ntdll!unsigned long (*)[3])0xfffff8a0049d5324)
((ntdll!unsigned long (*)[3])0xfffff8a0049d5324) : 0xfffff8a0049d5324 [Type: unsigned long (*)[3]]
[0] : 0xaaaaaaaa [Type: unsigned long]
[1] : 0xaaaaaaaa [Type: unsigned long]
[2] : 0xaaaaaaaa [Type: unsigned long]
--- cut ---
The second block of 20 uninitialized bytes resides inside a IO_RESOURCE_DESCRIPTOR record of type CmResourceTypeConfigData (0x80). While the overall union inside IO_RESOURCE_DESCRIPTOR is 0x18 (24) bytes long, only the first 4 of them are used to store a 32-bit value 0x00000001. The remaining part remains unused and contains left-over data from previous allocations:
--- cut ---
kd> dt _IO_RESOURCE_DESCRIPTOR 0xfffff8a0049d533c
ntdll!_IO_RESOURCE_DESCRIPTOR
+0x000 Option : 0x1 ''
+0x001 Type : 0x80 ''
+0x002 ShareDisposition : 0x3 ''
+0x003 Spare1 : 0 ''
+0x004 Flags : 0
+0x006 Spare2 : 0
+0x008 u : <unnamed-tag>
kd> ?? sizeof(_IO_RESOURCE_DESCRIPTOR)
unsigned int64 0x20
kd> db 0xfffff8a0049d533c 0xfffff8a0049d533c+20-1
fffff8a0`049d533c 01 80 03 00 00 00 00 00-01 00 00 00 aa aa aa aa ................
fffff8a0`049d534c aa aa aa aa aa aa aa aa-aa aa aa aa aa aa aa aa ................
--- cut ---
We have verified that regular (non-admin) users have read access to the affected registry values, and thus may successfully exploit the vulnerability. We have also confirmed the bug by enabling the Special Pools mechanism for ntoskrnl.exe, and seeing repeated patterns of marker bytes when inspecting the FilteredConfigVector values in the default Windows Registry Editor (regedit.exe).
A proof-of-concept program is not provided for this issue, but it has been observed at normal system runtime, and is quite evident in the code.
Repeatedly triggering the vulnerability could allow local authenticated attackers to defeat certain exploit mitigations (kernel ASLR) or read other secrets stored in the kernel address space.
This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public.
Found by: mjurczyk