DEV Community


Posted on • Updated on


Stackoverflow [Android Internals CTF Ex7]

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

Let's Begin

Lets start by running the program in android.

I'll use adb to push it to my android device.

└─$ adb push a.out /data/local/tmp 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Seems like we need the right username and password.

Let's open up the program in IDA to perform static analysis.


In the functions window, we can see that there exists a function called print_flag.

Click x to find all references of the function within a.outimage

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 IDA.


There is an interesting function called within the main function, 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 verify_user.


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 functions.

The strcpy function has the following declaration.

char *strcpy(char *dest, const char *src)
Enter fullscreen mode Exit fullscreen mode


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 var_1C.

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.


Yea, its 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, verify.

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 GDB.

In our android lets run our gdbserver.

root@hammerhead:/data/local/tmp # ./gdbserver localhost:6666 ./a.out root AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB  
Enter fullscreen mode Exit fullscreen mode

In our host, lets connect to it using gdb-multiarch.


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 0xDEADBEEF.

root@hammerhead:/data/local/tmp # ./gdbserver localhost:6666 ./a.out root `echo -en "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xDE\xAD\xBE\xEF" ` 
Enter fullscreen mode Exit fullscreen mode


Notice that it now points to 0xEFBEADDC.

Next, lets get the address of the unreference function print_flag.


The function print_flag lies in the address 0x00008530.

If 0xDEADBEEF produces 0xEFBEADDC, we need to input 0x00008530 as 0x30850000.

root@hammerhead:/data/local/tmp # ./gdbserver localhost:6666 ./a.out root `echo -en "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\x30\x85\x00\x00" ` 
Enter fullscreen mode Exit fullscreen mode


And we got the flag.

Top comments (0)

An Animated Guide to Node.js Event Loop

>> Check out this classic DEV post <<