New issue
Advanced search Search tips
Starred by 2 users
Status: Fixed
Owner:
Closed: Jun 13
Cc:



Sign in to add a comment
Windows Kernel stack memory disclosure in exception handling (nt!KiDispatchException)
Project Member Reported by mjurczyk@google.com, Mar 10 2017 Back to list
According to our tests, the generic exception dispatching code present in the Windows kernel (Windows 7-10) discloses portions of uninitialized kernel stack memory to user-mode clients via the CONTEXT structure set up for the ring-3 exception handlers.

The attached proof-of-concept program can be used to reproduce the issue. It works by first spraying a full page of the kernel stack with a 0x41 byte ('A') using the nt!NtMapUserPhysicalPages system call (see [1]), then also spraying a page of user-mode stack (to recognize any false-positives) with a 0x78 ('x') byte, followed by raising an exception with a RaiseException() call and dumping the contents of the CONTEXT structure provided to the unhandled exception filter function. After running the program, we should observe the 'A' byte on output in place of disclosed kernel memory.

On most tested platforms (Windows 7 64-bit, Windows 10 32/64-bit), running the 32-bit proof-of-concept program reveals 4 bytes of kernel stack memory at offset 0x88 of the structure. An example output is as follows:

--- cut ---
00000000: 7f 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 7f 02 00 00 ................
00000020: 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00[41 41 41 41]2b 00 00 00 ........AAAA+...
00000090: 53 00 00 00 2b 00 00 00 2b 00 00 00 50 fe 32 00 S...+...+...P.2.
000000a0: 84 fd 32 00 00 e0 fd 7e 00 00 00 00 85 3c 1d 59 ..2....~.....<.Y
000000b0: 1c fd 32 00 6c fd 32 00 4f c5 72 75 23 00 00 00 ..2.l.2.O.ru#...
000000c0: 46 02 00 00 1c fd 32 00 2b 00 00 00 7f 02 00 00 F.....2.+.......
000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000e0: 00 00 00 00 80 1f 00 00 ff ff 00 00 00 00 00 00 ................
000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002c0: 00 00 00 00 00 00 00 00 00 00 00 00 ?? ?? ?? ?? ................
--- cut ---

Offset 0x88 of the CONTEXT structure on x86 corresponds to the 32-bit CONTEXT.FloatSave.Cr0NpxState field, which appears to remain in an uninitialized state before being copied to user-mode. We have tested that with the kernel stack spraying disabled, these bytes contain varying values originating from the kernel memory space.

On Windows 7 32-bit, we're observing a slightly different output:

--- cut ---
00000000: 7f 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000010: 00 00 00 00 00 00 00 00 00 00 00 00 7f 02 00 00 ................
00000020: 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 ................
00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000090: 3b 00 00 00 23 00 00 00 23 00 00 00 0c fe 2a 00 ;...#...#.....*.
000000a0: 40 fd 2a 00 00 f0 fd 7f 74 6c 8e 77 89 bb c8 38 @.*.....tl.w...8
000000b0: d8 fc 2a 00 28 fd 2a 00 5d 84 c3 75 1b 00 00 00 ..*.(.*.]..u....
000000c0: 46 02 00 00 d8 fc 2a 00 23 00 00 00 7f 02 00 00 F.....*.#.......
000000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000e0: 00 00 00 00 80 1f 00 00 ff ff 00 00 00 00 00 00 ................
000000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002a0: 00 00 00 00 00 00 00 00 00 00 00 00 41 41 41 41 ............AAAA
000002b0: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
000002c0: 41 41 41 41 41 41 41 41 41 41 41 41 ?? ?? ?? ?? AAAAAAAAAAAA....
--- cut ---

Here, we can see that 32 bytes from the kernel stack are leaked at the end of the CONTEXT structure, which correspond to the last bytes of the CONTEXT.ExtendedRegisters array. We have confirmed that when the spraying function is not invoked, this memory region discloses valid kernel-mode pointers.

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.

References:
[1] nt!NtMapUserPhysicalPages and Kernel Stack-Spraying Techniques, http://j00ru.vexillium.org/?p=769
 
RaiseException.cpp
1.8 KB View Download
Project Member Comment 1 by mjurczyk@google.com, Mar 16 2017
Labels: Reported-2017-Mar-16
Project Member Comment 2 by mjurczyk@google.com, Mar 20 2017
Labels: MSRC-37783
Project Member Comment 3 by mjurczyk@google.com, May 20 2017
Labels: CVE-2017-8482
Project Member Comment 4 by mjurczyk@google.com, Jun 13
Labels: Fixed-2017-Jun-13
Status: Fixed
Fixed in today's Patch Tuesday.
Project Member Comment 5 by mjurczyk@google.com, Jun 20
Labels: -restrict-view-commit
Sign in to add a comment