Skip to content

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 (xxxClientAllocWindowClassExtraBytes extra-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. xxxFreeWindow sırasında ThreadUnlock ü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 win32kfull bugcheck'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 SYSTEM token'ı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