Posts DekraCTF - Echopwn [Pwn]
Post
Cancel

DekraCTF - Echopwn [Pwn]

Echopwn is a simple binary that reads the user input twice and reflects it.

Using checksec we can see that most memory protections are enabled, including stack canaries and address randomization. Therefore we will need a memory leak to bypass these protections.

Reverse engineering the binary we can view the doRead function that is vulnerable against format string vulnerability and stack buffer overflow.

We can insert %lx%lx%lx%lx%lx%lx%lx%lx%lx%lx%lx%lx%lx in the first user input to read arbitrary memory exploiting format string vulnerability.

So doing this, the program reflects a memory leak containing useful information to continue with the exploitation process.

This is an example of a memory leak that we received sending the previous string:

55fb481636b1 0 7f188b27a980 55fb481636d8 0 0 7 6c25786c2578 6c2525786c2578 6c2578786c2578 6c25786c6c2578 6c25786c2578 6c25786c2578 6ece5044a053bf00

So we can leak a libc address (0x7f188b27a980) and a stack canary value (0x6ece5044a053bf00).

We use the libc address leak to calculate the offset from libc base address in order to bypass stack randomization.

Offset to libc base = leaked_address - libc base = 0x394300

Now we know the libc base address so we can exploit the binary with ret2lib attack. 

We use readelf against libc to extract the offsets of system and exit functions  about libc base address.

We use strings to extract the /bin/sh strings offset in libc.

This is a 64 bit binary so we need to search for a pop rdi; ret gadget in libc to put the /bin/sh reference in rdi before calling the system function.

This is a 64 bit binary, so we need to search for a pop rdi; ret gadget in libc in order to put the /bin/sh reference, and then calling the system function.

With all this information we can calculate the real addresses of exit, system, the pop rdi; ret gadget and /bin/sh.

system_address = leaked_address - offset_to_libc_base + system_offset_in_libc + alignment_offset

exit_address = leaked_address - offset_to_libc_base + exit_offset_in_libc + alignment_offset

bin_bash_string = leaked_address - offset_to_libc_base + bin_sh_offset_in_libc + alignment_offset

pop_ret_gadget = leaked_address - offset_to_libc_base + pop_ret_offset_in_libc + alignment_offset

Notice that we add an alignment_offset in these all calculations because the real address is 0x21680 bigger than our results.

alignment_offset = 0x21680

In GDB we can search for a real addresses easily:

Now it’s time to put all pieces together and create our payload:

So we have to craft this payload and send it in the second user input:

12*”A” + 40*”B” + canary_leak + exit + pop_ret_gadget + bin_sh_string + system

Our exploit is able to calculate all these addresses on runtime bypassing randomization with the obtained memory leak and we exploit the second user input BoF vulnerability to successfully do a ret2lib attack and gain a shell.

This post is licensed under CC BY 4.0 by the author.