Skip to content
November 8, 2016 / Rafal Wojtczuk

Thoughts on the recent “NtSetWindowLongPtr” vulnerability

On October 31, Google security team has announced it has discovered a vulnerability, actively exploited the wild, in (unspecified) versions of Microsoft Windows. The vulnerability is a local privilege escalation, allowing an unprivileged user to gain kernel privileges. The original advisory is here.

On November 1, Alex Ionescu posted on his blog some remarks (here and here) about the nature of the vulnerability.

No public exploit code is known at the time; the information mentioned above is not sufficient for the author to reproduce the vulnerability. Still, some details can be deduced:

  • One of the exploitation steps is issuing the win32k NtUserSetWindowLongPtr syscall, in order to set one of the field (“spmenu”) in the kernel data structure describing a window.
  • The “spmenu” field semantics is different depending on the style of the window. If the window has WS_CHILD attribute, “spmenu” stores menu id, and kernel allows to set it to an arbitrary value. Without WS_CHILD attribute, “spmenu” is a pointer to kernel data structures.
  • Generally, kernel code is careful to use the “spmenu” field properly. Particularly, when changing the windows style from WS_CHILD to non-WS_CHILD, the “spmenu” field is reset to 0, to prevent referencing arbitrary pointer.
  • Apparently, under unspecified conditions, it is possible to force the kernel to treat “spmenu” as trusted pointer, which likely results in arbitrary code execution in kernel context.

Again, the vulnerability is a local privilege escalation, meaning attacker needs to be able to run arbitrary code on the victim machine. Still, it seems that attacker needs very limited privileges (just the ability to issue win32k syscalls) to run an exploit. In the Google announcement, the possibility to break from a sandbox is explicitly mentioned. Interestingly, a vulnerability in Adobe Flash was discovered in the wild at the same time.

Thus, attacker used the following steps:

  1. Entice the victim to open in a browser a webpage containing browser exploit code.
  2. Use the browser exploit (based on Flash vulnerability or anything else) and achieve arbitrary code execution. In most cases, the code will run in a sandbox, with limited privileges.
  3. Use the kernel vulnerability to get full control over the machine.

A very interesting question is which sandboxes can be breached via NtSetWindowsLong vulnerability? Without the full knowledge of the vulnerability internals, we cannot
be sure but we can make educated guesses. The following cases are most likely affected, because there are no restrictions on using win32k syscalls in the respective sandbox:

  • Chrome browser on Windows 7
  • Internet Explorer
  • Edge before Windows 10 1607 (aka “anniversary update”)

Chrome browser on Windows 8 and 10 is not affected. When running on these OS’s, Chrome sandbox uses the “win32k lockdown” mechanism, that forbids issuing any win32k system calls, thus mitigating the vulnerability.

The most interesting case is Edge on Windows 10 1607. In this case, the sandbox does not block all win32k system calls. Instead, only some of them are filtered out, as described in MS presentation on Windows 10 mitigations. Particularly, the NtuserSetlongptr syscall is not blocked; therefore, Edge sandbox on Windows 10 1607 is likely affected.

This particular vulnerability is unusual mostly because it was announced before a patch was available (the patch is expected to be available on regular Patch Tuesday, today, November 8). In fact, win32k vulnerabilities are common; until November, this year there were 31 CVE items related to win32k mentioned in Microsoft security bulletins. It is expected – win32k driver is huge, exposing broad interface to the potentially malicious usermode.

So far, only Chrome browser uses full win32k lockdown. Still, it does not protect against other (not in win32k driver) kernel vulnerabilities – while much less frequent, they do happen.

In order to get mitigation against all kernel vulnerabilities, for many more applications, we need another layer of isolation. Hypervisor-based technology helps with that. If we run malicious code in VM, then even if the former achieves kernel privileges, then still the VM can contain the malware. Even though hypervisor itself can potentially have bugs as well, the attack surface of a well-written hypervisor is way smaller than the attack surface of Windows kernel.

Bromium vSentry isolates each supported application in a VM, and therefore breakouts from sandboxes via Windows kernel vulnerabilities are of little concern for vSentry users.

%d bloggers like this: