Supervisor Mode Execution Prevention¶
Intel CPU özelliği (CR4.SMEP, bit 20): ring-0 bir user-mapped page'den instruction fetch yaptığı anda page fault üretir; böylece klasik ret2usr escalation'ı öldürür.
Mechanism¶
Neden çalışır
CR4.SMEP = 1 (bit 20) olduğunda, CPU supervisor code'un (CPL < 3)
user-accessible (U=1) işaretli bir page'den yaptığı her instruction fetch'i
fault olarak ele alır. Control flow'u hijack edip RIP'i bir userland
buffer'a yönelten bir kernel-mode exploit — yani kanonik
ret2usr tekniği, ki burada saldırgan kendi kolayca
map'lenebilen, writable, RWX userspace'ine
commit_creds(prepare_kernel_cred(0)) shellcode'unu yerleştirir — artık o
kodu çalıştıramaz: ilk instruction fetch fault verir. SMEP böylece kernel
payload'unu barındırmanın en ucuz yerini ortadan kaldırır.
Invariant şudur: kernel asla user page'lerinden instruction çalıştırmaz. SMEP bunu her fetch'te hardware'de zorlar; dolayısıyla saldırgan ya control flow'u kernel koduna yöneltmeli (ROP) ya da önce SMEP'i kapatmalıdır.
Walkthrough¶
Linux'ta destek kontrolü:
grep -o '\bsmep\b' /proc/cpuinfo | head -1
# smep (present => CPU enforces SMEP; Intel, since 2012 / Ivy Bridge)
SMEP açıkken, userland'e düşen bir control-flow hijack hemen fault verir:
ring-0 RIP -> 0x00007fff_user_shellcode ; U=1 page
-> #PF (SMEP violation): instruction fetch from user page
5.1 öncesi CR4 üzerinden disable bypass'ı
CR4 pinning'den önce, exploit'ler bit 20/21 temizlenmiş halde
native_write_cr4()'ü, bir pop rdi ; ret gadget'ı ve 0x6f0 gibi bir CR4
değeriyle çağırıyordu:
pop rdi ; ret -> 0x6f0 ; CR4 with SMEP(20)/SMAP(21) cleared
mov cr4, rdi ; ret (native_write_cr4)
ret -> userspace escalation stub
Linux 5.1+ hassas CR4 bit'lerini read-only-after-init olarak pin'ler,
böylece bu write bir no-op'a dönüşür ve WARN_ONCE tetikler. Bkz.
Disable SMEP via CR4 ROP.
SMEP execution'ı durdurur, data'yı değil
SMEP, user page'lerini okuma/yazma hakkında bir şey söylemez — o iş SMAP'in işidir. Hiç user page çalıştırmayan saf data-only bir ROP chain SMEP'ten etkilenmez.
Detection¶
Bir SMEP ihlali, faulting RIP'i ring 0'dan alınmış bir user-mode adres olan bir page fault olarak görünür; kernel oops bir user page üzerinde instruction-fetch fault'u gösterir.
Mitigation¶
SMEP bir savunmadır; residual / bypass yüzeyi:
- CR4 bit'ini disable et — pinning öncesi CR4 ROP; CR4 pinning ile etkisizleştirilir.
- ret2dir / kernel-resident payload — kodu bir user page yerine attacker-controlled belleğin bir kernel alias'ından (physmap direct map) çalıştır; böylece SMEP hiçbir zaman bir user fetch görmez. İlgili: SMAP bypass via kernel-resident payload.
- set_memory_x page-table saldırısı — bir kernel page'i executable yap, bkz. set_memory_x page-table attack.
- BPF JIT spray — attacker-influenced byte'ları executable bir kernel JIT page'ine emit et, bkz. BPF JIT spray.
- Saf kernel ROP — hiç user page çalıştırma; kernel
.text'tenprepare_kernel_cred/commit_credschain'le.
SMAP ile birlikte çalışır; PaX eşdeğerini daha önce KERNEXEC olarak göndermişti.