Win32k Window Object Type Confusion (CVE-2021-1732)¶
xxxCreateWindowExsırasındaki bir user-mode callback'in, bir window'un extra-bytes storage mode'unu ve flag'ini birbiriyle uyumsuz bıraktığı bir win32kfull LPE; kernel bir offset'i pointer sanıyor ve sonuç OOB write -> arbitrary R/W -> SYSTEM oluyor.
Mechanism¶
Bug sınıfı: user-mode callback boyunca flag/type desync
Bir window object (tagWND), class'ına ait "extra bytes" değerini iki modda
saklayabilir:
- Mode 1 — buffer user-space heap'te tutulur ve raw pointer
tagWND.pExtraBytesiçinde durur. - Mode 2 — buffer kernel desktop heap'tedir (
NtUserConsoleControltarafından kurulur); buradapExtraBytes, desktop heap'e bir offset tutar ve birextraFlagbit'i bunun offset tabanlı olduğunu işaretler.
xxxCreateWindowEx sırasında win32k, xxxClientAllocWindowClassExtraBytes üzerinden
user mode'a geri çağrı (callback) yapar. Güvenlik açığı şu: bir saldırgan tam o
callback'in içinde window'u Mode 1'den Mode 2'ye geçirebilir (offset flag'ini set
eder) ve NtCallbackReturn üzerinden arbitrary bir değer döndürebilir. Kernel kaldığı
yerden devam ettiğinde bu arbitrary değeri pExtraBytes'a az önce set edilen flag'i
temizlemeden yazar — yani field artık saldırganın seçtiği bir sayıdır ve kernel bunu
daha sonra güvenilir bir desktop-heap offset'i olarak yorumlar. Data değeri ile type
flag'i uyumsuzdur: bir offset, pointer'a benzer bir miktarmış gibi karıştırılır ve bu da
desktop heap içindeki (ve ötesindeki) memory safety'yi kırar.
Walkthrough¶
Yüksek seviyede; public root-cause analizlerinden (Project Zero ITW, DBAppSecurity/iamelli0t). 2021 başında BITTER APT tarafından in the wild exploit edildi.
- Callback'i hook'la:
PEB.KernelCallbackTableüzerindenxxxClientAllocWindowClassExtraBytesslot'unu yönlendir ki window oluşturma sırasında saldırgan kodu çalışsın. - Flag'i desync et: hook'un içinde
NtUserConsoleControlçağırarak offset-mode flag'ini set et, ardındanNtCallbackReturnile kontrollü bir değer döndür. Kernel değeri commit eder ama flag'i set bırakır. - OOB write: oluşan confusion'ı kullanarak komşu bir window'un
cbWndExtra(extra-bytes uzunluğu) değerini büyük bir sayıyla overwrite et; böylece o window artık gerçek sınırlarının çok ötesine read/write yapabilir. - Arbitrary read: victim window'un menu pointer'ını (
spMenu) bozarakGetMenuBarInfoüzerinden kernel memory'sini parça parça oku. - Arbitrary write: aşırı uzun extra bytes üzerinden
SetWindowLongPtrkullanarak kontrollü write'lar yap. - Privesc:
EPROCESS/token adreslerini leak et ve SYSTEM process token'ını exploit eden process'in token'ının üzerine kopyala.
CVE-2022-21882 olarak yeniden ortaya çıktı
Aynı callback/flag desync pattern'i, orijinal fix'ten sonra CVE-2022-21882 olarak geri döndü; bu da altta yatan sınıfın tek bir offset kontrolü değil, user-mode-callback re-entrancy olduğunu vurguluyor.
Detection¶
- Bir process'in kendi
PEB.KernelCallbackTable'ına anormal write'lar veyauser32.dlldışına işaret eden callback entry'leri. - Bir window-creation callback'inin içinden çağrılan
NtUserConsoleControl, üstelik büyük/sıra dışı değerler döndürenNtCallbackReturnile birlikte. - İmza niteliğindeki primitive zinciri: bir window'un
cbWndExtradeğerinin devasa bir sayıya şişmesi, ardından düşük yetkili bir process'ten beklenmedik handle'lara karşıGetMenuBarInforead'leri veSetWindowLongPtrwrite'ları. - Post-exploitation: az önce yoğun USER32 window aktivitesi yapmış bir process'in integrity/token elevation'ı.
Mitigation¶
- CVE-2021-1732 (Şubat 2021) ve CVE-2022-21882 (Ocak 2022) için patch uygula. Fix, callback öncesi state'e güvenmek yerine extra-bytes storage mode'unu callback'ten sonra yeniden doğruluyor.
- GDI/USER'a ihtiyaç duymayan process'ler için Win32k system-call filtering'i etkinleştir ki callback ile erişilebilen yüzey ortadan kalksın.
- Defence-in-depth: HVCI/VBS, SMEP/SMAP ve Credential Guard, ortaya çıkan kernel R/W ile token-theft adımının değerini düşürür.
References¶
- CVE-2021-1732 RCA — Google Project Zero (0-days in the wild)
- CVE-2021-1732: win32kfull xxxCreateWindowEx callback OOB — iamelli0t
- Inside Win32k Exploitation Part 2: CVE-2022-21882 and CVE-2021-1732 — Unit 42