창은 잠갔지만 그 안의 메뉴는 잠그지 않았다 — win32k 권한상승의 실전 사례

창은 잠갔지만 그 안의 메뉴는 잠그지 않았다 — win32k 권한상승의 실전 사례

분류: CVE · 커널·OS · 권한상승(LPE) [정보성] · CVE-2023-29336

덱. 보안 리서치 업체 NumenCyber가 실제 공격에서 이미 악용된 것으로 확인된 Windows 커널 취약점 CVE-2023-29336을 분석했습니다. 창(window) 객체는 참조 잠금을 걸었지만 그 안에 중첩된 메뉴 객체는 잠그지 않은 오래된 코드 습관이 원인으로, 해제된 메모리를 재사용하는 UAF(use-after-free, 해제 후 재사용) 취약점으로 이어졌습니다. Windows 11에서는 통하지 않는 것으로 보이지만 이전 버전에서는 여전히 실질적 위험으로 분석됐습니다.

리드

윈도우 GUI를 다루는 커널 서브시스템 win32k는 오랫동안 권한상승 취약점의 텃밭이었습니다. 이유는 단순합니다 — 창, 메뉴, 클래스 확장 데이터 같은 객체들이 서로를 겹겹이 참조하는 오래된 구조인데, 이 참조 관계 중 하나라도 잠금(lock)을 빠뜨리면 사용자 입력만으로 커널 메모리를 해제·재사용시킬 수 있는 길이 열립니다. CVE-2023-29336은 그 교과서 같은 사례입니다. 창 객체 자체는 안전하게 잠갔지만, 창 안에 여러 단계로 중첩될 수 있는 메뉴 객체까지는 잠그는 걸 놓쳤습니다.

핵심 사실 요약

  • 근본원인(분석): xxxEnableMenuItem 커널 함수가 메뉴 항목의 상태를 처리하는 과정에서, 상위 함수는 창에 연결된 메뉴를 잠그지만 그 메뉴 안에 중첩된 서브메뉴·서브서브메뉴까지는 잠그지 않습니다. NumenCyber는 오래된 소스 주석을 근거로, 원래 구현이 “창 객체 잠금”에만 집중하고 그 안에 내포된 메뉴 객체 잠금을 빠뜨렸다고 짚었습니다. 이 참조 카운트 누락이 메뉴 객체를 실제보다 먼저 해제시키는 UAF로 이어집니다.
  • 실제 공격 확인: 이 취약점은 패치가 나오기 전 실제 공격에서 악용된 제로데이로 확인됐습니다. CISA가 2023년 5월 9일 KEV(Known Exploited Vulnerabilities, 실제 악용 확인 취약점) 목록에 등재했고, 여러 보안 매체도 동일하게 보도했습니다(NVD/CISA KEV 대조로 확인 완료, 2026-08-31).
  • 영향 범위: 분석은 Windows Server 2016을 테스트 기준으로 삼았고, Windows 11에서는 이 취약점이 익스플로잇되지 않는 것으로 관찰됐다고 밝혔습니다. 그 사이 버전들의 정확한 영향 목록은 ⚠️미확인(팩트체크 대상)입니다.
  • 패치 시점: 2023년 5월 9일 정기 보안 업데이트(Patch Tuesday)에서 수정됐습니다(NVD/CISA KEV 대조로 확인 완료). 세부 빌드·KB 번호별 목록까지는 이 초안에서 직접 대조하지 못했습니다.
  • CVSS: 원문(NumenCyber)에는 점수가 명시돼 있지 않으나, NVD 기준 CVSS v3.1 **7.8(HIGH)**로 확인됩니다(AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — 로컬 권한상승 특성과 부합).
  • 익스플로잇 개념(구체 페이로드 제외): 3단계로 중첩된 메뉴 구조를 의도적으로 구성해 특정 메뉴가 예상보다 먼저 해제되게 만들고, 그 빈 메모리 공간을 다른 객체로 되채워 커널 메모리를 원하는 값으로 덮어쓸 수 있는 발판을 마련하는 방식입니다. 이후 단계에서는 임의 주소를 읽는 데 GetMenuBarInfo()를, 임의 주소에 쓰는 데 SetClassLongPtr()를 활용해 읽기·쓰기 프리미티브(primitive, 기초 조작 수단)를 확보했다고 원문은 설명합니다. 이런 프리미티브는 과거 CVE-2017-0263, CVE-2016-0167, CVE-2022-21882, CVE-2021-1732 등 다른 win32k 취약점 익스플로잇에서도 반복적으로 쓰인 패턴이라고 원문은 언급합니다.
  • 마이크로소프트의 대응 방향: 원문은 마이크로소프트가 Windows 11 프리뷰에서 win32k의 일부를 Rust로 재작성하는 작업을 진행 중이라고 언급하며, 이런 재작성이 향후 이 계열 취약점을 줄이거나 없앨 잠재력이 있다고 평가했습니다.

짧은 논평

이 사례가 흥미로운 건 새로운 기법이 아니라 “오래된 습관”이 원인이라는 점입니다. 창 객체를 잠그는 코드는 있었지만, 그 창 안에 몇 겹이든 중첩될 수 있는 메뉴 객체까지 똑같이 잠가야 한다는 걸 놓쳤습니다. 참조 카운팅이 있는 시스템에서 “이 객체를 잠그면 안전하다”는 가정이, 실은 “이 객체가 참조하는 다른 객체까지 다 잠가야 안전하다”였던 셈입니다. 저희가 필터 우회나 파서 불일치 사례에서 반복해서 보는 구조와 닮았습니다 — 안전장치가 표면의 한 객체에만 걸려 있고, 그 객체가 내포한 하위 구조는 별도의 신뢰 경계로 취급되지 않았을 때 틈이 생깁니다. win32k처럼 수십 년 묵은 코드베이스에서는 이런 누락이 한 번으로 끝나지 않고 비슷한 형태로 계속 재발했다는 게 원문이 나열한 이전 CVE 목록에서도 드러납니다. 마이크로소프트가 이 서브시스템을 Rust로 재작성하려는 움직임도 결국 같은 결론입니다 — 코드 습관에 기대는 것보다, 잠금이 빠지면 컴파일 자체가 안 되게 만드는 쪽이 더 믿을 만하다는 판단입니다.

References / 참고자료

  1. NumenCyber, “Analysis of CVE-2023-29336 Win32k Privilege Escalation Vulnerability (with POC)” — 이 글이 재구성한 원 분석. 취약점 근본원인과 익스플로잇 구성 방식을 다룸. https://www.numencyber.com/cve-2023-29336-win32k-analysis/
  2. NumenCyber, PoC 코드 저장소(GitHub) — 원문이 인용한 개념증명 코드 위치. https://github.com/numencyber/Vulnerability_PoC/blob/main/CVE-2023-29336/poc.cpp
  3. Zero Day Initiative, “The May 2023 Security Update Review” — 원문이 패치 시점 근거로 인용한 자료. https://www.zerodayinitiative.com/blog/2023/5/8/the-may-2023-security-update-review

이 글은 위 원 분석을 우리 관점에서 다시 쓰고 짧은 논평을 더한 정보성 초안입니다. 특정 문장·코드·PoC를 그대로 옮기지 않았으며, 작동하는 익스플로잇 코드는 싣지 않았습니다. ⚠️미확인 표시 항목은 발행 전 독립 팩트체크에서 확증·정정되어야 합니다.