Page table manipulation attack (PTMA)¶
Attacker-controlled byte'ları bir hardware page-table page'iyle overlap ettiren, sonra arbitrary bir physical mapping forge etmek için bir Page Table Entry (PTE)'yi düzenleyen data-only bir attack — herhangi bir code execution olmadan DEP/NX, SMEP, SMAP ve CFI'yi bypass eder.
Mechanism¶
Note
Bir hardware page table yalnızca bellektir: her PTE, bir physical frame number (PFN) artı
permission/status flag'leri tutan 64-bit'lik bir word'dür. CPU bu entry'leri her erişimde
walk eder, bu yüzden bir PTE yazabilirsen, bir virtual page'i seçtiğin herhangi bir physical
frame'e remap edebilirsin. PTMA bu invariant'ı istismar eder: kernel, MMU'nun zaten
güvendiği bir PTE'yi asla yeniden doğrulamaz, bu yüzden tek bir forge edilmiş entry sana
arbitrary physical memory üzerinde read/write verir — kernel text ve struct cred dahil.
Hiçbir instruction pointer hijack edilmez, bu yüzden DEP/NX, SMEP/SMAP, KASLR ve CFI'nin hepsi
ilgisizdir; attack tamamen data-only'dir. Zor kısım, controlled byte'larını canlı bir page
table ile physically çakıştırmaktır; bu, free edilmiş bir object ile taze allocate edilmiş bir
PTE page'i aynı physical page'i paylaşacak şekilde bir cross-cache / page-spray reclaim ile çözülür.
Walkthrough¶
x86-64'te bir PTE, PFN'i 12–51 bit'lerinde ve flag'leri low/high bit'lerde encode eder:
PTE = 0xe800098952ff43 (example from the Dirty Pagetable writeup)
| | |
NX/PKey PFN flags (_PAGE_PRESENT=bit0, _PAGE_RW=bit1, _PAGE_USER=bit2 ...)
Adımlar (Dirty Pagetable kurgusunu izleyerek):
/* 1. Trigger heap bug (UAF / double-free / OOB) on a victim object. */
/* 2. Cross-cache reclaim: free the victim slab so its page returns to the
page allocator, then spray user page tables so a PT page reuses it.
"The single sharing page and page table are allocated from the same
migrate free_cache with the same order." */
/* 3. The freed object now physically overlaps a live PTE array. A write
primitive through the dangling object becomes a PTE write. */
uint64_t *evil_pte = victim_write_window; /* aliases real page-table memory */
*evil_pte = (target_phys & PFN_MASK) | _PAGE_PRESENT | _PAGE_RW; /* forge mapping */
Entry'yi kullanılabilir bir primitive'e dönüştürmek:
/* 4. Point the forged PTE at kernel physical memory, then dereference the
corresponding userspace virtual address to read/write kernel data. */
char *win = mmap_addr_covered_by(evil_pte);
/* reads/writes now hit target_phys: patch modprobe_path, cred.uid, SELinux state, ... */
Writeup'ta belirtilen kısıtlar
PTE'nin physical-address field'ı tamamen serbest değildir: writeup şunu gözlemler: "bit18 is
located in the physical address of the PTE, which means that if we don't bypass the
limitation, we can only patch the kernel where the bit18 of the physical address is 1."
Flag bit'leri (örn. bit 8 / bit 18 üzerinde sigdelsetmask() etkileşimleri üzerinden), ek bir
bypass olmadan hangi physical hedeflerin erişilebilir olduğunu kısıtlar, bu yüzden hedef seçimi
serbest bir değişken değil, exploit'in parçasıdır.
Bir 2024 varyantı ("Flipping Pages", CVE-2024-1086), PTMA'yı page-table hiyerarşisinde bir seviye
yukarı taşır: bir PMD page'i ve bir PTE page'i aynı physical frame'e double-allocate ederek,
bir userland address'ine (0x40000000) yapılan bir write doğrudan PTE word'ünü düzenler.
Bir fork() + munmap(), TLB'yi flush eder ki forge edilmiş translation etkili olsun, sonra
eşleşen higher-level address'in bir read'i arbitrary physical memory'yi dereference eder — orada
modprobe_path'i bulup overwrite etmek için kullanıldı.
Warning
Reclaim adımı kırılgan kısımdır. PTE page'leri page allocator'ın order-0 PCP list'lerinden gelir; victim slab page'i, spray'den önce aynı migrate type ve order'a zorlanmalıdır, aksi halde forge-edilmiş-PTE alias'ı asla materyalize olmaz. Eşleşmeyen order/zone basitçe iyi huylu bir page verir.
Detection¶
Bir heap free'sinin hemen ardından gelen anomalili page-table allocation churn'ü (mmap/fault
fırtınaları üzerinden mass PTE/PMD allocation) ve overwrite edilmiş bir modprobe_path veya
kernel-physical frame'lerin bir user address space'ine beklenmedik mapping'leri gibi post-exploit
imzaları.
Mitigation¶
- PT-Rand ve ilgili savunmalar, page-table memory'sini randomize/izole eder ki attacker byte'ları canlı bir PTE array ile güvenilir şekilde co-locate edilemesin.
- Page/slab isolation (örn.
SLAB_VIRTUAL, slab page'leri page-allocator page'lerinden ayırmak), PTMA'nın dayandığı cross-cache reclaim'i kırar. CONFIG_INIT_ON_ALLOC_DEFAULT_ON, allocation'da page'leri sıfırlar; bazı forge-edilmiş-PTE reuse path'lerini bozar (ve belirli v6.4+ akışlarındabad_page()detection'ını tetikler).
Ayrıca bkz. Dirty Pagetable (data-only page-table attack), page-level cross-cache attack.