Archer Pwn/RE Challenge RaRCtf

Astrah
5 min readAug 10, 2021

--

Fig 1

1. Basic info about the file

Using file command we find its a 64 bit executable that is not stripped(has debugging information)

Fig 2

2. Workflow of the file

Next, checking how the executable works

Fig 3

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

Fig 4

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()

Fig 5

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

Fig 5

Using disas main we can see the the main function below

Fig 6

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

Fig 7

Looking at makeshot function

Fig 8

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

Fig 9

We are now on the function scanf which asks for user input! as shown above

Fig 10

Using the code address we found on fig 6, then subtract 500000

we get -FBF98

Fig 11

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,

Fig 12

500000 is added on rax(our input),

Fig 13

We get an address that is in the stack and we are able to get the exact address that stores code variable.

Fig 14

As we step in, to the instruction points the value of our 0x404068 address with 0,

Fig 15

we can see the address value being replaced from the stack frame

Fig 16

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

Fig 17

Hitting the continue(c) command we see the instruction being executed to get a shell on our machine

Fig 18

Now, since our 2nd input works fine, we can now try it on the system provided

Fig 19

and we are in, and finally we can get the flag

Fig 20

--

--

Astrah
Astrah

Written by Astrah

Passionate about Cyber Security

No responses yet