[hxp-2017 CTF] Babyish - Writeup by j0nathanj
HXP CTF- 2017:Babyish
In this challenge, we’re given a 32 bit ELF executable(DEP enabled), a “custom” libc, and a C source.
The source code looks like this:
This is a fairly short code.
vulnerability’s cause is due to line 33.
In line 33, the user is asked to enter a length, which will be used
as the length of the input that will be written to a 0x40 sized
buffer name ‘buf’.
Line 33 checks if the size is greater than or equals to 0x40, and if so, it exits with an appropriate message.
The bug occurs when the user inputs a negative number as an input. The size satisfies the constraint that it has to be less than 0x40, and also when using the function ‘read’ the len is considered an unsigned integer, hence -1 is a considered to be 4294967295.
This way we can overwrite stuff, and get an overflow.
The question that comes next is, because DEP is enabled, how do we leak some addresses?
Well, it turns
out that we not only need to leak an address in LIBC, but we also
need to leak an address in the stack because just before the last
‘ret’ instruction in main, the stack pivots due to the following
0x80487e6 <main+247>: lea esp,[ecx-0x4]
The good part is that we have control over ecx.So, if we leak an address in the stack in addition to a leak of a libc address, we can get control over eip. (because of the last ret)
When running the
executable with a short username, we immediately notice that some
“random” value is printed out.
If we dig a little deeper, we can see that this is where we can leak stuff!
In the screenshot above, we can see that the 2 addresses in the green box are printed (because there is no null terminator between where the beginning of the print [the first 0x41] and them, so they get printed).
As seen to the
left, the stack is very near the first address, and we can calculate
our stack based on this leaked value.
The other address is an address in libc, which we can use to calculate other addresses of libc functions/gadgets/etc based on their offsets.
Below is a screenshot of the function “__libc_start_main” to see how close it is to the second address in the green box.
Using this information, we are left with writing an exploit.
The trick that I used here was to call “system” with the appropriate parameter – “/bin/sh”.
(also, just to make it a little nicer, I got the return address of system to be exit, so we don’t segfault when we call exit to exit the shell. This was totally unnecessary, but why not make the exploit as formal as possible )
Below is an the screenshot of the exploit, also added a python file of the exploit.
After running the following exploit, we get the flag:
Thanks for reading!