Prefetch Side-Channel KASLR Break¶
The
prefetchinstructions execute in data-dependent time: their latency leaks whether a virtual address is mapped and which translation-cache level holds its mapping — an unprivileged oracle that locates the kernel direct map and text, defeating KASLR.
Editorial note (unverified)
Bu not mekanizmayı ağırlıklı olarak attack açısından anlatır; mitigation/
kategorisindeki yeri ve savunma-altitude'u editorial re-review bekliyor.
Mechanism¶
Neden çalışır
prefetch* bir hint'tir: software-prefetch instruction'ları (prefetchnta,
prefetcht0/t1/t2, prefetchw) asla fault üretmez ve asla privilege kontrolü
yapmaz — CPU bunları yok saymakta serbesttir. Ama bunları bedava yok saymaz.
Hint'e göre hareket etmek için core, verilen virtual address'i translate etmek
zorundadır ve bu translation TLB ve paging-structure cache'lerini walk eder
(ya da hit eder). İşin miktarı — ve dolayısıyla instruction'ın yürütme süresi —
translation'ın ne kadarının zaten cache'lendiğine ve address'in hiç map'li
olup olmadığına bağlıdır.
Gruss ve diğerleri ("Prefetch Side-Channel Attacks", CCS 2016) bunu iki oracle'a dönüştürür. translation-level oracle, yalnızca timing'den, bir virtual address'in hangi seviyede (PML4/PDPT/PD/PT) map'li olmaktan çıktığını geri kazanır — bir process'in paging hiyerarşisini ve dolayısıyla ASLR/KASLR layout'unu yeniden inşa eder. address-translation oracle, kernel'in direct-physical map'inin tüm physical memory'yi alias'lamasını sömürür: bir user page'in (cache'lenebilir) direct-map alias'ını prefetch etmek o physical line için cache'i prime eder; bu da sonra user mapping üzerinden gözlemlenebilir — virtual→physical address'leri çözer ve direct map'i bulur. Timing farkı mimari olarak erişilemeyen mapping state'inden geldiği için ne SMAP, ne SMEP, ne de KASLR'nin randomize edilmiş base'i bunu gizler: map'li olan bir base'e "dokunmak" map'siz bir tahminden tutarlı şekilde daha hızlıdır.
Walkthrough¶
Çekirdek mantık, bir prefetch ardından ikinci bir erişimin rdtsc-parantezli
timing'idir; ölçüm prefetch etrafında reorder edilmesin diye serialize edilmiştir.
1. Bir probe address'inin serialize edilmiş timing'i. Kavramsal olarak, her aday kernel base address için prefetch'in sonraki erişim süresini nasıl etkilediğini ölçersiniz:
// inaccessible kernel virtual address candidate
static inline uint64_t probe(void *addr) {
uint64_t t0, t1;
asm volatile("mfence");
t0 = __rdtscp(&aux);
__builtin_prefetch(addr, 0, 0); // prefetchnta — never faults
t1 = __rdtscp(&aux);
asm volatile("mfence");
return t1 - t0; // cycles the prefetch itself took
}
rdtscp kısmen serializing'tir; prefetch'in translation işi ölçülen pencerenin içine
düşsün diye onu mfence/lfence ile eşleyin. Address başına çok sayıda sample'ın
ortalamasını alın ve gürültüyü bastırmak için minimum'u alın.
2. KASLR base adaylarını tara. Kernel image base'i küçük bir 2 MB hizalı slot kümesi üzerinde randomize edilir:
for (uint64_t base = KERNEL_LOW; base < KERNEL_HIGH; base += STEP) {
uint64_t min = ~0ULL;
for (int i = 0; i < TRIES; i++) {
uint64_t c = probe((void*)base);
if (c < min) min = c;
}
record(base, min); // mapped base => systematically lower minimum
}
Map'li (gerçek) base, map'siz tahminlere göre daha hızlı prefetch olur çünkü translation paging-structure cache'lerinde/TLB'de mevcuttur; aykırı (outlier) base sızdırılan KASLR offset'idir.
3. ret2dir / direct-map çözümlemesi (address-translation oracle). Bilinen bir user physical page'in direct-map alias'ını prefetch etmek ve ardından user mapping'in timing'ini ölçmek virtual→physical ilişkisini çözer; direct-physical map'in nerede yaşadığını açığa çıkarır — makalenin SMAP'i bypass etmek ve ret2dir'i mümkün kılmak için kullandığı yapı taşı.
Bu bir timing oracle, leak primitive değil
Prefetch ayrıcalıklı veriyi bir register'a okumaz. Yalnızca sonradan timing'ini ölçtüğünüz microarchitectural state'i (cache/TLB doluluğu) değiştirir. Sinyal küçüktür (onlarca cycle) ve CPU/microcode'a bağlıdır; sonraki birçok parçada bu fark azalmış ya da yok olmuştur.
Detection¶
Yazılımdan tespiti zor: saldırı, syscall ve fault olmayan sıkı bir ayrıcalıksız
prefetch/rdtsc loop'udur. Anormal rdtsc/rdtscp oranları ya da TLB-miss
pattern'leri için performance-counter izlemesi olağan yaklaşımdır, ama gürültülüdür.
Ayrıcalıksız rdtsc'yi devre dışı bırakmak (CR4.TSD) en ucuz timer'ı kaldırır ama
daha kaba timing kaynakları kalır.
Mitigation¶
(Artık risk / bypass.) KPTI / KVA shadow çoğu kernel mapping'ini user page table'larından kaldırır, böylece kernel address'lerinin user-mode prefetch'i translate edecek bir şey bulamaz — klasik varyantı kapatır. EntryBleed saldırısı, user page table'larında map'li kalmak zorunda olan birkaç address'i (syscall entry trampoline'i) prefetch ederek bunu KPTI'a karşı diriltir ve kernel text base'ini yeniden türetir. Daha güçlü entropy (KASLR, FG-KASLR) tarama maliyetini yükseltir ama oracle'ı kaldırmaz. Ayrıca bkz. prefetch-timing-kaslr-bypass ve bağımsız prefetch-side-channel.
References¶
- D. Gruss, C. Maurice, A. Fogh, M. Lipp, S. Mangard. Prefetch Side-Channel Attacks: Bypassing SMAP and Kernel ASLR. ACM CCS 2016. — https://dl.acm.org/doi/10.1145/2976749.2978356
- Graz University of Technology publication record (open-access copy). — https://graz.elsevierpure.com/en/publications/prefetch-side-channel-attacks-bypassing-smap-and-kernel-aslr