1. Basic info about the file
Using file command we find its a 64 bit executable that is not stripped(has debugging information)
2. Workflow of the file
Next, checking how the executable works
We see that it was asking for user input twice (fgets() used in the 1st input and scanf on the 2nd) on different occasions, however on the second occasion, a segmentation fault happened, it seems it needed a specific input for it to work properly. At first i thought of buffer overflow because of the segmentation fault.
3. Theoretic flow of the plan to achieve success
Ghidra was used to decompile and disassemble the elf file
We see fgets function used to fetch user data, when user inputs yes makeshot(); is called, if user inputs no a message is displayed and the program exits.
After makeshot function, code is compared to 0x13371337, if code==0x13371337 the program exits, if not equal it proceeds to spawning a shell using system(“/bin/sh”)
Taking a look at makeshot()
An input is expected , then 500,000 is added on the address local_10(input), then the value in the address points to 0.Meaning that an address that is within the stack is expected as input for the makeshot function to proceed successfully otherwise an error of segmentation fault will be displayed. This is because the 0 is added to an address that doesn’t exist.
Steps
- Find an address that is within the stack, then subtract 500,000 before inputting it to cater for local_10 = local_10 + 0xa0000(address + 500,000). For this we will use the address that holds the code variable mentioned in Fig 4.
- The value of the address where code is stored will be pointed to 0, which means when the program will proceed to system(“/bin/sh”) from fig 4
Enough of the theory, let’s proceed to GDb
4. Using Gdb to execute our plan
Note:Keep in mind what we already know
A breakpoint on main
Using disas main we can see the the main function below
We will put a breakpoint before makeshot function is executed (0x000000000040121d)
And before breakpoint 2 user is required to input yes/no, we go with yes
Looking at makeshot function
Let’s trigger the 2nd input prompt.
We will do this by first stepping in(si) into makeshot then, multiple si.
Note: for default c functions like puts and fflush, you will have to use next in(ni) command to avoid getting into those functions. just like i did
We are now on the function scanf which asks for user input! as shown above
Using the code address we found on fig 6, then subtract 500000
we get -FBF98
But why are we using the code address?This is because the program will change the value of address that holds the code variable, meaning that the comparison will be not equal hence program proceeds executing system(“/bin/sh”) as we will later see.
lets input it,
500000 is added on rax(our input),
We get an address that is in the stack and we are able to get the exact address that stores code variable.
As we step in, to the instruction points the value of our 0x404068 address with 0,
we can see the address value being replaced from the stack frame
After return from makeshot function, we are assured that the compare will not be equal, hence from main function the jump not equal(jne) will be true
Hitting the continue(c) command we see the instruction being executed to get a shell on our machine
Now, since our 2nd input works fine, we can now try it on the system provided
and we are in, and finally we can get the flag