# CVE-2020-1027: Windows buffer overflow in CSRSS

Unchecked UNICODE_STRING MaximumLength in CSRSS sxssrv manifest parser lets any process trigger a heap overflow in memcpy, enabling sandbox escape.

- Payout: Real-world hack
- Severity: high
- Program: Microsoft Windows
- Credited: Sergei Glazunov, Project Zero (Originally posted on [Project Zero blog](https://googleprojectzero.blogspot.com/p/rca.html) 2021-01-12)
- Disclosed: 2020-03-23
- CVE: CVE-2020-1027
- Write-up quality: 8/10
- Original: https://github.com/googleprojectzero/0days-in-the-wild/blob/main/0day-RCAs/2020/CVE-2020-1027.md
- Library page: https://bugbountylibrary.com/r/p0%3ACVE-2020-1027
- Tags: domain:desktop impact:privesc impact:rce kind:incident platform:project-zero sev:high tech:windows technique:chained technique:source-review vuln:memory-corruption vuln:privilege-escalation vuln:sandbox-escape

**Target:** CSRSS ALPC IPC handler sxssrv!BaseSrvSxsCreateActivationContext (side-by-side assembly manifest parsing)
**Root cause:** The IPC handler validates Buffer+Length against the capture buffer but never validates MaximumLength; the reused output UNICODE_STRING's MaximumLength is trusted as ApplicationNameCapacity, so memcpy overflows the destination with attacker-controlled size and data.
**Steps:**
1. Load Ntdll.dll and resolve CsrAllocateCaptureBuffer, CsrClientCallServer, CsrCaptureMessageString.
2. Allocate a capture buffer via `CsrAllocateCaptureBuffer(4, 0x300)`.
3. Build a CSR_API_MSG at offset 0x40: set ApiNumber 0xc1, length 9, and 0x201 at +0x59.
4. Place a manifest XML string pointer at +0x80 and its size at +0x88; set +0xf0 = 1.
5. Capture UNICODE_STRINGs for ApplicationName (NULL_BYTE_STR), manifest name, path `\\.\c:Windows\`, and module `System.Data.SqlXml.Resources` at offsets 0x48/0x60/0xc8/0x120.
6. Overwrite the ApplicationName MaximumLength at +0x122 with `0x8000` to bypass the capacity check.
7. Call `CsrClientCallServer(Message, CaptureBuffer, 0x10017, 0xf0)` to trigger the overflow in `sxs!CNodeFactory::XMLParser_Element_doc_assembly_assemblyIdentity`.
8. Craft manifest assemblyIdentity name of ~0x2000 'A's so memcpy writes past the destination buffer.
**How found:** Text states it could have been found via manual audit of CSRSS IPC handlers; the analyst had the exploit sample and identified the missing MaximumLength validation by reviewing UNICODE_STRING handling in the manifest parser.
**Exploitation:** Attacker overwrites adjacent _MY_XML_NODE_INFO objects to build a write-what-where primitive, then overwrites the module list head in PEB_LDR_DATA to start a code-reuse attack; CFG limits calls to existing functions with one controlled argument, which suffices to pivot into a ROP chain and escape the browser sandbox.
**Escalation:** Chained with Chrome 0-day CVE-2020-6418 (renderer RCE) as the sandbox-escape stage; on older OSes paired with CVE-2020-1020/CVE-2020-0938 instead.
**Insight:** When an IPC struct reuses a caller-supplied UNICODE_STRING as an output parameter, the MaximumLength field becomes an attacker-controlled capacity that the callee trusts for memcpy bounds; audit every place a length/capacity field crosses a trust boundary separately from the pointer+length check.
