Skip to content

dxgkrnl / D3DKMT DirectX Graphics Kernel attack surface

dxgkrnl.sys — GPU scheduler (VidSch) ve video memory manager (VidMm) — win32k'ye benzer, low-integrity / AppContainer'dan D3DKMT* system call'larıyla erişilebilen geniş bir ring0 attack surface'tir; tarihsel olarak type confusion ve UAF bug class'larıyla LPE'ye yol açtı.

Mechanism

Note

DirectX graphics kernel subsystem üç kernel-mode driver'dan oluşur: dxgkrnl.sys (display port driver + scheduler), dxgmms1.sys ve dxgmms2.sys (memory management). User-mode caller bu koda D3DKMT* prefix'li native call'lar (ör. D3DKMTCreateAllocation, D3DKMTCreateContext, D3DKMTRender, D3DKMTEscape) üzerinden ulaşır. Bu yüzey win32k.sys gibi davranır: rendering ve GPU'nun düzgün çalışması için sandbox'lanmış process'ler dahi çağırabilmek zorundadır, dolayısıyla düşük privilege'dan doğrudan ring0 koduna geçiş sağlar.

Tekrar tekrar kırılan invariant: kernel, GPU nesnesi (allocation, context, device, resource) durumunu tanımlayan user-supplied handle'lara, flag'lere ve type discriminator'lara, transition sırasında yeterli validation yapmadan güvenir. DXGK nesneleri polymorphic'tir; bir field (ör. bir CrossAdapter flag'i ya da bir allocation type discriminator) hangi kernel struct'ının expected olduğunu belirler. Attacker bu discriminator'ı iki çağrı arasında değiştirebilirse, kernel bir nesneyi yanlış type olarak yorumlar (type confusion) veya bir handle serbest bırakıldıktan sonra tekrar kullanılır (use-after-free). Bunun sonucu genelde controlled write / pointer deref'tir.

Walkthrough

Aşağıdaki adımlar tamamen public, patch'lenmiş ZDI/Trend Micro "DirectX to the Kernel" çalışmasındaki bug class'ların conceptual özetidir; weaponize edilmiş bir zincir değildir.

Attack surface'e ulaşmak

// User mode, özel privilege gerekmez — AppContainer içinden bile reachable.
D3DKMT_CREATEDEVICE cd = {0};
cd.hAdapter = adapter;
D3DKMTCreateDevice(&cd);          // hDevice döner

D3DKMT_ESCAPE esc = {0};
esc.hAdapter = adapter;
esc.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
esc.pPrivateDriverData = user_blob;   // "completely user-controlled blob"
D3DKMTEscape(&esc);               // vendor DDI'ya tünel açar

Bug class 1 — Type confusion (CVE-2018-8405, ZDI-18-946, DXGDEVICE::CreateAllocation)

D3DKMTCreateAllocation'ın kernel implementasyonu, allocation'ın nasıl backing yapıldığını belirleyen CrossAdapter flag'ini validate etmez.

  1. Attacker bir allocation'ı CrossAdapter = 0 ile oluşturur ve dönen handle'ı saklar.
  2. Aynı handle ikinci bir CreateAllocation çağrısına CrossAdapter = 1 ile geçirilir.
  3. Kernel artık nesneyi farklı bir type/layout olarak yorumlar; bir alan yanlışlıkla pointer olarak dereference edilir ve memory corruption oluşur.

Type discriminator'ın two-call arası tutarlılığı hiç kontrol edilmediği için bu klasik bir confused-deputy/type-confusion primitive'idir ve SYSTEM'e yükselmeye yol açar.

Bug class 2 — Untrusted pointer dereference (CVE-2018-8400, DXGCONTEXT::ResizeUserModeBuffers)

Handler, user-supplied bir değeri pointer olarak dereference etmeden önce range/validity kontrolü yapmaz. Attacker bu değeri kontrol ettiği için, dereference'i attacker-chosen bir adrese yönlendirebilir — controlled read/write yönünde bir primitive.

Bug class 3 — Race / TOCTOU (UAF)

Birçok DXGK nesnesi paylaşılan scheduler ve VidMm state'ini refere eder. Bir thread bir context/allocation'ı destroy ederken paralel bir thread aynı handle üzerinde işlem yaparsa, driver serbest bırakılmış nesneyi tekrar kullanır. Bu class daha yeni patch'lerde de görülmeye devam etti (ör. 2025 DirectX Graphics Kernel UAF LPE, CVE-2025-55678). Freed pool chunk'ı controlled data ile reclaim edilirse UAF, ele geçirilmiş bir object pointer'ına dönüşür.

Warning

Bu yüzeyin tehlikesi altitude'da değil, reachability'de: D3DKMT* call'ları renderer/GPU-process sandbox'larından bilerek engellenmez, çünkü graphics fonksiyonelliği için gereklidir. Dolayısıyla bir dxgkrnl bug'ı, sandbox escape + LPE'yi tek adımda birleştirir.

Detection

  • Driver Verifier / special pool: dxgkrnl.sys, dxgmms1.sys, dxgmms2.sys üzerinde special pool ve Driver Verifier etkinleştirmek, OOB erişimleri ve UAF'leri test/lab ortamında crash anında yakalar.
  • ETW / EDR telemetry: Beklenmedik caller'lardan (ör. document viewer, browser renderer, non-graphics service) gelen anormal D3DKMT* çağrı desenlerini, özellikle CreateAllocation/CreateContext çağrılarını aynı handle ile art arda flag değiştirerek yapanları izle.
  • Crash forensics: dxgkrnl.sys frame'lerinde tekrar eden 0x1E/0x50/0xC4 bugcheck'leri veya pool corruption imzaları, in-the-wild exploitation denemesinin sinyali olabilir; live-dump'ları koru.
  • Integrity anomaly: Low-integrity ya da AppContainer token'lı bir process'in kısa süre sonra SYSTEM token'ıyla child spawn etmesi, DKOM-tabanlı token değişimini işaret eder.

Mitigation

  • Patch: İlgili KB güncellemelerini uygula — CVE-2018-8400/8405/8406 (Ağustos 2018) ve sonraki dxgkrnl UAF fix'leri (ör. CVE-2025-55678). Bu class için tek gerçek çözüm vendor patch'idir.
  • Kernel exploit mitigation'ları: kCFG (Control Flow Guard for kernel), VBS/HVCI ve kernel CET shadow stack, corruption'ı code-exec'e çevirmeyi zorlaştırır; type-confusion write primitive'ini tamamen engellemese de exploitation maliyetini yükseltir.
  • Attack surface reduction: Gerekmediği ortamlarda (ör. server/VDI headless host'lar) GPU/DirectX yükünü minimize et; win32k/GPU syscall filtering'i destekleyen sandbox policy'lerini (Win32k lockdown benzeri) uygula.
  • Least privilege: Multi-user, RDP ve VDI host'larda local LPE etkisi yüksek olduğu için untrusted kullanıcı sayısını ve interactive attack surface'i sınırla.

References