170 likes | 191 Views
Explore the ongoing challenge faced in defeating Instruction Set Randomization, known since 1998. Despite numerous defenses proposed like Non-Executable Buffers, Array Bounds checking, and more, the issue persists. This text delves into a detailed analysis of buffer overflows, including a code example and insights on attacking strategies such as execve instruction set randomization. Discover the possibilities and vulnerabilities associated with guessing keys in binary code injection attacks, along with proposed solutions and attack scenarios.
E N D
Defeating Instruction Set Randomization Nora Sovarel
“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 Buffer Overflow
I don’t know Maybe, lack of interest… Maybe, none of the defences is good enough… What about Instruction Set Randomization? Why is still an issue in 2004?
[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 */ "\x50" /* pushl %eax */ "\x53" /* pushl %ebx */ "\x89\xe1" /* movl %esp,%ecx */ "\x99" /* cdql */ "\xb0\x0b" /* movb $0x0b,%al */ "\xcd\x80" /* int $0x80 */ ; Attack String - execve
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 89 ^ ac => 25 e1 ^ 7d => 9c 99 ^ 97 => 0e b0 ^ a2 => 12 0b ^ 0c => 07 cd ^ 90 => 5d 80 ^ dc => 5c
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 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)
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 or Same randomization key for all forked processes
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