Convert Write-Where to Write-What-Where via GDI objects¶
Sınırlı bir write-where / arbitrary-increment primitive'ini, GDI bitmap veya palette object'lerini corrupt ederek tam arbitrary read/write'a yükselten bir Windows kernel exploitation tekniği.
Mechanism¶
Sınırlı bir write neden tam R/W'ye dönüşür
Birçok kernel bug'ı yalnızca kısıtlı bir primitive verir — kontrol edilen bir
adrese yazılan sabit bir değer ya da bir increment. GDI object'leri mükemmel
"conversion gadget"lar oluşturur: bir GDI Bitmap'in kernel Surface'i (SURFOBJ)
bir size field'ı ve bitmap'in ilk scan line'ına bir pointer olan pvScan0'ı taşır
ve zararsız user-mode API'ları GetBitmapBits / SetBitmapBits belleği
doğrudan pvScan0 üzerinden okur ve yazar. pvScan0'ı overwrite etmek (ya da
bir bitmap'i komşu birine ulaşacak şekilde büyütmek) bu düzgün biçimli API'ları bir
arbitrary read/write primitive'ine çevirir. Aynı fikir GDI PALETTE object'lerine
pFirstColor/cEntries üzerinden uygulanır. Corrupt edilen pointer data olduğu
için teknik data-only'dir ve SMEP/SMAP/CFG'yi by-pass eder.
Walkthrough¶
Herkese açık Windows kernel-exploitation writeup'larından çıkarılan kavramsal reprodüksiyon.
- GDI bitmap'leri ikisi komşu olacak şekilde allocate et — bir manager bitmap'i ve bir worker bitmap'i.
- Bitmap'lerin kernel adreslerini process PEB'indeki
GdiSharedHandleTableüzerinden leak et. - Bug'ın sınırlı write'ını kullanarak ilk bitmap'i büyüt ya da manager'ın
pvScan0'ını worker'ınpvScan0'ına point edecek şekilde overwrite et. - Read: manager'ın pointer'ını bir hedef kernel adresine ayarla, ardından worker
üzerinde
GetBitmapBitsoradaki belleği döndürür. - Write: manager'ın pointer'ını bir hedefe ayarla, ardından worker üzerinde
SetBitmapBitsattacker data'sını oraya yazar. _EPROCESS'iPsInitialSystemProcess/ActiveProcessLinksüzerinden dolaş ve SYSTEM token'ını hedef process token'ının üzerine kopyala (bkz. EPROCESS token stealing).
İlgili conversion gadget'lar
Yakından ilişkili primitive'ler GDI bitmap arbitrary R/W primitive ve GDI palette object arbitrary R/W primitive'dir.
Detection¶
- Anormal bitmap/GDI handle churn'ünün ardından standart-kullanıcı bir process'in SYSTEM hâline gelmesi (token-swap telemetrisi).
- EDR tarafından işaretlenen process token integrity / parent-child anomalileri.
- GDI / win32k surface'lerine bağlı kernel crash'leri / pool-corruption bugcheck'leri.
- Exploit kodunun
GdiSharedHandleTable/ PEB'i şüpheli biçimde okuması. - AV/EDR'den Win32k / GDI exploit heuristic'leri.
Mitigation¶
- Low-IL process'ler için kernel-address leakage'ını ve
pvScan0erişimini kaldıran ve GDI type isolation ekleyerek klasik bitmap/palette primitive'lerini etkisizleştiren Windows 10 Anniversary / Creators Update ve sonrasında kal. - HVCI / VBS, Kernel CFG ve type-isolation savunmalarını etkinleştir.
- GDI attack surface'ini azaltmak için sandbox'lanmış process'ler için Win32k system-call filtering / lockdown'ı etkinleştir.
- Least privilege ile çalış ve EDR token-tampering tespitlerini kullan.
- Patch'leme yoluyla kernel pool hardening ve KASLR mitigation'larını güncel tut.