======================= Lec04: Writing Exploits ======================= 0. Challenge: Stalking Professor ================================ $ cat token.c $ make token $ ./token 118f3f8e10d8f0fb1ff91470e26709765190f948 $ ./token ... This token generator gives you a new token in each invokation (see the code!). For your convenience, the token generator also gets a seed as an input. $ ./token 0 b9e3223bc9fc484f87aecbb970512377cc8198c5 This token is generated at the genesis of the computer era (aka UNIX Epoch https://en.wikipedia.org/wiki/Unix_time): Wed Dec 31 19:00:00 1969 $ man 2 time Question: When did your professor start preparing this tutorial for you? 1. First Exploit ================ Do you remember a crackme binary, ./crackme0x00, which we hijacked to divert its control flow to bypass its (toy) authentication logic. Remind a few things: 1) related code snippet $ objdump -d crackme0x00 ... 8048414: 55 push %ebp 8048415: 89 e5 mov %esp,%ebp 8048417: 83 ec 28 sub $0x28,%esp ... 8048448: 8d 45 e8 lea -0x18(%ebp),%eax 804844b: 89 44 24 04 mov %eax,0x4(%esp) 804844f: c7 04 24 8c 85 04 08 movl $0x804858c,(%esp) 8048456: e8 d5 fe ff ff call 8048330 ... 2) stack status |<-- -0x18-->|+--- ebp top v [ [ ] ][fp][ra] |<---- 0x28 ------->| 0x18 + 4 = 28, which is exactly the length of "AAAABBBBCCCCDDDDEEEEFFFFGGGG" the following "HHHH" will cover the [ra]. Today's task is to develop this vulnerability to spawn a shell for attacker's profit (i.e., a flag, so your point!) Before exploiting the vulnerability, let's check the current security mechanisms applied in this binary: $ ../../../bin/checksec.sh --file crackme0x00 RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO No canary found NX disabled No PIE No RPATH No RUNPATH crackme0x00 Or use the 'checksec' command in PEDA. By the way, what are these information? RELRO: ? STACK CANARY: ? NX: ? PIE: ? RPATH: ? RUNPATH: ? Since this binary is not protected with the Non-eXecutable (NX) feature, you can inject your shellcode in any place and jump there. In this tutorial, we are going to place the shellcode (i.e., readflag) 1) stack, and 2) an environment variable. ---------------------------------------------------------------------- #!/usr/bin/env python2 import os import struct import subprocess as sp def p32(n): return struct.pack("|+--- ebp top v [ [ ] ][fp][ra][ .... ][SHELLCODE=SHELLCODE ....] |<---- 0x28 ------->| | ^ +------------------------+ 1. How to find an address of getenv("SHELLCODE")? $ ./crackme0x00 ... $ gdb -p $(pgrep ./crackme0x00) ... > p getenv("SHELLCODE") 2. Another potential way to get the proper address is via a "core" dump. $ ulimit -c unlimited $ SHELLCODE=AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ./crackme0x00 $ gdb -c core > x/100x $esp ... 3. Could you exploit without knowning the precise location of SHELLCODE (perhaps a sequence of NOPs?) SHELLCODE=\x90\x90\x90 .... \x90\x90[SHELLCODE] [ ^ ] Jump into any place before the shellcode should end up executing the shellcode. 2) Placing the payload on the stack: |<-- -0x18-->|+--- ebp top v [ [ ] ][fp][ra][SHELLCODE ....] |<---- 0x28 ------->| | ^ +---+ 1. Is your shellcode placed correctly in your stack? via scanf("%s")? 2. Could you make your shellcode?