Another month, another CTF! This Advent CTF runs almost the entire month of December. This challenge seemed easy at first, but turned out to be a bit more tricky!
We’re given a vulnerable binary plus the C source:
1 2 3 4 5 6 7 8 9 10 11 12 13
This looks pretty straight-forward, right?
scanf, an executable stack and a small buffer, oh my! A standard buffer overflow:
1 2 3 4 5
eip was overwritten with
HHHH, so we need 28 bytes to overflow the buffer. Next, because the stack is executable, we should be able to jump to it… but how? ALSR is enabled so we don’t know the location of the stack. None of the registers contain a pointer to the shellcode, there aren’t any
jmp esp or
call esp instructions. Bruteforcing it seemed tedious at best. We looked at writing a ROP chain, but there are very few useable gadgets.
Thinking long and hard together with Swappage and superkojiman, we came up with several strategies. One of the suggestions by Swappage revolved around abusing
scanf to build shellcode somewhere. superkojiman noticed that the main code section is
1 2 3 4 5 6 7
Yes, this has to be it! We can write to a section of memory that is executable and at a fixed location. After writing shellcode there, we simply jump to it to have our cake and eat it.
So I modified a ROP chain that I was fiddling with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
I used a modified version of this shellcode. The shellcode wasn’t working locally, and I narrowed it down quickly to a bad byte,
0x0c. This was part of the
lea ecx, [esp] instruction. I exchanged this for:
1 2 3 4 5 6 7
And off we went! I verified the exploit remotely by reading
/etc/passwd and then I guessed the name of the flag file to be
flag. Simple, really =)
1 2 3
The flag was
ADCTF_Sc4NF_IS_PRe77Y_niCE. In the end, the executable stack turned out to be a red herring and something more unusual was going on. Cool challenge!