Introduction
We are given the following code:
|
|
Let’s see what flags it is compiled with:
So far we can’t execute shellcode on the stack. However it doesn’t have ASLR enabled so we can reference segments of code without leaking addresses.
Solution
The challenge description mentions some warnings compiling the code, let’s compile it:
Basically it’s pointing that scanf
uses both passcode1
and passcode2
uninitialized, so it uses the “garbage” available in the stack when executing it.
Let’s see where in the stack is located:
Here is the stack frame for the login function, luckily enough passcode1
(0xebp-0x10
) is a valid pointer. However pastcode2
(0xebp-0xc
) is an invalid memory address so scanf
causes segmentation fault when attempting to write in that address.
If we now enter all 100 characters on welcome
we corrupt the login
stack frame just until passcode1
(included):
At this point we can overwrite the address where scanf writes, that means that we can write an int
(the same as 4 bytes) in an arbitrary address.
Our goal now is to modify an address so that we can return to system("/bin/cat flag")
. Firstly thought to bruteforce modifying the first but then realized that scanf adds a terminating null byte (\0
).
The only option left is to overwrite the got address. There are the following functions available before the code exits:
fflush
printf
puts
exit
Here is the GOT addresses using gdb gef:
After some debugging realized that x00
and x0c
are bad chars for scanf (using %s
formatter), therefore we can’t override printf
or puts
.
To generate the payload we can use python
:
python2 -c 'print("A"*96+"<GOT_DIR>"+"<RET_DIR>")' > fflush
Don’t forget to jump to the previous direction of
system
call, otherwise the argument wouldn’t be passed, also the address has to be sent in decimal form due to%d
formatter.
Here is the result with the different functions: