Hybrid View

Subtle information disclosure in WIN32K.SYS syscall return values

While performing some random research related to the WIN32K.SYS driver syscalls a few months ago, I stumbled on an interesting finding – when examining the full 32-bit (or in the case of the original research – 64) return values, some of the services seemed to return unusual numbers, for example 0xfffffa8000ea0000. After investigating the subject for a while, it turned out that a part of the WIN32K syscall interface indeed does not always return a value of the native CPU size (as opposed to the core NT kernel). Instead, some of the graphical services seem to be explicitly declared as:

Code:

VOID NtUserRandomService( ... )

or

Code:

USHORT NtUserRandomService( ... )

Funny enough to find such types of quirks in the Windows kernel, eh? A list of the flawed syscall names is as follows:

ETHREAD (full disclosure)

NtUserAlterWindowStyle

NtUserSetThreadState

NtUserNotifyWinEvent

NtUserModifyUserStartupInfoFlags

NtUserSetThreadLayoutHandles

NtUserNotifyIMEStatus

NtUserSetThreadLayoutHandles

NtUserSetRipFlags (Windows XP only)

NtUserSetDbgTag (Windows XP only)

ETHREAD (partial disclosure)

NtUserRegisterClassExWOW

NtUserGetKeyState

NtUserGetAsyncKeyState

NtUserVkKeyScanEx

NtUserSetWindowWord

NtUserSetClassWord

W32THREAD (full disclosure)

NtGdiEngUnlockSurface

NtGdiPATHOBJ_vEnumStartClipLines

NtGdiEngDeletePath

NtGdiEngDeleteClip

NtGdiFONTOBJ_vGetInfo

Other (unknown?)

NtGdiFlush

NtGdiEngUnlockSurface

The above list was created based on the Windows 7 64-bit graphical system call table, although I do not guarantee it is by any means complete (system calls might have been added, removed, or altered since then). As can be seen, a user-mode application is primarily able to read the addresses of two, internal kernel-mode structures (assigned to the currently executed thread, thus no serious information disclosure is going on, here). These are:

ETHREAD – the very standard NT kernel structure, assigned to every single thread running in the system,

W32THREAD – an internal, and pretty much unexplored structure, allocated on demand (i.e. when the thread calls a win32k service for the first time). For more details, you’re advised to take a look at the Mysteries of win32k & GDI post on the Woodmann RCE Forums.

In order to confirm the story a little, let’s take a look at the exemplary NtUserGetKeyState system call epilogue:

Clearly, the code doesn’t care about the upper 16 bits of the return value (leading to a partial disclosure) – that’s also the case for the rest of the aforementioned routines. A complete log from a Windows 7 64-bit instance of a Proof of Concept code follows:

Since the disclosed addresses do not pose a direct threat to the system security, the MSRC team did not consider the issue worth fixing. Well, although I do agree that it’s a minor issue, it is still amusing for me to find such peculiarities in the main Windows graphical kernel module No source code this time, although I do encourage you to fire your IDA and verify the findings by yourself (Windows WIN32K.SYS System Call Table might come in handy).

Take care!

PS. It seems that I wasn’t the only one coming across this matter – Tavis Ormandy has apparently tweeted about it a year ago, as well Nice one.

PS2. I received the first, valid submission for Pimp CrackMe – a reversing challenge by Gynvael and me (see: link). Well done!