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 |
|
I checked gdb
and 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 rwx
!
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!