Skip to content

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.

  1. GDI bitmap'leri ikisi komşu olacak şekilde allocate et — bir manager bitmap'i ve bir worker bitmap'i.
  2. Bitmap'lerin kernel adreslerini process PEB'indeki GdiSharedHandleTable üzerinden leak et.
  3. Bug'ın sınırlı write'ını kullanarak ilk bitmap'i büyüt ya da manager'ın pvScan0'ını worker'ın pvScan0'ına point edecek şekilde overwrite et.
  4. Read: manager'ın pointer'ını bir hedef kernel adresine ayarla, ardından worker üzerinde GetBitmapBits oradaki belleği döndürür.
  5. Write: manager'ın pointer'ını bir hedefe ayarla, ardından worker üzerinde SetBitmapBits attacker data'sını oraya yazar.
  6. _EPROCESS'i PsInitialSystemProcess / 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 pvScan0 eriş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.

References