Smash the Ref win32k reference-count bug class¶
Bir win32k use-after-free bug ailesi: parent object lock'lansa bile, bir child object'e tutulan "dumb" pointer hiç lock'lanmadığı için object, user-mode callback sırasında free ediliyor.
Mechanism¶
Note
İsmi xxx prefix'i taşıyan win32k routine'leri user mode'a doğru callout yapabilir
(window-procedure callback'leri, xxxClient... thunk'ları). O callback sırasında
untrusted application çalışır ve kernel'in hâlâ üzerinde işlem yaptığı object'leri yok
edebilir. Microsoft'un tarihsel savunması locking'tir: callout'tan önce kernel bir
reference bump'lar (örn. ThreadLockAlwaysWithPti, HMAssignmentLock), böylece object
gerçekten free edilmez — lock bırakılana kadar yaşayan bir zombie hâline gelir.
Smash the Ref sınıfı (Gil Dabah), bu korumanın primary object'e uygulandığı ama
onun işaret ettiği child object'lere her zaman uygulanmadığı gözlemidir.
Bir child'a (menu item array'i, bir sub-menu, bir property list) tutulan ham, elle
yönetilen bir pointer ("dumb pointer"), callback o child'ı free edip realloc ettiğinde
dangling kalır. Güvenlik sınırı — kernel'in yalnızca canlı, sahip olduğu bellek üzerinde
işlem yapması — aşılır, çünkü lifetime garantisi yanlış object'i kapsar.
Klasik bir UAF'tan kavramsal olarak şu noktada ayrılır: bug eksik/yanlış bir reference'tır,
tek bir code path'te açık bir free-sonra-reuse değil; free, attacker tarafından meşru
callback penceresinin içinde tetiklenir.
Walkthrough¶
Public PoC'lardan (gdabah/win32k-bugs, "Win32k Smash the Ref" whitepaper) yeniden kurulmuş high-level pattern. Yalnızca temsilî bir şekil:
kernel xxxSomething(pObj):
pChild = pObj->rgItems // raw pointer cached on the stack
... HMAssignmentUnlock(...) // <-- transitions into a user-mode callback
... use pChild ... // pChild may now be dangling
Bir analist'in tekrarlayacağı mantıksal adımlar:
- Parent UI object'i (window / menu) oluştur, böylece kernel bir child array'e veya sub-object'e bir pointer cache'ler.
- Kernel'i, yalnızca ham child pointer'ı tutarken bir user-mode callout yapan (window proc,
HMAssignmentUnlock,xxxClientFreeWindowClassExtraBytesvb.)xxx-prefix'li bir path'e sürükle. - Attacker-controlled callback içinde child object'i destroy/realloc et, böylece cache'lenmiş pointer artık free edilmiş ya da attacker-shaped belleğe işaret etsin.
- Kernel'e geri dön; kernel stale pointer'ı dereference eder — UAF burada.
Public test case 10 — UnlockNotifyWindow
win32kfull!UnlockNotifyWindow, pMenu->rgItems içine bir pointer cache'ler, sub-menu'lara
recurse eder ve user mode'a ulaşabilen win32kbase!HMAssignmentUnlock()'ı çağırır. O
callback sırasında items array'ini realloc eden bir attacker, saklanan pointer'ı geçersiz
kılar. Bu, public repository'deki ~13 belgelenmiş vakadan biridir.
Bu bug sınıfı, win32k user-mode callback abuse ile yakından ilişkilidir ve onunla örtüşür; temelde yapılandırılmış bir use-after-free'dir.
Detection¶
- Fuzzing/triage sinyali: Araştırmacılar bunları
win32k*.sysüzerinde Driver Verifier Special Pool + Pool Tracking etkinken buldu; Special Pool'a yerleştirilmiş free edilmiş bir child object, stale dereference'ta hemen fault verir ve birxxxcallout path'i içinde temiz bir crashing PC üretir. - Telemetry: EDR, bir low-integrity process'in custom window procedure'ü içinden verilen
olağandışı window/menu lifecycle çağrısı dizilerini (
SetWindowLongPtr,DestroyMenu, class-extra-bytes manipülasyonu) işaretleyebilir. - Crash forensics: faulting frame'i, tag'iyle artık eşleşmeyen bir pool pointer'ını
dereference eden bir
win32kfull!xxx*/HMAssignment*routine'i olan bugcheck'ler bu sınıfın güçlü göstergeleridir.
Mitigation¶
- Patch: Microsoft, etkilenen child-object path'lerine eksik lock/reference handling'i kademeli olarak ekledi; win32k'yı güncel tut.
- Type isolation: win32k type isolation bu object tiplerini dedicated pool'lara ayırarak reallocation adımının değerini düşürür. Bkz. win32k type isolation mitigation.
- Attack-surface azaltma: Win32k syscall filtering (
PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY), sandbox'lı renderer'lar için bu surface'i tamamen kaldırır. - Post-corruption hardening: KASLR, kCFG ve pool integrity, UAF'ı kullanılabilir bir read/write'a çevirmenin maliyetini artırır.