# CVE-2019-1458: Windows win32k uninitialized variable in task switching
*Maddie Stone, Project Zero (Originally posted on [Project Zero blog](https://googleprojectzero.blogspot.com/p/rca.html) 2020-07-27)*

## The Basics

**Disclosure or Patch Date:** 10 December 2019

**Product:** Microsoft Windows

**Advisory:** https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-1458 

**Affected Versions:**

* For Windows 10 1607 x64, [KB4525236](https://support.microsoft.com/en-us/help/4525236/windows-10-update-kb4525236) and previous
* For Windows 7 x64, [KB4525233](https://support.microsoft.com/en-us/help/4525233/windows-7-update-kb4525233) and previous

**First Patched Version:**

* For Windows 10 1607 x64, [KB4530689](https://support.microsoft.com/en-us/help/4530689/windows-10-update-kb4530689)
* For Windows 7 x64, [KB4530692](https://support.microsoft.com/en-us/help/4530692/windows-7-update-kb4530692)

**Issue/Bug Report:** N/A

**Patch CL:** N/A

**Bug-Introducing CL:** N/A

**Reporter(s):** Anton Ivanov and Alexey Kulaev of Kaspersky Lab (Thanks to Kaspersky Lab and [@florek_pl](https://twitter.com/florek_pl) for sharing detailed analyses!)

## The Code

**Proof-of-concept:** https://github.com/piotrflorczyk/cve-2019-1458_POC

**Exploit sample:** N/A

**Did you have access to the exploit sample when doing the analysis?** No

## The Vulnerability

**Bug class:** Uninitialized variable

**Vulnerability details:**

Piotr Florczyk (@florek_pl) did a [full root cause analysis and published it with a proof-of-concept (POC)](https://github.com/piotrflorczyk/cve-2019-1458_POC). 

The bug is that a field, `\*(gpsi + 0x154)`, in a global structure, `tagSERVERINFO`, which defines information about system windows for the operating system, is uninitialized. This then permits a user-space application to set extra window data in the task-switch window (`FNID_SWITCH`, 0x280), which is usually only able to be set by the kernel. This extra window data is a pointer which is then dereferenced and written to. This gives a limited write primitive to an arbitrary memory address.

**Patch analysis:** N/A

**Thoughts on how this vuln might have been found _(fuzzing, code auditing, variant analysis, etc.)_:**

`SetWindowLongPtr` bugs have been very prevalent over the years. Therefore, I think it would be quite easy for a skilled researcher to identify through manual reverse engineering/auditing that the FNID_SWITCH field in gpsi was initially uninitialized and then follow the code path through to see that that would permit the attacker-controlled pointer dereference. Due to the different conditions and the order of system calls, I think it would be more difficult to fuzz this bug rather than manually reverse it.

**(Historical/present/future) context of bug:** 

Kaspersky Lab found this bug exploited in conjunction with the Chrome 0-day [CVE-2019-13720](CVE-2019-13720.md). The Chrome exploit embedded the exploit for this vulnerability, CVE-2019-1458, as the elevation of privilege. 

This exploit was discovered by Kaspersky in November 2019. Windows 7, which this exploit targeted, was hitting end-of-life in January 2020. It’s possible that the attackers decided to just go ahead and use this exploit even if it was “noisy” or potentially easier to detect, knowing that the EOL was coming. 

## The Exploit

**Is the exploit method known?** Yes

**Exploit method:**

The details about the exploitation method were posted by Kaspersky Lab in their post [“The Zero Day Exploits of Wizard Opium”](https://securelist.com/the-zero-day-exploits-of-operation-wizardopium/97086/).

To exploit this bug, a Windows kernel memory corruption, Bitmaps were used to both bypass ASLR and get arbitrary kernel read and write. This post [describes the technique](https://labs.f-secure.com/archive/a-tale-of-bitmaps/) in detail. In their blog post, Kaspersky explains that the exploit supports two different methods for ASLR bypass:

1. For older builds, the Bitmap kernel addresses are leaked by the `GdiSharedHandlerTable`
2. Creating an `AcceleratorTable` object and using `gSharedInfoHandleTable` to leak its kernel address, then freeing the `AcceleratorTable` and allocating a Bitmap in its place.

To elevate privileges, the exploit steals the system token from the `EPROCESS` object in a project running as `SYSTEM`. This is a known technique that has been documented in many places such as [here](https://improsec.com/tech-blog/windows-kernel-shellcode-on-windows-10-part-1).

## The Next Steps

### Variant analysis

**Areas/approach for variant analysis (and why):**

When patching this bug, Microsoft added initialization for 2 other system window types in addition to `FNID_SWITCH`. There are more than just these system window types so it’d be worth exploring why only these ones were selected for initialization and if:
1. Any other system window types still have the uninitialized variable vulnerability, or 
2. The other window types who now have initialization have any SetWindowLongPtr vulnerabilities.

Another interesting area for variant analysis would be in the task switching code. I originally attempted to patch-diff this vulnerability when the patch was first released, but ended up reverse engineering another bug in the task-switching code [[blog post](https://googleprojectzero.blogspot.com/2020/04/tfw-you-get-really-excited-you-patch.html). There appears to be quite a bit of legacy code still in the module. With at least 2 bugs in it in 3 months, and one exploited in the wild, it seems like a ripe area for analysis. 

Note: Project Zero did not perform either of these analyses. 

**Found variants:** N/A

### Structural improvements

This vulnerability was not exploited against the latest Windows release due to mitigations that have been added, such as Win32k lockdown for sandboxed code and they’ve mitigated the two ASLR bypass methods this exploit uses. This shows that Microsoft’s mitigations and structural improvements are working.

### 0-day detection methods

User applications that are creating system windows such as `FNID_SWITCH`.

## Other References 
* December 2019: [“Windows 0-day exploit CVE-2019-1458 used in Operation WizardOpium”](https://securelist.com/windows-0-day-exploit-cve-2019-1458-used-in-operation-wizardopium/95432/) by Kaspersky Lab
* March 2020: [Root Cause Analysis and POC of CVE-2019-1458](https://github.com/piotrflorczyk/cve-2019-1458_POC) by florek_pl
* March 2020: [“TFW you-get-really-excited-you-patch-diffed-a-0day-used-in-the-wild-but-then-find-out-it-is-the-wrong-vuln”](https://googleprojectzero.blogspot.com/2020/04/tfw-you-get-really-excited-you-patch.html) by Maddie Stone, process of attempting to patch-diff CVE-2019-1458, but instead analyzing another bug in win32k task switching* 
* May 2020: [“The zero-day exploits of Operation WizardOpium”](https://securelist.com/the-zero-day-exploits-of-operation-wizardopium/97086/) by Kaspersky Lab