1. 취약점 개요
CVE-2026-20817은 Windows Error Reporting Service(WER)에서 발견된 로컬 권한 상승 취약점이다. 서비스가 프로세스 생성 요청을 처리할 때 요청자의 권한을 검증하지 않아 발생한다.
WER 서비스는 NT AUTHORITY\SYSTEM 권한으로 실행되며 ALPC 포트를 통해 클라이언트 요청을 수신한다. 공격자는 일반 사용자 권한으로 특정 메시지를 전송하여 SeTcbPrivilege를 제외한 SYSTEM 수준의 토큰으로 프로세스를 생성할 수 있으며 해당 프로세스의 명령줄 인자를 완전히 제어할 수 있다.
1.1 취약점 정보
항목 | 내용 |
CVE ID | CVE-2026-20817 |
취약 구성요소 | wersvc.dll (Windows Error Reporting Service) |
취약점 유형 | Elevation of Privilege |
CWE 분류 | CWE-280 (Improper Handling of Insufficient Permissions or Privileges) |
CVSS v3.1 Score | 7.8 (High) |
CVSS Vector | AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
공개일 | 2026년 1월 14일 |
1.2 CWE-280 개요
CWE-280은 소프트웨어가 기능에 접근할 때 권한 부족 상황을 처리하지 않거나 부적절하게 처리하는 경우를 말한다.
CWE-280 요소 | 취약점에서의 발현 |
불충분한 권한 | 일반 사용자가 SYSTEM 전용 기능 요청 |
처리 부재 | 서비스가 요청자의 권한을 검증하지 않음 |
예기치 않은 경로 | 거부되어야 할 요청이 정상 처리됨 |
비정상 상태 | 낮은 권한 사용자가 높은 권한 토큰 획득 |
2. 취약점 상세 분석
2.1 함수 호출 흐름
CWerService::SvcElevatedLaunch ← [1] 권한 검증 누락
│
▼
ElevatedProcessStart ← [2] 공유 메모리에서 명령줄 추출
│
▼
CreateElevatedProcessAsUser
│
├──► UserTokenUtility::GetProcessToken ← [3] SYSTEM 토큰 기반 생성
│
└──► CreateProcessAsUserW ← [4] 공격자 명령줄로 프로세스 생성
Plain Text
복사
[그림 1] CVE-2026-20817 취약점 발생 함수 호출 흐름도
2.2 취약점 패치 비교 분석
2.2.1 취약점 패치 전 (취약)
__int64 __fastcall CWerService::SvcElevatedLaunch(
struct _RTL_CRITICAL_SECTION *this,
struct _WERSVC_MSG *a2,
struct _WERSVC_MSG *a3)
{
// ...
// 권한 검증 없이 바로 처리 진행
v6 = CWerService::OpenSenderProcessThread(this, ...);
if ( v6 >= 0 )
{
// ...
v6 = ElevatedProcessStart(...);
}
// ...
}
C
복사
[코드 1] 패치 전 SvcElevatedLaunch - 권한 검증 없이 프로세스 생성 요청을 즉시 처리
2.2.2 취약점 패치 후 (완화)
__int64 __fastcall CWerService::SvcElevatedLaunch(
LPCRITICAL_SECTION lpCriticalSection,
struct _WERSVC_MSG *a2,
struct _WERSVC_MSG *a3)
{
// ...
// Feature Flag 확인 - 활성화 시 즉시 거부
if ( (unsigned __int8)wil::details::FeatureImpl<
__WilFeatureTraits_Feature_2607502650>::__private_IsEnabled(...) )
{
*((_DWORD *)a3 + 10) = 1;
*((_DWORD *)a3 + 11) = -1073741823; // STATUS_NOT_IMPLEMENTED
return 2147500037LL; // E_NOTIMPL
}
// 이하 기존 코드 (Feature Flag 활성화 시 도달 불가)
// ...
}
C
복사
[코드 2] 패치 후 SvcElevatedLaunch - Feature Flag로 기능 자체를 비활성화하여 취약점 완화
Microsoft는 권한 검증 로직을 추가하는 대신 Feature Flag를 통해 기능 자체를 비활성화했다. 기능을 완전히 차단한 점으로 미루어 볼 때 해당 기능이 본래 외부에 노출되어서는 안 되는 내부 전용 기능이었을 가능성이 높다.
2.3 SvcElevatedLaunch - 권한 검증 부재
이 함수는 프로세스 생성 요청의 진입점이며 CWE-280 취약점이 발생하는 지점이다.
__int64 __fastcall CWerService::SvcElevatedLaunch(
struct _RTL_CRITICAL_SECTION *this,
struct _WERSVC_MSG *a2,
struct _WERSVC_MSG *a3)
{
void *v5 = 0;
hObject = 0;
v14 = 0;
// ALPC 클라이언트 프로세스 핸들 획득
// 클라이언트가 신뢰할 수 있는 호출자인지 검증하지 않음
v6 = CWerService::OpenSenderProcessThread(
this,
(int)a2,
*((_DWORD *)a2 + 48) != 0 ? 1216 : 1088,
(int)&hObject,
0, 0, 0);
if ( v6 >= 0 )
{
memset_0(v16, 0, sizeof(v16));
v7 = 0;
v8 = 0;
v9 = *((_DWORD *)a2 + 48);
if ( v9 )
{
v10 = (_QWORD *)((char *)a2 + 64);
do
{
if ( v8 >= 0x10 )
break;
if ( *v10 )
v16[v7++] = *v10;
++v8;
++v10;
}
while ( v8 < v9 );
}
// 검증 없이 ElevatedProcessStart 호출
v6 = ElevatedProcessStart(
*((_DWORD *)a2 + 12), // 프로세스 타입
hObject, // 클라이언트 프로세스 핸들
*((void **)a2 + 7), // 공유 메모리 핸들 (명령줄)
v16,
v7,
&v14);
}
// ...
}
C
복사
[코드 3] SvcElevatedLaunch 전체 구현 - 클라이언트 권한 검증 없이 ALPC 요청 처리
OpenSenderProcessThread는 ALPC 클라이언트의 프로세스 핸들을 획득할 뿐 해당 프로세스의 권한 수준을 검증하지 않는다. 따라서 일반 사용자의 요청도 거부되지 않고 ElevatedProcessStart로 전달된다.
2.4 ElevatedProcessStart - 명령줄 추출
이 함수는 공유 메모리에서 공격자가 제어하는 명령줄을 읽어온다.
__int64 __fastcall ElevatedProcessStart(
int a1,
void *a2, // 클라이언트 프로세스 핸들
void *a3, // 공유 메모리 핸들
void *a4,
unsigned int a5,
void **a6)
{
// ...
// 클라이언트가 생성한 공유 메모리 핸들을 현재 프로세스(WER 서비스)로 복제
v15 = (HANDLE *)tlx::replace<tlx::file_handle_traits>(hFileMappingObject);
CurrentProcess = GetCurrentProcess();
if ( !DuplicateHandle(a2, a3, CurrentProcess, v15, 0x80000000, 0, 0) )
{
// ...
}
// 공유 메모리 매핑 (0x208 = 520 바이트)
v20 = MapViewOfFile(hFileMappingObject[0], 4u, 0, 0, 0x208u);
// ...
// 명령줄 복사 - 클라이언트가 제어하는 데이터
ElevatedProcessAsUser = memcpySEH(v32, v20, 0x208u);
// ...
// 내용 검증 없이 CreateElevatedProcessAsUser로 전달
ElevatedProcessAsUser = CreateElevatedProcessAsUser(
(_DWORD)a2,
(unsigned int)v32, // 클라이언트가 제공한 명령줄
a4,
a5,
0,
(__int64)&hSourceHandle,
v24);
// ...
}
C
복사
[코드 4] ElevatedProcessStart 구현 - 공유 메모리에서 공격자 제어 명령줄을 검증 없이 추출
클라이언트는 ALPC 메시지를 보내기 전에 공유 메모리를 생성하고 원하는 명령줄을 기록해둔다. 함수는 이 내용을 검증 없이 그대로 사용한다.
2.5 UserTokenUtility::GetProcessToken - 토큰 획득
이 함수가 권한 상승의 핵심이다. 일반 사용자의 요청이 어떻게 SYSTEM 수준 토큰으로 이어지는지 분석한다.
__int64 __fastcall UserTokenUtility::GetProcessToken(
HANDLE ProcessHandle, // 클라이언트 프로세스 핸들
int a2,
void **a3) // 출력: 토큰
{
// ...
// 클라이언트 프로세스의 토큰 열기
v7 = (void **)tlx::replace<tlx::file_handle_traits>(&TokenHandle);
if ( !OpenProcessToken(ProcessHandle, 0x4Fu, v7) )
{
// ...
}
if ( !a2 )
goto ReturnToken;
// 상승된 토큰 획득 시도
v10 = (void **)tlx::replace<tlx::file_handle_traits>(&hObject);
v11 = LUAGetElevatedToken(TokenHandle, v10);
// ...
// SeTcbPrivilege 검사 - 일반 사용자의 토큰은 이 조건을 통과하지 못함
if ( (unsigned __int64)hObject + 1 > 1 &&
!(unsigned int)UtilTokenHasPrivilege(hObject, L"SeTcbPrivilege") )
{
v15 = hObject;
hObject = 0;
if ( (unsigned __int64)v15 + 1 > 1 )
CloseHandle(v15); // 토큰 폐기
}
// 적합한 토큰이 없는 경우 - 일반 사용자는 여기로 진입
if ( (unsigned __int64)hObject + 1 > 1 )
goto ReturnToken;
// ========== 핵심 취약 경로 ==========
// WER 서비스(SYSTEM)의 토큰에서 SeTcbPrivilege만 제거한 토큰 생성
if ( LookupPrivilegeValueW(0, L"SeTcbPrivilege", &Luid.Luid) )
{
Luid.Attributes = 0;
// WER 서비스 자신의 토큰 열기 (NT AUTHORITY\SYSTEM)
v17 = (void **)tlx::replace<tlx::file_handle_traits>(&ExistingTokenHandle);
CurrentProcess = GetCurrentProcess();
if ( !OpenProcessToken(CurrentProcess, 0xF01FFu, v17) )
{
// ...
}
// SYSTEM 토큰에서 SeTcbPrivilege만 제거
NewTokenHandle = (void **)tlx::replace<tlx::file_handle_traits>(&hObject);
if ( !CreateRestrictedToken(
ExistingTokenHandle, // WER 서비스의 SYSTEM 토큰
0,
0, 0,
1u, // DeletePrivilegeCount = 1
&Luid, // SeTcbPrivilege
0, 0,
NewTokenHandle) )
{
// ...
}
}
ReturnToken:
*a3 = hObject ? hObject : TokenHandle;
// ...
}
C
복사
[코드 5] GetProcessToken 구현 - WER 서비스의 SYSTEM 토큰에서 SeTcbPrivilege만 제거한 토큰 생성
토큰 획득 흐름:
1.
클라이언트(일반 사용자)의 토큰으로 상승된 토큰 획득 시도
2.
일반 사용자는 적합한 상승 토큰이 없어 실패
3.
대체 경로 진입: GetCurrentProcess()로 WER 서비스 자신의 프로세스 핸들 획득
4.
WER 서비스의 SYSTEM 토큰을 열고 CreateRestrictedToken으로 SeTcbPrivilege만 제거
5.
이 토큰이 프로세스 생성에 사용됨
클라이언트가 일반 사용자여도 WER 서비스의 SYSTEM 토큰을 기반으로 새 토큰이 생성된다는 것이 핵심이다.
2.6 CreateElevatedProcessAsUser - 최종 프로세스 생성
__int64 __fastcall CreateElevatedProcessAsUser(
void *a1,
__int64 a2, // 명령줄 (클라이언트 제어)
// ...
{
// ...
// 실행 파일 (고정)
v17 = L"WerMgr.exe";
if ( (v12 & 2) == 0 )
v17 = L"WerFault.exe";
// 경로 구성: C:\Windows\System32\WerFault.exe
CreateProcessToken = tlx::assign_sprintf<wchar_t,...>(
lpApplicationName,
L"%s\\%s",
lpCurrentDirectory,
v51);
// 명령줄 구성: "...\WerFault.exe" <클라이언트가 입력한 인자>
CreateProcessToken = tlx::assign_sprintf<wchar_t,...>(
lpCommandLine,
L"\"%s\\%s\" %s",
lpCurrentDirectory,
v22,
v57); // ← 클라이언트가 제어
// ...
// 최종 프로세스 생성
v36 = CreateProcessAsUserW(
v10, // 토큰: SYSTEM - SeTcbPrivilege
lpApplicationName[0], // WerFault.exe (고정)
lpCommandLine[0], // 클라이언트가 입력한 명령줄
0, 0,
1, // bInheritHandles = TRUE
v32,
lpEnvironment,
lpCurrentDirectory,
&StartupInfo,
&hObject);
// ...
}
C
복사
[코드 6] CreateElevatedProcessAsUser 구현 - SYSTEM 토큰과 공격자 명령줄로 프로세스 생성
2.7 최종 결과
항목 | 값 |
실행 파일 | C:\Windows\System32\WerFault.exe (고정) |
명령줄 인자 | 공격자 완전 제어 (최대 520바이트) |
토큰 | SYSTEM에서 SeTcbPrivilege만 제거 |
3. PoC 시연
본 PoC는 CVE-2026-20817 취약점의 트리거를 위해 별도의 파일 교체 취약점과 체인하여 시연되었다. 아래 영상은 일반 사용자 권한에서 WER 서비스를 통해 높은 권한의 프로세스가 생성되는 과정을 보여준다.
[동영상 1] CVE-2026-20817 시연 영상
시연 환경: Windows 11 23H2 (패치 미적용)
시연 내용:
1.
현재 사용자 권한 확인 (일반 사용자)
2.
WER 서비스 ALPC 포트 연결
3.
메시지 전송 및 프로세스 생성
4.
생성된 프로세스의 토큰 권한 확인 (SYSTEM 수준)
시연에서 확인된 바와 같이 공격자는 일반 사용자 권한만으로 SYSTEM 토큰을 획득할 수 있다. 해당 토큰에는 SeDebugPrivilege, SeImpersonatePrivilege, SeBackupPrivilege 등 높은 권한이 포함되어 있어 이를 활용한 자격 증명 탈취 및 완전한 시스템 장악으로 이어질 잠재적 위협이 있다.
4. 탐지 및 검증
4.1 행위 기반 탐지
다음 조건을 만족하는 프로세스 생성 이벤트를 모니터링한다.
•
프로세스: WerFault.exe 또는 WerMgr.exe
•
토큰 특성: SeDebugPrivilege 보유 + SeTcbPrivilege 미보유 (비정상 조합)
•
명령줄: 정상 WER 동작과 불일치하는 인자
4.2 PurpleHound 솔루션을 통한 검증
본 취약점과 같은 권한 상승 공격에 대해 조직의 보안 인프라가 효과적으로 대응할 수 있는지 사전에 검증하는 것이 중요하다.
PurpleHound는 78ResearchLab에서 개발한 BAS(Breach and Attack Simulation) 솔루션으로 실전 기반 공격 시나리오를 재구성하여 기업이 보유한 보안 장비와 시스템이 실제 공격에 얼마나 효과적으로 대응 가능한지 검증할 수 있도록 지원한다. 북한 등 실제 위협 그룹이 사용하는 최신 공격 기술을 반영하며 모든 공격 시나리오는 검증을 거쳐 탑재된다.
CVE-2026-20817 취약점 역시 PurpleHound에 공격 시나리오로 탑재되어 조직 내 엔드포인트 보안 솔루션 및 EDR이 해당 공격을 탐지·차단하는지 검증할 수 있다.
5. 권장 조치
•
2026년 1월 Microsoft 보안 업데이트 즉시 적용
•
패치 불가 시: 엔드포인트 모니터링 강화
6. 결론
CVE-2026-20817은 WER 서비스가 프로세스 생성 요청 시 요청자의 권한을 검증하지 않아 발생하는 CWE-280 취약점이다.
CWerService::SvcElevatedLaunch에서 요청자 권한 확인이 없어 일반 사용자 요청도 처리된다. UserTokenUtility::GetProcessToken에서 적합한 상승 토큰이 없으면 WER 서비스의 SYSTEM 토큰을 기반으로 SeTcbPrivilege만 제거한 토큰이 생성된다.
공격자는 이 토큰으로 실행되는 프로세스의 명령줄을 완전히 제어할 수 있으며 시스템을 장악할 수 있는 잠재적 위협이 존재한다.


