Get the executable here
- Give the program the correct argument so it will print the flag
- It is ok if the program crash afterwards.
- Do not reverse the decrypt function
Lets start by running the program in android.
adb to push it to my android device.
┌──(razali㉿razali)-[~/…/Ivy/AndroidVulnResearch/ctf/stacking] └─$ adb push a.out /data/local/tmp
Next, run the program in the android device.
root@hammerhead:/data/local/tmp # ./a.out usage: ./a.out <username> <password> root@hammerhead:/data/local/tmp # ./a.out root toor Login failed
Seems like we need the right username and password.
Let's open up the program in
IDA to perform static analysis.
functions window, we can see that there exists a function called
We can see that there are actually no references to that function within the program. From the title of this exercise,
stacking, we know that we need to perform some kind of stack overflow.
Let's take a look at the
main function in
There is an interesting function called within the
verify_user. It takes in the username in
R0 and password in
R1 and performs some kind of verification.
Let's take a deeper look into the function
I have marked the first occurrence of username and password. Let's rename the variables by pressing the
n key and giving them appropriate names.
It will now look like
Looking further below, there are 2 unsafe
strcpy function has the following declaration.
char *strcpy(char *dest, const char *src)
Let's focus on the 2nd
strcpy, marked with asterisk
*, as the destination variable is closer to the start of the stack.
The destination variable in the above figure is
Now let's scroll back all the way up to the top of the function to see how far is this variable from the start of the stack.
0x1C which is 28 bytes from the start of the stack.
IDA by default names stack variables by how far they are from the start of the stack.
Lets take a look at how a
stack frame looks like.
As we can see, our goal is to override the
Link Register. The
Link register contains the address to return to after completing the current function,
So in order to override it , we need to spam 28 bytes + an extra 4 bytes to override the
Frame Pointer, and our final 4 bytes to override our link register.
Thus lets put an input of 32 'A's followed by 4 'B's.
Lets look at the result in
In our android lets run our
root@hammerhead:/data/local/tmp # ./gdbserver localhost:6666 ./a.out root AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
In our host, lets connect to it using
We can see that our function tried to return to an address
0x42424240 which is our
BBBB. The reason it is not
0x42424242 is because due to alignment reasons.
Anyway, now we know how to direct the function to point to anywhere we want.
Lets try to point the function to
root@hammerhead:/data/local/tmp # ./gdbserver localhost:6666 ./a.out root `echo -en "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xDE\xAD\xBE\xEF" `
Notice that it now points to
Next, lets get the address of the unreference function
print_flag lies in the address
0xEFBEADDC, we need to input
root@hammerhead:/data/local/tmp # ./gdbserver localhost:6666 ./a.out root `echo -en "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x30\x85\x00\x00" `
And we got the flag.