Skip to content

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'ten prepare_kernel_cred/commit_creds chain'le.

SMAP ile birlikte çalışır; PaX eşdeğerini daha önce KERNEXEC olarak göndermişti.

References