| 항목 | 내용 |
|---|---|
| CVE ID | CVE-2022-21882 |
| 영향 구성요소 | Windows Win32k 창 객체와 user-mode callback 경로 |
| 영향 제품 | 2022년 1월 보안 업데이트 이전의 Windows 10·Windows 11·Windows Server 2019·Windows Server 2022 |
| 취약점 유형 | Win32k Type Confusion에 따른 로컬 Privilege Escalation |
| CVSS v3.1 | Microsoft 7.0 High (AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H); NVD 7.8 High |
| 공개/수정 | 2022-01-11 공개, 2022년 1월 Windows 보안 업데이트에서 수정 |
| 악용 상태 | CISA KEV에 2022-02-04 등재 |
| 분석 기준 | Microsoft/NVD/CISA 메타데이터와 Apache-2.0으로 공개된 Google Project Zero root-cause analysis의 정적 분석. PoC·공격 코드는 실행하지 않음 |
CVE-2022-21882는 Windows GUI 하위 시스템인 Win32k에서 창 객체의 표현이 callback 도중 바뀌었는데,
커널이 callback 뒤에 그 변화를 다시 검증하지 않은 문제다. 그 결과 같은 WndExtra 필드를
사용자 모드 포인터로 보아야 할 시점과 커널 desktop heap 오프셋으로 보아야 할 시점이 뒤섞여,
경계 밖 읽기·쓰기로 이어질 수 있었다.
이 취약점은 "사용자 모드 callback은 호출자에게 제어를 잠시 넘겨 주므로, callback 이전에 세운 커널 객체 불변식이 그대로 남아 있다고 가정하면 안 된다"는 원칙을 잘 보여 준다. 수정은 callback 종료 시 ConsoleWindow 상태 플래그를 확인하고, 객체 종류가 바뀌었다면 결과를 성공으로 사용하지 않도록 했다.
응용 프로그램이 창을 만들거나 메뉴·스크롤바·툴팁 같은 GUI 기능을 요청하면, user32/win32u 계층의 API는 Win32k 커널 경로를 호출한다. 커널은 화면 객체와 desktop heap을 관리하지만, 일부 작업은 사용자 모드가 준비한 메모리나 정책을 필요로 한다. 그래서 Win32k는 처리 중 user-mode callback을 호출할 수 있다.
응용 프로그램
│ GUI API
▼
user32 / win32u
│ system call
▼
Win32k 커널 경로 ── callback ──> user-mode callback 함수
│ │
└────────────── callback 반환 <───┘
│
▼
창 객체 생성·갱신 계속
callback은 정상 기능이지만 신뢰 경계를 만든다. 커널은 callback 전후에 객체의 종류, 포인터의 뜻, 크기와 범위가 달라지지 않았는지 다시 확인해야 한다. 그렇지 않으면 이전 상태를 전제로 한 포인터 연산이 다른 형식의 데이터를 잘못 해석한다.
Google Project Zero의 공개 RCA는 이 문제를 tagWND 창 객체의 WndExtra 필드가 서로 다른
방식으로 해석되는 경우로 설명한다. 일반 창에서는 이 값이 사용자 모드 pointer로 취급될 수 있다.
ConsoleWindow 상태가 설정된 창에서는 같은 값이 kernel desktop heap의 offset으로 해석된다.
동일한 WndExtra 비트열
일반 창: user-mode 주소로 해석
ConsoleWindow 창: kernel desktop heap 기준 offset으로 해석
두 해석은 교환 가능하지 않다. 포인터와 offset은 모두 정수처럼 저장되더라도 기준 주소와 유효 범위가 다르다. 창 종류가 바뀐 뒤에도 이전 해석을 계속 쓰면, 계산 결과가 예상한 객체 범위를 벗어날 수 있다.
RCA에 따르면 관련 Win32k 경로는 xxxClientAllocWindowClassExtraBytes callback을 user mode로
전달한다. 이 callback의 대상은 KernelCallbackTable에 있으며, kernel은 반환 뒤에도 자기 객체가
처음 가정한 유형과 같은지 확인해야 한다.
중요한 점은 callback 함수 주소만 보호한다고 충분하지 않다는 것이다. callback 기간에 변경될 수 있는 창의 상태와 반환값의 해석 규칙도 함께 검증해야 한다. CVE-2022-21882는 호출 제어권이 사용자 모드에 있었다는 사실보다, 그 뒤에 커널이 상태 전이를 검증하지 않았다는 점이 핵심이다.
- Microsoft는 이 CVE를 Win32k Elevation of Privilege 취약점으로 공지했고, NVD는 CWE-787 Out-of-bounds Write를 기록한다.
- CISA KEV는 Microsoft Win32k Privilege Escalation Vulnerability로 이 항목을 등재했다.
- Apache-2.0으로 공개된 Project Zero RCA는 관련 GUI 커널 함수가
xxxClientAllocWindowClassExtraBytescallback을 유발하며, callback 중 ConsoleWindow 플래그를 설정하면 창 유형이 바뀔 수 있었다고 기록한다. - RCA는 callback 종료 뒤 창 유형 변화를 확인하지 않아 잘못된 데이터 해석과 경계 밖 읽기·쓰기가
가능해졌고, 수정은
0x800ConsoleWindow 플래그를 검사한다고 설명한다.
공개 RCA의 사실을 방어 관점으로 단순화하면 다음과 같다. 아래는 취약한 객체 상태 전이의 설명이며, 특정 exploit의 API 호출 순서·메모리 배치·주소 계산을 제공하지 않는다.
패치 전의 상태 전이
Win32k: "이 창의 WndExtra는 user-mode pointer다"
│
▼
user-mode callback 실행
│
▼
창이 ConsoleWindow 상태로 전이
WndExtra의 의미: pointer ────────> kernel desktop heap offset
│
▼
callback 반환 후에도 이전 해석을 재검증하지 않음
│
▼
잘못된 기준 주소·범위로 접근 ──> OOB 읽기/쓰기 가능성
이것은 메모리에 저장된 비트가 바뀌지 않아도 "그 비트를 읽는 규칙"이 바뀌어 발생하는 타입 혼동이다. 커널이 일반 창 규칙으로 결과를 계속 사용하면, ConsoleWindow 규칙에서의 offset이 포인터처럼 쓰이거나 그 반대의 상황이 생긴다. 결과적으로 한 창의 추가 데이터 접근이 이웃 커널 객체의 범위로 확장될 수 있다.
NVD의 CVSS는 로컬 접근과 낮은 권한을 전제로 한다. 즉, 이 CVE 자체는 웹에서 곧바로 실행되는 취약점이 아니라 이미 로컬 코드 실행 위치를 얻은 공격자가 더 높은 권한을 얻는 데 사용할 수 있는 커널 취약점이다. CISA KEV 등재는 그 위험이 이론에 그치지 않았음을 뜻하지만, 모든 공격 체인이나 피해 범위를 동일하게 단정하지는 않는다.
낮은 권한 사용자 프로세스
│ GUI 커널 경로
▼
Win32k 창 객체의 해석 불일치
│
▼
커널 메모리 경계 붕괴
│
▼
더 높은 권한의 객체·토큰에 영향을 줄 수 있는 상태
실제 시스템 권한 획득에는 OS 빌드, 메모리 배치, 완화 기능 등 추가 조건이 필요하다. 따라서 "경계 밖 접근 가능성"과 "항상 SYSTEM 권한 획득"을 같은 주장으로 다루면 안 된다.
Project Zero RCA에 따르면 수정된 xxxClientAllocWindowClassExtraBytes 경로는 callback이 끝나기 전
ConsoleWindow 상태 플래그 0x800을 확인한다. 플래그가 설정됐으면 성공 결과를 반환하지 않는다.
이는 callback 동안 객체의 표현 규칙이 바뀌면, 이전 상태를 전제한 할당/반환값을 사용하지 않는다는
뜻이다.
패치 후의 방어 흐름
callback 반환
│
▼
ConsoleWindow 전이 플래그(0x800) 확인
│
├─ 설정됨 ──> 실패 처리; 이전 WndExtra 해석을 계속 사용하지 않음
│
└─ 설정되지 않음 ──> 원래 창 종류의 검증된 경로 계속
운영자는 영향을 받는 Windows 클라이언트·서버에 2022년 1월 이후 보안 업데이트를 적용해야 한다. 환경별 정확한 누적 업데이트와 빌드는 Microsoft Security Update Guide로 확인한다. 오래된 Windows 이미지나 장기간 격리된 서버는 현재 지원 상태와 별도로 이 누적 업데이트가 실제 설치됐는지 점검해야 한다.
이 보고서는 공개 exploit 또는 PoC를 내려받아 실행·컴파일·재현하지 않았다. Project Zero RCA가 설명하는 객체 상태 전이와 수정 조건만 정적으로 검토했으며, 커널 주소 획득, 메모리 배치, 임의 읽기·쓰기 구성, 토큰 변경 같은 세부 재현 절차는 제공하지 않는다.
- Windows Win32k 소스와 Microsoft의 원본 binary diff가 공개되지 않아, 모든 영향 빌드에서의 정확한 함수 경로와 기계어 수준 변경은 독립적으로 확인할 수 없다.
tagWND와 관련 flag의 내부 레이아웃은 문서화된 안정 ABI가 아니므로, 공개 RCA의 설명을 다른 Windows 빌드의 고정 offset으로 일반화해서는 안 된다.- 실제 악용에서의 callback 제어 방식, 메모리 배치와 후속 권한 상승 단계는 이 보고서의 방어적 분석 범위를 넘어가며, 공개 RCA의 재현 절차로 확장하지 않는다.
- 커널이 user-mode callback 뒤에 다시 확인해야 하는 객체 불변식에는 어떤 종류가 있을까?
- 포인터와 offset처럼 저장 표현은 비슷하지만 기준 주소가 다른 값들을 API 타입으로 어떻게 구분할까?
- Microsoft Security Update Guide, CVE-2022-21882
- NIST NVD, CVE-2022-21882
- CISA, Known Exploited Vulnerabilities Catalog
- Google Project Zero, CVE-2022-21882: Win32k Window Object Type Confusion — Apache-2.0 저장소
아래 분석 글은 해당 사이트 약관이 이 저장소의 보수적 본문 근거 기준과 맞지 않거나 명확하지 않아, 본문 작성 근거로 사용하지 않고 추가 확인 링크로만 둔다.
- Palo Alto Networks Unit 42, Inside Win32k Exploitation
- Fortra Core Labs, Analysis of CVE-2022-21882