======================= Lec03: Writing Exploits ======================= 1. Disassembly: IDA =================== Please download and install IDA Pro (DEMO or freeware): https://www.hex-rays.com/products/ida/support/download_demo.shtml IDA is one of the most favorable disassembler used by reverse engineers. You can find basics concepts and tutorial here: (Tutorial: Part 1. The Basics of IDA Pro) http://resources.infosecinstitute.com/basics-of-ida-pro-2/ https://out7.hex-rays.com/files/idademo69_windows.exe https://out7.hex-rays.com/files/idademo69_linux.tgz https://out7.hex-rays.com/files/idademo69_mac.tgz If you feel adventurous, please go ahead and check Part 2/3/4 of the tutorials. 2. First Exploit ================ Do you remember the crackme binaries (and its password)? $ cd tut/lab03 $ cp ../lab01/IOLI-crackme/crackme0x00 . If you disassembled the binary (it's good time to fire IDA!), you might see these code snippet: $ objdump -d crackme0x00 ... 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 ... What's the value of 0x804858c? Yes, "%s", which means the scanf() function gets a string as an argument on -0x18(%ebp) location. What happens if you inject a long string? Like below. $ echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ./crackme0x00 IOLI Crackme Level 0x00 Password: Invalid Password! Segmentation fault There are a few ways to check the status of the last segmentation fault: 1) checking logging messages $ dmesg | tail -1 [237413.117757] crackme0x00[353]: segfault at 41414141 ip 0000000041414141 sp 00000000ff92aef0 error 14 in libc-2.24.so[f7578000+1b3000] 2) running gdb $ echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA > input $ gdb ./crackme0x00 > run input $ dmesg | tail -1 [238584.915883] crackme0x00[1095]: segfault at 48484848 ip 0000000048484848 sp 00000000ffc32f80 error 14 in libc-2.24.s What's the current instruction pointer? You might need this help: $ man ascii NOTE. if you want to go seriously, please check peda's pattern command. You can also figure out the exact shape of the stack frame by looking at the instructions as well. $ 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 ... |<-- -0x18-->|+--- ebp top v [ [ ] ][fp][ra] |<---- 0x28 ------->| 0x18 + 4 = 28, which is exactly the length of "AAAABBBBCCCCDDDDEEEEFFFFGGGG" the following "HHHH" will cover the [ra]. In this tutorial, we are going to hijack the control flow of ./crackme0x00 by overwriting the instruction pointer. As a first step, let's make it print out "Password OK :)"! 8048469: e8 e2 fe ff ff call 8048350 804846e: 85 c0 test %eax,%eax 8048470: 74 0e je 8048480 8048472: c7 04 24 96 85 04 08 movl $0x8048596,(%esp) 8048479: e8 c2 fe ff ff call 8048340 804847e: eb 0c jmp 804848c -> 8048480: c7 04 24 a9 85 04 08 movl $0x80485a9,(%esp) 8048487: e8 b4 fe ff ff call 8048340 804848c: b8 00 00 00 00 mov $0x0,%eax 8048491: c9 leave 8048492: c3 ret We are going to jump to 0x08048480 such that it prints out "Password OK :)". Which characters in input should be changed to 0x08048480? Let me remind you that x86 is a little-endian machine. $ hexedit input "C-x" will save your modification. $ cat input | ./crackme0x00 IOLI Crackme Level 0x00 Password: Invalid Password! Password OK :) Segmentation fault Today's task is to create a python template for exploitation. Please modify the python script (exploit.py) to hijack the control flow of crackme0x00! and answer Q1, Q2 and Q3. If you'd like to practice more, can you make the exploit to gracefully exit the program after hijacking its control multiple times?