GDI Palette object arbitrary R/W primitive (pFirstColor/cEntries)¶
Bozuk bir Windows kernel GDI
PALETTEobjesinin, dokümante edilmişGet/SetPaletteEntriesAPI'leri aracılığıyla tek bir write-where bug'ını kararlı bir arbitrary kernel read/write'a nasıl dönüştürdüğünün kavramsal kataloğu.
Mechanism¶
Kırılan invariant
Bir GDI PALETTE (kernel'da _XEPALOBJ), color table'ı attacker açısından
iki alanla tanımlanan pool-backed bir objedir: pFirstColor (entry array'ine
bir pointer) ve cEntries (entry sayısı). Dokümante edilmiş user-mode API'leri
GetPaletteEntries / SetPaletteEntries (ve AnimatePalette) tam olarak
user mode adına color data'yı kernel objesinin içine ve dışına kopyalamak
için vardır.
Security boundary aşılır çünkü o trusted copy routine'leri körü körüne objenin
kendi pFirstColor/cEntries'ine güvenir. Ayrı bir kernel write-where bug'ı
pFirstColor'ı arbitrary kernel memory'ye işaret edecek şekilde bozarsa (ya da
cEntries'i şişirerek in-bounds görünen index'lerin sonun ötesini okumasını
sağlarsa), aynı yetkilendirilmiş user→kernel kopyası artık attacker'ın
nişanladığı yere okur ya da yazar. Code execution gerekmez: primitive tamamen
bozuk bir data pointer artı meşru API çağrılarından kurulur.
Walkthrough¶
Üst-seviye, public research'ten (SensePost, HITB 2018):
- Bir write primitive seed'le. Bir pool overflow / write-where bug'ı, bitişik
bir
PALETTE'inpFirstColor'ını ya dacEntries'ini bozmak için kullanılır. - Manager + worker pattern'i. Reliability için bir manager palette, ikinci
bir worker palette'in
pFirstColor'ını overwrite etmekte kullanılır. Manager ardından worker'ı talep üzerine herhangi bir kernel adresine yeniden nişanlar. - Read/write.
GetPaletteEntries(worker, ...)nişanlanan adresteki kernel memory'yi okur;SetPaletteEntries(worker, ...)onu yazar. 2. adımı tekrarlamak bunu tekrarlanabilir bir arbitrary R/W yapar. - Escalate. Tipik olarak
EPROCESS'i leak/lokalize etmek ve SYSTEM token'ını çalmak için kullanılır (bkz.eprocess-token-stealing).
Kavramsal şekil
corrupt(worker.pFirstColor = TARGET); GetPaletteEntries(worker) -> *TARGET
Detection¶
- Çok sayıda palette/bitmap oluşturup ardından sıkı
Set/GetPaletteEntriesdöngüleri issue eden process'ler, özellikle low-integrity / sandboxed bir process'ten. PALETTE/SURFACE'a referans verenwin32k/win32kbasepool-corruption bugcheck'leri.- GDI obje churn'ünün ardından local privilege-escalation davranışı (token swap).
- Tarihsel KASLR öncülü: PEB'den
GdiSharedHandleTableokumaları.
Mitigation¶
- GDI Type Isolation (Windows 10 1709+)
SURFACE/Bitmap header'larını attacker'ın erişebildiği data buffer'larından ayırarak Bitmap-as-target tekniğini zorlaştırır; ancak bu mitigation SURFOBJ/Bitmap header'ları için tasarlanmıştı ve palette corruption path'ini kırmaz — araştırmacıları geriye kalan bir vektör olarak PALETTE nesnelerine yönlendiren şey tam da budur. Çıtayı yükseltir, sınıfı kapatmaz (bkz.win32k-type-isolation-mitigation). - User-mode
GdiSharedHandleTablekernel-address leak'inin kaldırılması (1607). - Kernel pool integrity hardening, SMAP ve (Win11) kernel CFG.
- Corruption'ı seed'leyen upstream write-where bug'ını ortadan kaldır.