Mateusz Jurczyk, Project Zero (Originally posted on Project Zero blog 2021-02-04)

The Basics

Disclosure or Patch Date:

  • Disclosure: 30 October 2020 by Google Project Zero
  • Patch Date: 10 November 2020

Product: Microsoft Windows

Advisory: https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2020-17087

Affected Versions: For Windows 10 2004, KB4579311 and previous

First Patched Version: For Windows 10 2004, KB4586781

Issue/Bug Report: https://bugs.chromium.org/p/project-zero/issues/detail?id=2104

Patch CL: N/A

Bug-Introducing CL: N/A

Reporter(s): Mateusz Jurczyk and Sergei Glazunov of Google Project Zero

The Code

Proof-of-concept: https://bugs.chromium.org/p/project-zero/issues/detail?id=2104

Exploit sample: N/A

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

The Vulnerability

Bug class: Buffer overflow

Vulnerability details:

Pool buffer overflow due to an incorrect 16-bit integer truncation in the processing of IOCTL 0x390400. The bug is in the function cng!CfgAdtpFormatPropertyBlock. To calculate the size of the buffer to allocate, the function multiplies an attacker-controlled integer by 6 and stores the result in a variable of type USHORT. If the input buffer length passed in during the IOCTL call is greater than or equal to 0x2AAB, then the buffer allocated by BCryptAlloc() will be too small, leading to a buffer overflow.

Patch analysis: N/A

Thoughts on how this vuln might have been found (fuzzing, code auditing, variant analysis, etc.): Either through a manual audit of the IOCTL handling code accessible from user-mode, or through (coverage-guided) fuzzing.

(Historical/present/future) context of bug:

The vulnerability was used as part of an exploit chain for Chrome on Windows. It allowed the attacker to break out of the Chrome sandbox and execute code with system privileges. It was paired with CVE-2020-15999.

The Exploit

Exploit method: The exploit uses the buffer overflow to establish an arbitrary read/write primitive in the kernel address space with the help of Named Pipe objects.

The Next Steps

Variant analysis

Areas/approach for variant analysis (and why):

Look for other trivial cases of an allocation size being down-casted to a smaller integer type in cng.sys and other drivers with user-reachable attack surfaces.

Found variants:

Structural improvements

High level ideas:

  • Use static analysis to identify places in the kernel code where inadequately small integer types are used to store buffer lengths, and refactor them or discourage their use in the future.
  • Potential further hardening of the kernel pool allocator to make the exploitation of memory corruption in the Windows kernel (especially large overflows that corrupt more than 64 kB) less reliable.

0-day detection methods

Directly interacting with the cng.sys driver without going through system APIs is unusual, and may be an indicator of active exploitation.

Other References