Generalized BROP Stop/Found-Gadget Scan¶
Blind ROP: binary'nin bir kopyasına hiç sahip olmadan, "stop" gadget'larını ve işe yarar gadget'ları keşfetmek için bilinmeyen bir server binary'sini crash-vs-hang oracle ile uzaktan tarama.
Mechanism¶
Blind Return-Oriented Programming (BROP), Bittau, Belay, Mashtizadeh, Mazières ve Boneh'in "Hacking Blind," IEEE S&P 2014 (Oakland) çalışmasından gelir ve bir bypass'tır: attacker'ın ne binary'ye ne de source'a sahip olduğu durumda, stack-overflow'a açık bir network service'e karşı çalışan bir remote exploit inşa eder. Crash'te re-randomize etmeden fork-and-restart yapan service'leri hedefler (child, parent'ın ASLR layout'unu inherit eder) ve her isteği tek bir tahmin edilen address'in tek bir probe'una dönüştürür. Buradaki "generalized," ayrı bir named BROP variant'ı değildir: scan'in binary-agnostic olduğunu — belirli bir bilinen binary yerine keyfi, bilinmeyen bir remote target için gadget'ları yeniden kurduğunu — vurgular ve makalenin ayrı bir primitive'i olan generalized stack reading (bkz. stack-reading) ile karıştırılmamalıdır.
Invariant broken
BROP, ASLR + binary-açıklamama'nın arkasındaki varsayımı yıkar: attacker'ın text'i okumadan gadget bulamayacağı varsayımını. Server'ın kendi crash/no-crash davranışını bir oracle olarak kullanarak address space her seferinde tek bir byte-pattern olacak şekilde aranır, böylece bilinmeyen, randomize edilmiş layout okunmak yerine uzaktan yeniden kurulur.
Sınıflandırma primitive'i bir stop gadget'tır: return edildiğinde connection'ı crash ettirmek yerine asılı bırakan (blocking, ör. sonsuz bir loop veya socket'i açık tutan bir yol) bir address. Aramayı üç gözlemlenebilir sonuç yönlendirir: istek crash eder (kötü address / fault), asılı kalır (block eden bir şeye çarptı — aday stop gadget) veya normal döner.
Walkthrough¶
Saldırı, her biri öncekinin üzerine katmanlanan fazlar halinde ilerler:
- Stack reading. Saved return address'i her seferinde tek byte overwrite edip crash vs no-crash gözlemleyerek önce stack canary'yi, sonra saved frame pointer'ı ve return address'i geri kazan — bilinen bir text address'i açığa çıkarır ve canary'yi atlatan çalışan bir overflow verir. (Bkz.
stack-readingvebyte-by-byte-canary-brute-force.) - Bir stop gadget bul. Aday address'leri tara; connection'ı (crash yerine) asılı bırakan biri bir stop gadget'tır. Bu, probe edilen bir gadget'ın temiz çalışıp çalışmadığını anlamakta kullanılan "sentinel" olur.
- BROP gadget'ını tara. Stack'i
[probe_addr][stop or trap][stop or trap]...şeklinde diz ve davranışı izle. BROP gadget'ı (altı değer pop edenpop rbx; pop rbp; pop r12..r15; rettarzı bir dizi) ayırt edici signature'ıyla tespit edilir: ardışık offset'lerde girince giderek daha az öğe pop eder. Trap'leri ve stop gadget'larını araya serpip hangi kombinasyonların asılı kaldığını vs crash ettiğini kontrol ederek bir aday doğrulanır.
Probe layout (conceptual)
saved_ret -> [ probe ] [ stop ] [ trap ] [ trap ] [ trap ] [ trap ] [ trap ] [ stop ]
| |
| +-- if probe pops N words, the (N+1)th slot is "executed":
| place a stop there to get a hang, a trap to get a crash.
+-- candidate gadget under test
# crash -> bad guess
# hang -> probe consumed the expected number of words (matches signature)
- PLT'ye bir call / bir write bul. Register-control gadget'ları bilinince, PLT'de
write/dup2/putsbul ve mevcut socket üzerinden binary'yi dump etmek için bunları kullan — artık attacker binary'ye sahiptir ve geleneksel ROP ile bitirebilir (makalenin Braille aracında kabaca 2.000–4.000 istekte tam bir shell).
Defensive note
Bu, detection ve mitigation için belgelenmiş bir bypass tekniğidir. Belirleyici etken, re-randomize etmeden restart eden bir fork-server'dır; re-exec yapmak (restart'ta tam re-randomization) ve crash-rate alerting'in ikisi de onu köreltir.
Detection¶
Bir BROP koşusu, tek bir peer'dan aynı service'in crash/restart selini ve buna ek olarak asılı kalan birçok connection üretir. Crash-loop monitoring, kaynak başına connection-rate limit'leri ve bir worker'dan tekrarlayan SIGSEGV üzerine alerting güçlü sinyallerdir.
Mitigation¶
Her restart'ta re-randomize et (çıplak fork yerine tam exec), böylece child layout'ları farklı olur; process başına re-randomize eden stack canary'leri devreye al; tekrarlayan crash'leri tetikleyen kaynakları rate-limit'le veya geçici olarak ban'le.