Win32k Race-Condition Exploitation (TOCTOU window state)¶
win32k'nın, yeterince korunmayan window/menu/desktop-heap state'ini tutarken user mode'a geri girdiği ve böylece ikinci bir thread'in bu state'i time-of-check ile time-of-use arasında free etmesine ya da mutate etmesine izin veren kavramsal bir bug sınıfı — race'leri use-after-free ve type-confusion primitive'lerine dönüştürür.
Mechanism¶
Note
win32k aslında kernel'e taşınmış bir user-mode subsystem'di; hâlâ operasyonun ortasında user mode'a geri callback yapar ve mutable state'i (window object'leri, menüler, desktop heap) bir session'ın thread'leri arasında paylaşır. Bir defender'ın önemsediği invariant şudur: bir user-mode callback'ten ya da ikinci bir syscall'dan önce validate edilmiş state, kernel onu sonradan tükettiğinde hâlâ geçerli kalmalıdır.
İki ilişkili race pattern'i bunu kırar:
- window/desktop-heap state üzerinde TOCTOU. Kernel bir property'yi kontrol eder (type flag, size, bir child/parent ilişkisi) ve ardından user mode'a geri girdikten ya da yield ettikten sonra bunun hâlâ geçerli olduğu varsayımıyla hareket eder. Race'e giren bir thread bu boşlukta onu değiştirir. CVE-2021-1732 / CVE-2022-21882, bir window'un extra byte'larının type interpretation'ının callback penceresi sırasında flip edildiği somut örneklerdir. Dikkat: bu iki CVE aslında callback-driven type-confusion variant'ıdır (
xxxClientAllocWindowClassExtraBytesextra-byte yorumu) — kesin olarak ikinci bir racing thread gerektirmez; aşağıdaki Smash-the-Ref reference-count case'leri ise gerçek bir free/reuse timing race'i ister. Bkz. Win32k ConsoleControl offset confusion. - Reference-count / "smash the ref" race'leri. Bir callback içinde bir parent window'u destroy etmek (ör.
xxxFreeWindowsırasındaThreadUnlocküzerinden), başka bir thread'in hâlâ üzerinde işlem yaptığı bir child window'un free edilmesine kademeli olarak yol açar — free'nin tam anında bir callback bulunmayan bir use-after-free olur, dolayısıyla attacker'ın free ile reuse arasında gerçek bir timing race kazanması gerekir. Bkz. Smash the Ref.
İlişkili bir primitive de double fetch'tir: kernel aynı user-mode değerini iki kez okur (önce check, sonra use) ve attacker bunu aradaki anda flip eder. Bkz. double-fetch / user-kernel TOCTOU.
Walkthrough¶
Gil Dabah'ın "Smash the Ref" win32k araştırmasından ve public TOCTOU/double-fetch materyalinden çıkarılmış kavramsal taslak. Exploit seviyesinde detay yok.
Warning
Bu, bir sorun sınıfını ve public olarak açıklanmış, patch'lenmiş örnekleri detection ve hardening amacıyla anlatır — çalışan bir exploit değil.
Step 1 — Shared-state bir window belirle. Window state'ini validate eden, ardından user mode'a geri giren (bir user-mode callback) veya ikinci bir bağımlı read yapan, bu sırada başka bir thread'in aynı object'e ulaşabildiği bir win32k operasyonu bul.
Step 2 — Free ya da mutation ile race et. İkinci bir thread'de, object'i tam olarak kernel'in boşluğu sırasında destroy et (ya da type/size flag'ini flip et). Reference-count bug'larında bu, parent'ı destroy etmenin child'ı free etmesi kademesidir; TOCTOU'da ise check ile use arasında bir flag veya değer değişikliğidir.
Step 3 — Race'i deterministik şekilde kazan. Thread'leri core'lara pin'le, kernel'in vulnerable penceresini uzat (ör. callback içinde stall ederek) ve tekrarla. Birçok win32k race'i son derece tekrarlanabilirdir çünkü attacker callback timing'ini kontrol eder.
Step 4 — Reclaim et ve weaponize et. Free edilmiş object'in slot'unu şekillendirilmiş data ile reclaim et (heap grooming) ki dangling/confused erişim kontrollü bir read/write hâline gelsin, ardından bir token swap'e geç. Bkz. use-after-free ve race condition.
Detection¶
- Win32k crash clustering. window-free, menu ya da class-data rutinlerine bağlı tekrarlayan
win32kfullbugcheck'leri — başarısız race'ler başarılı olanlardan çok daha sık crash eder. - win32k üzerinde Driver Verifier. Special Pool artı race-dostu verification, aralıklı UAF race'lerini hunt/test ortamlarında deterministik, atfedilebilir bugcheck'lere dönüştürür.
- Callback-stall davranışı. Bir kardeş thread aynı window/menu handle'ını hammer'larken, bir win32k user-mode callback içinde kasıtlı olarak block eden bir GUI thread'i anormaldir.
- Multi-thread window-handle contention untrusted bir process'ten: birçok thread'in aynı
HWND/menüyü sıkı loop'larda create/destroy/operate etmesi. - Post-exploitation. Her zamanki data-only token-swap parmak izi (elevated olmayan bir process'in
SYSTEMtoken'ını alması).
Mitigation¶
- Hemen patch'le. Belirli örnekler (CVE-2021-1732, CVE-2022-21882, Smash-the-Ref dönemi fix'leri) lock ekleyerek ya da callback'ten sonra state'i yeniden validate ederek ele alınır. Cumulative update'leri güncel tut.
- Win32k syscall filtering, buna ihtiyaç duymayan process'ler için GUI-syscall erişilebilirliğini kaldırır — bu tüm sınıf için en etkili yapısal mitigation'dır. Bkz. Disable Win32k system calls.
- Type isolation, window/object pool'larını ayırarak race kaynaklı bir free'den sonra güvenilir reclaim'i azaltır. Bkz. Win32k type isolation.
- Mimari fix'ler. Microsoft, bu race'leri mümkün kılan lock-across-callback pattern'ini ortadan kaldırmak için kademeli olarak reference locking ve (yeni build'lerde) win32k bölgelerinin memory-safe refactoring'ini ekledi.
References¶
- Researcher Finds New Class of Windows Vulnerabilities (Gil Dabah / Smash the Ref) — SecurityWeek
- gdabah/win32k-bugs — Smash the Ref PoC repository
- CVE-2022-21882: Win32k Window Object Type Confusion — Project Zero 0-days In-the-Wild RCA
- Inside Win32k Exploitation: Background and Methodologies — Unit 42 (Part 1)