Data-only kernel exploit technique ported to 24H2¶
Windows 11 24H2
PreviousModeread/write primitive'ini kaldırdıktan sonra, bir data-only escalation,SeDebugPrivilege'i flip etmek içinSepDuplicateToken()'daki_TOKENreference-counter increment'ini yeniden kullanır.
Mechanism¶
Bir data-only attack, bir kernel read/write primitive'ini control flow'u hijack etmeden privilege escalation'a çevirir ve CFG/HVCI/kCET'i yener. Uzun süredir kullanılan Windows data-only primitive'i _KTHREAD.PreviousMode'du: onu UserMode (0)'a set etmek, Nt* memory API'lerinin (NtReadVirtualMemory / NtWriteVirtualMemory) kernel address'leri user mode'dan istenmiş gibi ele almasını sağlar ve tam arbitrary read/write verir. Windows 11 24H2 PreviousMode tekniğini öldürdü ve eski yöntemin side-effect'leri de cleanup için aynı API'lere bağlıydı, ki bu imkânsız hale geldi.
Note
24H2 yerine geçen şey, token duplication'dan kurulmuş saf bir arbitrary-increment primitive'i. _TOKEN.BnoIsolationHandlesEntry, bir _SEP_CACHED_HANDLES_ENTRY'ye işaret eder:
struct _SEP_CACHED_HANDLES_ENTRY {
struct _RTL_DYNAMIC_HASH_TABLE_ENTRY HashEntry; // 0x00
LONGLONG ReferenceCount; // 0x18
struct _SEP_CACHED_HANDLES_ENTRY_DESCRIPTOR EntryDescriptor; // 0x20
ULONG HandleCount; // 0x38
VOID** Handles; // 0x40
};
SepDuplicateToken() çalıştığında ve entry'nin ReferenceCount'u (offset 0x18) sıfır olmadığında, başka hiçbir side effect olmadan basitçe o 64-bit field'ı increment eder. Kernel write kontrolüne sahip bir attacker BnoIsolationHandlesEntry'yi target - 0x18'e işaret ettirirse, her token duplication target'taki 8 byte'ı increment eder. Bu, herhangi bir kernel address üzerinde nişanlanmış bir ++'tır.
Warning
Primitive yalnızca increment edilen değer 0x1 - 0x7fffffffffffffff aralığında kaldığı sürece güvenli. Duplication sırasında sıfır veya aralık-dışı bir değer bir bugcheck'e (BSOD) yol açar, yani hedef byte zaten sıfır olmamalı ve increment sayısı sınırlı olmalı.
Walkthrough¶
Amaç, mevcut process token'ının privilege bitmap'lerinde SeDebugPrivilege'i enable etmek. _TOKEN.Privileges (_SEP_TOKEN_PRIVILEGES) üç 8-byte bitmap tutar: Present, Enabled ve EnabledByDefault; bu escalation yalnızca Present ve Enabled'ı hedefler. SeDebugPrivilege bit 0x14'tür (bit 20).
Primitive yalnızca increment ettiği için, bitmap'in tek bir byte'ını hedefler ve o byte içinde istenen biti set etmek için gereken miktarda increment edersin:
// pseudocode for one bitmap (Present, then Enabled)
// priv = SeDebugPrivilege bit index = 0x14
// byte_off = priv >> 3 // which byte of the 8-byte bitmap
// amount = 1 << (priv & 7) // increment to set the bit in that byte
// 1. Aim BnoIsolationHandlesEntry so the counter sits on the chosen byte:
// BnoIsolationHandlesEntry = process_token + Privileges.Present
// + byte_off - 0x18;
write_kernel_ptr(token + offsetof_BnoIsolationHandlesEntry, target - 0x18);
// 2. Duplicate the token 'amount' times; each call increments the byte.
for (i = 0; i < amount; i++)
DuplicateTokenEx(hToken, ..., &hDup[i]);
// 3. Repeat for Privileges.Enabled so the privilege is both present
// and enabled.
SeDebugPrivilege, mevcut _EPROCESS'in token'ında present ve enabled olunca, process tam escalation için bir SYSTEM process'i açabilir ve içine inject edebilir.
Cleanup ve self-correction
Çoğaltılmış token handle'larını kapatmak, SepDuplicateToken'ın karşılığının reference counter'ı decrement etmesini sürer, böylece işin bitince hDup[] handle'larını kapatmak bitmap byte'ını geri aşağı yürütür, inject edilmiş privilege'ı otomatik olarak düşürür ve yırtık (torn) bir token state'inden kaçınır.
Detection¶
- Kendi
_TOKEN'ına önceki bir kernel write ile ilişkili birDuplicateTokenExçağrısı patlaması yapan bir user-mode process anormaldir; EDR,Privileges.Present/Enabled'ı meşru bir atama olmadanSeDebugPrivilegekazanan token'ları işaretleyebilir. - HVCI / Kernel CFG data-only flip'leri durdurmaz; ilk kernel write primitive'ini reddetmek için attack-surface reduction'a (driver blocklist) güven.
Mitigation¶
- Alttaki kernel read/write primitive'ini (exploit edilen zafiyetli driver'ı) ele; teknik, birinin zaten var olduğunu varsayar.
- Microsoft'un 24H2
PreviousModehardening'i, bu port'u zorlayan mitigation'ın ta kendisidir; token reference-count path'lerinin sürekli hardening'i veBnoIsolationHandlesEntry'nin doğrulanması bu varyantı kapatırdı. - Primitive'i en baştan elde etmenin maliyetini artırmak için HVCI'yi, vulnerable-driver blocklist'i ve Credential Guard'ı enable et.