ASLR Brute Force (fork-based address guessing)¶
Fork eden bir server'a karşı, her child parent'ın sabit randomize layout'unu inherit eder, dolayısıyla bir attacker, biri hayatta kalana kadar child'ları tekrar tekrar crash ederek ASLR base'ini tahmin edebilir.
Mechanism¶
Neden çalışır
ASLR yalnızca execve()'de yeniden randomize olur. fork()'lanan bir child,
parent'ın bir kopyasıdır — aynı randomize offset'leri tutar. Birçok network
daemon'ı (klasik olarak Apache) connection başına bir child fork eder, dolayısıyla
"bu ilişkili process'lerden herhangi birinin layout'unu belirlemek, o layout'u
hepsi için açığa çıkarır" (Shacham ve diğerleri). Crash olmuş bir child, hayatta
kalan parent'ın layout'unu değiştirmez ve parent aynı base ile taze child'lar
spawn etmeye devam eder.
Bu, ASLR'ı sabit cevaplı bir tahmin oyununa dönüştürür: aday bir base'e hard-code edilmiş bir exploit gönder; yanlışsa child crash olur (ve server hizmet vermeye devam eder), doğruysa execute olur. 32-bit PaX'te mmap offset'inin yalnızca 16 bit entropy'si vardır — "delta mmap denen mapped data offset, 16 bit randomness ile sınırlıdır" — dolayısıyla search space küçücüktür.
Kırılan invariant: attacker'ın entropy'den daha küçük bir probe sayısına ihtiyacı vardır ve fork eden, yeniden randomize etmeyen, crash-tolerant bir target tam da ihtiyaç duyulan tekrarlanan, düşük maliyetli denemeleri sağlar.
Walkthrough¶
Orijinal ölçüm (Shacham ve diğerleri, 32-bit x86'da PaX-protected Apache'ye karşı):
Search space : 2^16 = 65,536 possible mmap bases
Worst case : 65,536 probes
Average : 32,768 probes
Measured : avg 216 s, max 810 s, min 29 s to derandomize
Saldırı loop'u (kavramsal):
for guess in candidate_bases(): # iterate the 2^16 mmap offsets
if send_exploit(target, base=guess): # connect -> overflow -> ret to guess
break # child survived & ran our payload
# else: that child crashed; parent forks a new one with the SAME base
Beklenen davranış: çoğu deneme, fork'lanan child'ı crash eder (connection reset'leri);
guess inherit edilen base ile eşleştiği an, return target geçerlidir ve payload çalışır
— info leak olmadan ASLR derandomize edilir.
Kesinlikle fork-inheritance, re-exec değil
Saldırı, fork()'un parent'ın sabit layout'unu inherit etmesine bağlıdır. Server,
connection başına taze bir process execve() ediyorsa (yeniden randomize ederek) ya
da tüm parent'ı crash edip/yeniden spawn ediyorsa, base değişir ve brute force fail
eder. Full entropy'li 64-bit ASLR (ve PIE), search space'i pratik olmaktan çıkarır.
Detection¶
Brute force gürültülüdür: fork eden bir server, başarıdan önce bir dizi child crash'i
(segfault'lar / anormal connection reset'leri) üretir — core-dump sayımlarında, dmesg
segfault satırlarında ve crash-restart telemetry'sinde görünür.
Mitigation¶
(Onu durduran şey.) Process başına yeniden randomize et (yalnızca fork yerine re-exec), full-entropy 64-bit PIE ASLR, kötü davranan bir client'ı throttle eden crash-rate detection ve low-entropy mmap'li crash-tolerant fork eden server'lar çalıştırmamak.
References¶
- Shacham, Page, Pfaff, Goh, Modadugu, Boneh. On the Effectiveness of Address-Space Randomization. CCS 2004. — https://hovav.net/ucsd/papers/sppgmb04.html