JIT Spray (DEP+ASLR bypass)¶
Bir just-in-time compiler'ı suistimal ederek attacker'ın seçtiği constant'ları executable page'lere olduğu gibi emit ettir, sonra instruction-ortasına atla; böylece o constant byte'lar bir NOP sled artı shellcode olarak decode olur — bir leak veya ROP chain olmadan DEP/W^X ve ASLR'yi yener (Blazakis, 2010).
Mechanism¶
Neden çalışır
DEP/W^X data page'lerini non-executable yapar ve ASLR kodun nerede yaşadığını gizler. Bir JIT bu invariant'ların ikisini de attacker için kırar: çalışma zamanında yeni executable kod yazar ve attacker-controlled constant'ları doğrudan o koda gömer.
- Büyük constant'larla dolu bir scripting ifadesi —
var x = 0x3c909090 ^ 0x3c909090 ^ ...;—XOR EAX, 0x3c909090gibi bir x86 instruction zincirine derlenir; her biri executable bir JIT page'ine90 90 90 3cliteral byte'larını emit eder. - x86'da instruction alignment yoktur, dolayısıyla böyle bir instruction'ın
bir byte içine atlamak constant'ı yeniden yorumlar:
0x90byte'larıNOPolarak decode olur ve takip eden opcode byte'ı yeni bir instruction başlatır. Attacker, gadget/shellcode byte'larını birçok constant içine paketleyip JIT'lenmiş fonksiyonu birçok kez instantiate ederek, bir NOP-sled-artı-payload'ın kopyalarını geniş, öngörülebilir bir address aralığına spray eder. - Spray edilen aralık geniş olduğu ve JIT page'leri kaba alignment'larda
kümelendiği için, sabit bir landing adresi güvenilir biçimde spray'in içine
iner — dolayısıyla hiçbir info leak'e (ASLR) ve hiçbir
RETchain'ine (DEP/ROP) gerek yoktur; kontrol sadece sled boyunca kayar ve constant-encoded payload'a girer. - Teknik, Dion Blazakis'in 2010 Interpreter Exploitation: Pointer Inference and JIT Spraying çalışmasında tanıtıldı ve Adobe Flash'taki ActionScript JIT'ine karşı demonstre edildi. Variable-length bir ISA gerektirir: ARM gibi fixed-length, aligned ISA'lara aynı şekilde instruction-ortasına atlanamaz.
Hem DEP'in hem de ASLR'nin dayandığı invariant — attacker bilinen executable kodu bilinen bir adrese yerleştiremez — yanlıştır, çünkü JIT tam olarak bunu talep üzerine yapar.
Walkthrough¶
1. Payload byte'larını JIT'lenmiş constant'lar içine encode et. Hazırlanmış bir immediate'ın her XOR'u executable page'e dört payload byte'ı yerleştirir:
; source: x = (0x3c909090 ^ 0x3c909090 ^ 0x3c909090 ^ ...);
; emitted: B8 90 90 90 3C MOV EAX, 0x3c909090
; 35 90 90 90 3C XOR EAX, 0x3c909090
; 35 90 90 90 3C XOR EAX, 0x3c909090
2. off+1'de girerek yeniden yorumla. Baştaki opcode byte'ını atlamak, stream'i her instruction'ın kendi opcode'unu tüketen bir sled'e çevirir:
; entry at offset +1:
90 NOP
90 NOP
90 NOP
3C 35 CMP AL, 0x35 ; harmless, advances to next constant -> sled
3. Birçok kopya spray et. JIT'lenmiş fonksiyonu binlerce kez instantiate et, böylece executable kopyalar öngörülebilir bir aralığı örter, sonra kontrolü bir corruption primitive ile sabit bir instruction-ortası adrese yönlendir:
Beklenen sonuç: yürütme gömülü NOP'lar boyunca kayar ve constant-encoded shellcode'a girer. DEP ve ASLR, hiçbir leak ve hiçbir ROP olmadan bypass edilir.
Constant blinding + W^X JIT ile yenilir
Standart düzeltme constant blinding'dir: büyük immediate'ları emit'ten önce process başına rastgele bir cookie ile XOR'la, böylece attacker'ın gördüğü byte'lar öngörülemez olur; randomize edilmiş/guard'lanmış JIT page yerleşimi, alignment'ı bozmak için rastgele NOP-insertion ve W^X JIT (page'ler ya writable ya executable'dır, asla ikisi birden — kodu yaz, sonra execute'a flip et) ile birleştirilir. İlgili varyantlara bak: asm.js-targeted JIT spray ve constant-embedded gadget JIT spray.
Detection¶
Birçok büyük-constant yüklü executable page üreten bir JIT compilation patlaması ya da yürütmenin bir JIT page'ine non-entry (instruction-ortası) offset'te girmesi anormaldir — gerçi tasarım gereği input sıradan numerik script gibi görünür.
Mitigation¶
(Onu ne durdurur.) Constant blinding (immediate'larda byte-smuggling'i yener), W^X / write-xor-execute JIT page'leri, randomize edilmiş JIT region base'i ve guard page'ler ile NX-by-default. Bunlar spray'in iki varsayımına saldırır — öngörülebilir byte'lar ve öngörülebilir bir adres.
References¶
- Dion Blazakis. Interpreter Exploitation: Pointer Inference and JIT Spraying (Black Hat / Defcon 2010). — https://github.com/emintham/Papers/blob/master/Blazakis-%20Interpreter%20Exploitation:%20Pointer%20Inference%20and%20JIT%20Spraying.pdf
- Wikipedia. JIT spraying. — https://en.wikipedia.org/wiki/JIT_spraying