Skip to content

Speculative Probing Code-Region Derandomization (BlindSide variant)

Crash-bastırılmış speculative control-flow hijacking, tek bir memory write'ı hiç crash olmadan kernel kodunu (KASLR ve hatta fine-grained / execute-only şemaları) derandomize eden bir blind probing primitive'ine dönüştürür.

Mechanism

Note

Kavramsal: NEDEN çalışır, invariant/teori.

Klasik BROP (Blind Return-Oriented Programming), bilinmeyen bir address space'i bir return address'i üzerine yazarak ve process'in crash edip etmediğini gözlemleyerek prob'lar. Crash/no-crash oracle'ı, deneme başına bir bit layout bilgisi sızdırır — ama her yanlış tahmin gözlemlenebilir bir fault üretir (çökmüş bir worker, bir kernel oops'u). Bu yüzden defender'lar probing'i tespit eder veya rate-limit'ler ve kernel'de tek bir yanlış probe genellikle tüm sistem için ölümcüldür.

BlindSide ("Speculative Probing") crash'i kaldırır. Temel içgörü şudur: bir speculation window içinde üretilen fault'lar, processor misspeculate edilmiş yolu geri aldığında ezilir — asla architectural exception'lara dönüşmezler. Speculation'ı (ör. zehirlenmiş bir conditional branch veya memory-corruption tabanlı bir speculative control-flow hijack üzerinden) attacker'ın seçtiği bir adresin prob'una yönlendirerek, attacker şunu yapabilir:

  • map'lenmiş/geçerli olabilen veya olmayan bir adresi dereference / call etmek,
  • adres "iyi" ise CPU'nun o yol boyunca speculative olarak çalışmasını sağlamak, side effect olarak bir cache line'a dokunmak,
  • ve adres "kötü" ise hiç architectural crash yaşamamak, çünkü fault, misspeculate edilmiş işin geri kalanıyla birlikte bastırılır.

Probe sonucu sonra bir crash oracle değil, bir microarchitectural side channel (tipik olarak bir Flush+Reload cache covert channel) üzerinden geri okunur. BlindSide'ın dayandığı invariant budur: speculative execution transient yolu çalıştırır ve fault'lar dahil architectural state'i atar, microarchitectural state'i (cache) gözlemlenebilir bırakırken.

Oracle sessiz olduğundan, attacker bunu milyonlarca kez tekrarlayarak şunları yapabilir:

  1. KASLR'ı kır — biri "isabet" edene kadar aday adresleri prob'layarak kernel base'ini / bilinen kod bölgelerini bul.
  2. Speculative BROP düzenle — ROP tarzı gadget'ları kör şekilde bul, BROP'un taradığı gibi ama speculative olarak, hiç crash etmeden kod tarayarak.
  3. Fine-grained ve arbitrary-strong randomization'ı yen, execute-only memory (XOM) dahil, çünkü speculative read/call'lar XOM'un architectural olarak yasakladığı kod-bölgesi içeriklerini sızdırabilir ve data-only veya JIT-ROP tarzı takipleri mümkün kılar.

Saldırı, bir memory write vulnerability'si (control-flow hijacking için klasik ön koşul) ve kullanılabilir bir speculation primitive'i artı cache side channel varsayar. Intel Skylake–Coffee Lake ve AMD Zen+ / Zen 2 sınıfı core'lara karşı gösterildi ve yazarlar 4 dakikadan kısa sürede tamamen remote bir KASLR break sergiledi.

Walkthrough

Saldırının kendisi vulnerable bir target ve microarchitectural ölçüm gerektirir; aşağıda, ön koşulları muhakeme etmek ve mitigation'ları gözlemlemek için yetkili bir lab makinesinde çalıştırabileceğiniz defender-odaklı bir walkthrough var.

BlindSide'ın dayandığı speculation-sınıfı mitigation'ların (branch prediction control) aktif olup olmadığını teyit edin:

grep -r . /sys/devices/system/cpu/vulnerabilities/ 2>/dev/null

Mitigate edilmiş bir host'ta beklenen (örnek) çıktı:

/sys/devices/system/cpu/vulnerabilities/spectre_v2:Mitigation: Retpolines, IBPB: conditional, ...
/sys/devices/system/cpu/vulnerabilities/spectre_v1:Mitigation: usercopy/swapgs barriers and __user pointer sanitization

KASLR'ın (BlindSide'ın derandomize ettiği şey) enabled olup olmadığını kontrol edin:

# 'nokaslr' on the cmdline disables it; its absence means KASLR is on
cat /proc/cmdline
# Compare a known symbol's runtime address across two boots to see entropy
sudo grep ' _stext$' /proc/kallsyms

Beklenen: KASLR aktifken _stext'in adresi boot'lar arasında farklılaşır (gerçek değerleri görmek için kptr_restrict=0 gerekebilir — bkz. kptr-restrict).

Attacker'ın sürdüğü kavramsal probing loop'u şöyle görünür (pseudo-code; speculative yoldur, architectural değil):

/* attacker controls a speculative control-flow hijack that lands here */
if (mispredicted_condition) {       /* squashed after resolution */
    probe = *(volatile char *)guess; /* fault suppressed if 'guess' bad */
    reload_line[ probe ];            /* cache footprint = leaked bit */
}
/* architecturally: nothing happened, NO crash */

Attacker sonra reload_line[]'ı Flush+Reload ile zamanlayarak guess'in geçerli bir mapping olup olmadığını öğrenir ve kernel base geri kazanılana kadar aday KASLR aralığı boyunca tekrarlar.

Detection

  • BlindSide özellikle crash-free olacak şekilde tasarlanmıştır, bu yüzden klasik sinyal (BROP taramasından gelen tekrar eden segfault'lar / kernel oops'ları) büyük ölçüde yoktur. Crash sayılarına güvenmeyin.
  • Yüksek-oranlı Flush+Reload aktivitesi (cache-flush instruction'ları, anormal LLC miss pattern'ları) kalıntı sinyaldir; anormal cache-eviction oranları için CPU performance-counter izleme gerçekçi detection yüzeyidir, ancak gürültülüdür.

Mitigation

  • Speculation primitive'ini ortadan kaldırın. BlindSide control flow'u speculative olarak hijack eder; speculative target'ları kısıtlayan software/hardware control-flow integrity çıtayı yükseltir. Yazarlar coarse CFI'ın yetersiz olduğunu belirtir. Bkz. kernel-control-flow-integrity ve fineibt.
  • Speculation-control mitigation'larını açık tutun (IBPB/IBRS/retpoline) ki attacker branch prediction'ı kolayca zehirleyemesin — bkz. retpoline ve indirect-branch-prediction-barrier.
  • Tek başına randomization (fine-grained / execute-only olsa bile) burada kalıcı bir savunma değildir, çünkü speculative read'ler architectural XOM garantisini bypass eder — bkz. kernel-address-space-layout-randomization.

References