Page Table Manipulation (SMEP/SMAP defeat via PTE rewrite)¶
Bir bug-class notu: saldırgan page-table entry'lerini (doğrudan ya da bir kernel write primitive aracılığıyla) yazabildiği anda SMEP/SMAP/W^X çöker — çünkü o savunmalar tam da yeniden yazılan PTE bitleri üzerinden ifade edilir.
Mechanism¶
Note
SMEP, SMAP ve kernel W^X bağımsız çitler değildir — her erişimde MMU
tarafından page-table-entry permission bitlerine karşı yorumlanırlar. SMEP,
supervisor mode'dayken PTE'sinde user (U/S) biti set olan bir page'i execute
etmeyi reddeder; SMAP böyle bir page'i okumayı/yazmayı reddeder; W^X
(CONFIG_STRICT_KERNEL_RWX) code page'lerini non-writable, data page'lerini
non-executable olarak işaretler. Kernel self-protection belgeleri kuralı açıkça
belirtir: "code is not writable, data is not executable, and read-only data is
neither writable nor executable," ve "any areas of the kernel with
executable memory must not be writable." Savunucunun invariant'ı bu yüzden
page-table integrity'dir: permission bitleri ve onları tutan page-table
page'leri, bir corruption primitive'ine karşı kendileri değişmez olmalıdır.
Eğer saldırgan bir PTE'yi flip edebilirse — bir user page'de U/S'yi clear etmek
(onu artık "user" olmaktan çıkarır ve SMEP'i geçer), kernel text'inde writable
bitini set etmek veya NX'i clear etmek — hardware sadakatle saldırganın
policy'sini uygular. Kontrol başarısız olmadı; girdisi yeniden yazıldı.
Page-table page'lerinin yüksek değerli bir hedef olmasının sebebi budur: tek bir PTE yazımı, bir userland page'ini kernel-executable bir page'e çevirip CR4'e hiç dokunmadan SMEP'i etkisiz hale getirebilir.
Walkthrough¶
Temsili bir zincir (kavramsal; corruption primitive'inin önceden var olduğu varsayılır):
1. attacker has a kernel arbitrary-write (or controls a PTE-sized field)
2. locate the PTE backing a user-controlled page (or kernel text)
3. rewrite the entry:
- clear _PAGE_USER -> page no longer "user" -> SMEP/SMAP stop policing it
- set _PAGE_RW -> kernel text becomes writable (defeats W^X)
- clear _PAGE_NX -> data page becomes executable
4. the MMU now enforces the rewritten permission; control/data flow proceeds
İlgili yayınlanmış varyantlar, code pointer'ları yerine page-table data'sının kendisini hedef alır: klasik code-pointer hijacking olmadan kernel kontrolündeki mapping'lere ulaşan Dirty Pagetable ve set_memory_x page-table attack'a bakın. ret2dir sonucu ikiz problemdir: bir PTE'yi yeniden yazmak yerine, zaten saldırgan kontrolündeki bir user page'inin bir "synonym"'i olan mevcut iyi huylu bir kernel mapping'ini (physmap direct map) suistimal eder, "circumventing checks that distinguish user from kernel addresses."
Savunmanın açık olduğunu doğrulama (savunucu tarafı):
# W^X / strict RWX present in config
CONFIG_STRICT_KERNEL_RWX=y
CONFIG_STRICT_MODULE_RWX=y
# CPU features that the PTE bits feed into
grep -o 'smep\|smap' /proc/cpuinfo # SMEP/SMAP supported & enabled
Detection¶
- Page-table page'lerinin integrity monitoring'i: page-table page frame'leri
üzerinde hypervisor-/IOMMU-destekli watchpoint'ler ya da kernel text'inin ve onun
PTE'lerinin periyodik hashing'i, beklenmedik
_PAGE_RW/_PAGE_NX/_PAGE_USERgeçişlerini yüzeye çıkarır. - Invariant denetimi: hem writable hem executable olan bir kernel page'i veya supervisor context'inde executable map'lenmiş bir "user" page'i, tanımı gereği bir W^X / SMEP ihlalidir ve hardened bir kernel'de asla oluşmamalıdır.
- Allocator/ownership sinyalleri: ret2dir tarzı suistimal, user frame'lerinin physmap alias'larına düşen kernel erişimleri olarak görünür — hangi frame'lerin user'a ait olduğunu bilen bir exclusive-ownership şemasına gözlemlenebilir.
Mitigation¶
- Page table'ları kernel data path'ine read-only yap. Page-table page'lerini ve kritik table'ları (IDT/GDT/syscall table) read-only işaretleyen hardening, her yeniden yazmayı başıboş bir write yerine açık, denetlenebilir bir yoldan geçmeye zorlar — PaX KERNEXEC'in "page tables read-only" ayarlayarak yaptığı tam olarak budur.
- U/S'yi uçtan uca anlamlı tut SMEP/SMAP ve KPTI ile, böylece MMU'nun okuduğu bitler tek savunma hattı olmaz; software eşdeğeri PaX UDEREF, bir PTE biti bypass edilse bile user/kernel ayrımını uygular.
- Altta yatan write'ı reddet. PTE yeniden yazımı bir kernel write primitive'i gerektirir; allocator hardening, hardened usercopy ve CFI bir tane elde etmenin çıtasını yükseltir. Physmap-synonym varyantı için, üstü kapalı alias'ı eXclusive Page Frame Ownership ile ortadan kaldırın.