Win32k ConsoleControl Offset Confusion (CVE-2022-21882)¶
tagWNDextra-bytes alanında,xxxClientAllocWindowClassExtraBytesuser-mode callback'i üzerinden ulaşılabilen bir win32kfull type/offset confusion; CVE-2021-1732'nin bir patch bypass'ı olup local privilege escalation için in-the-wild exploit edildi.
Mechanism¶
Note
win32k her pencere için "extra bytes" (cbWndExtra / window-class extra bytes) saklar; bu alanın yorumlanması window object'teki bir flag bit'ine bağlıdır. Sıradan bir pencerede extra-bytes alanı (tagWND.WndExtra / pExtraBytes) bir user-mode pointer olarak ele alınır. Console window olarak işaretlenmiş bir pencerede (NtUserConsoleControl ile set edilen 0x800 flag'i) ise aynı alan bir kernel desktop-heap offset olarak yeniden yorumlanır.
Kernel'in koruması gereken invariant şudur: extra-bytes allocation callback'inin başındaki pencere type/flag durumu, kernel dönen değeri tükettiğinde hâlâ geçerli olmalıdır. Bug bu invariant'ı kırar. Kernel xxxClientAllocWindowClassExtraBytes user-mode callback'inde (window extra bytes ayırmak için kullanılır) beklerken, attacker NtUserConsoleControl üzerinden kernel'e tekrar girer ve pencereyi bir "console window"a çevirerek alanın nasıl yorumlandığını değiştirir.
Callback geri döndüğünde kernel window type'ı yeniden doğrulamaz. Attacker'ın pointer olarak kontrol ettiği bir değer artık kernel-heap offset olarak tüketilir (ya da tam tersi) — klasik bir offset/pointer type confusion'dır ve desktop heap'e out-of-bounds write verir.
Bu bir patch bypass'tır: CVE-2021-1732 aynı sınıf confusion'dı, ancak Microsoft'un fix'i yalnızca xxxCreateWindowEx path'ini kapsıyordu. CVE-2022-21882 ise xxxClientAllocWindowClassExtraBytes'a, orijinal patch'in hiç korumadığı ek system window procedure'lar (xxxSwitchWndProc, xxxSBWndProc, xxxMenuWindowProc, xxxDesktopWndProc) üzerinden ulaşır.
Walkthrough¶
Project Zero in-the-wild RCA'sına ve Unit 42'nin iki parçalı analizine dayanan kavramsal bir reprodüksiyon. Yalnızca mantıksal adımlar.
Warning
Aşağıdaki, kamuya açıklanmış ve patch'lenmiş davranışın detection ve eğitim amaçlı üst düzey bir taslağıdır. Kasıtlı olarak uygulanabilir değildir: offset, gadget veya kopyala-yapıştır code yoktur.
Step 1 — User-mode callback'i hook'la.
Attacker, process'in KernelCallbackTable'ında xxxClientAllocWindowClassExtraBytes'a karşılık gelen girdiye bir hook kurar. Bu ona kontrol ettiği, kernel tarafından başlatılan bir callback verir.
Step 2 — Callback ortasında window type'ı çevir.
Hook'lanan callback'in içinden, hedef tagWND üzerinde console-window flag'ini (0x800) set etmek için NtUserConsoleControl çağır. Kernel işleme bir user pointer beklemiş olsa da, pencerenin extra-bytes alanı artık semantik olarak bir kernel offset'tir.
Step 3 — Confused write. Callback geri döner. Kernel flag'i yeniden kontrol etmeden devam eder ve attacker'ın etkilediği alanı yanlış yorumla tüketir; bu da desktop heap içinde kontrollü bir out-of-bounds write üretir.
Step 4 — Read/write primitive'leri kur.
OOB write, komşu bir pencerenin cbWndExtra'sını büyütmek için kullanılır; bu da normalde sınırlı olan bir SetWindowLongPtr write'ını daha geniş bir primitive'e çevirir. Forge edilmiş bir menu structure artı GetMenuBarInfo kontrollü bir read sağlar. Bkz. tagWND cbWndExtra arbitrary-write primitive.
Step 5 — Token theft.
Kernel read/write ile attacker EPROCESS listesini gezer, SYSTEM process token'ını saldıran process'e kopyalar ve SYSTEM olarak çalışır — hiçbir zaman enjekte edilmiş kernel code çalıştırmayan data-only bir saldırı. Bkz. EPROCESS token stealing.
Detection¶
KernelCallbackTableintegrity. Non-system bir GUI process'ten win32k client callback table'ına yapılan hook'lar güçlü bir sinyaldir.KernelCallbackTable'ın snapshot'ını alıp yüklenen image baseline'ı ile karşılaştıran EDR, tamper'ı flag'leyebilir.- Anormal
NtUserConsoleControlkullanımı. Console-control path'lerinin meşru çağıranları dardır. Bir window-class extra-bytes allocation callback'inin içinden yapılan birNtUserConsoleControlçağrısı son derece anormal bir sıralamadır. - Win32k anomaly telemetry. Aşırı büyük bir
cbWndExtraima edenSetWindowLongPtr/SetWindowLongwrite'larına veGetMenuBarInfotarafından tüketilen forge edilmişspmenu/menu-bar structure'larına dikkat edin. - Davranışsal / post-exploitation. Token-context uyuşmazlığı (medium-IL bir process'in aniden
SYSTEMtoken'ına sahip olması) ve creation sırasında type flag'leri beklenmedik şekilde değişen parent/child pencereler. - Crash forensics. Desktop-heap OOB write'lar sıklıkla
win32kfullbugcheck'leri olarak ortaya çıkar; meşru olarak console window olmayan pencerelerdeki0x800console flag'lerini korele edin.
Mitigation¶
- CVE-2022-21882'yi düzelten Ocak 2022 cumulative update'i uygulayın. Düzeltilmiş code,
xxxClientAllocWindowClassExtraBytestamamlanmadan önce console-window flag'ini (0x800) yeniden kontrol eder ve flag callback sırasında değiştiyse işlemi başarısız kılar; böylece ulaşan tüm wndproc'larda offset/pointer confusion'ı kapatır. - Win32k syscall filtering. GUI syscall'lara ihtiyaç duymayan process'ler için (birçok service ve browser-renderer process'i), tüm attack surface'i kaldırmak üzere Win32k system-call disable mitigation policy'sini etkinleştirin. Bkz. Disable Win32k system calls.
- Type isolation / hardening. Modern win32k build'leri, window object'leri ayrıştırmak ve confused alanların değerini azaltmak için type isolation kullanır.
- Defense in depth. HVCI/KMCI ve credential-theft monitoring, primitive'e ulaşılsa bile data-only token-swap aşamasının getirisini azaltır.
References¶
- CVE-2022-21882: Win32k Window Object Type Confusion — Project Zero 0-days In-the-Wild RCA
- Inside Win32k Exploitation: Analysis of CVE-2022-21882 and CVE-2021-1732 — Unit 42 (Part 2)
- Inside Win32k Exploitation: Background and Methodologies — Unit 42 (Part 1)
- Analysis of CVE-2022-21882: Win32k Window Object Type Confusion Exploit — Core Labs