Customer Stories
w3th4nds,
May 19
2022
After the successful hijacking of the D12 spaceship during the Space Pirate mission, the crew managed to place a signal transmitter on a vending machine that the Golden Fang's members are using to order food from the Supplier Spacecraft of Draeger. Golden Fang's crew's favorite food contains a secret ingredient called "Little Green People0," which we do not have further info about. The signal passes through many satellites before it reaches the Supplier, so it won't be easy to track the device and the leaked signal. Can you take advantage of it and get control of the Supplier?
In this writeup, we will cover one of the most basic heap techniques which are tcache poisoning and heap overflow. The goal of the challenge is to teach the user the basics of heap exploitation techniques and how the memory is mapped dynamically.
Starting to play with the binary:
First of all, we start with a checksec to check the protections:
We see a menu, which is something classic for a heap challenge. Apart from that, we cannot assume anything else from the interface, so let’s head into the disassembler.
Disassembly ⛏️
Starting from main():
There are some function calls:
setup() : Sets the appropriate buffers in order for the challenge to run.
banner() : Prints the banner.
new_order
show_order
edit_order
delete_order
Take a better look at these:
We see that there is a malloc function that accepts any size. Then it allocates the desired space and we fill it with data via read.
This function reads the index of order and prints it (possible leak of an address).
As the name suggests, here we can change the order of our choice. But, here lies the bug as the new_order length is calculated via strlen, leading to a possible off by one overflow. The length of read is set to strlen(note), which may overflow because when adding a new note, the string is not NULL terminated. Specifically, it can overflow into the size field of the adjacent chunk.
It deletes/frees an order and then null terminating it, so there are no UAF or double-free bugs here.
From the functions we analyzed before, we can assume some things. First of all, we need to check the libc version of the binary.
We see that it’s libc-2.27. According to the libc given, we can perform various heap exploitation techniques. Libc-2.27 is vulnerable to an attack called tcache poison.
Our exploitation path is like this:
Allocate two chunks with sizes 0x420 and 0x100 to make use of the unsorted bins. The allocation with size 0x100 is to make sure that the freeing of 0x420 does not result in the consolidation with the top chunk
Free them both.
Then, one of them will have the FD field set to a non-zero value, which is also a libc pointer.
Afterward, we allocate an order with size 0x100 and only send 1 byte as input.
Printing that order will leak a libc pointer.
After both are freed:
Now we allocate 0x420 one more time and send "A".
As we see, there are libc pointers at 0x555555757260 and when we call show_order, we get the leak.
Now that we have libc leak, all we need to do is overwrite __free_hook with the address of system("/bin/sh"). First of all, we are going to trigger the heap overflow in edit_order.
To start with, we will allocate 3 0x48 sized chunks to make them adjacent.
Then, using the heap overflow, we overflow the size field of the second chunk by editing A. We overwrite the size to 0x80.
After that, we free B. It is considered a 0x80 chunk by the allocator, so it is placed in the 0x80 tcache bin.
We then free the third allocation.
Later, we allocate a 0x70 sized chunk. This time, we can write 0x70 bytes to it, so we can overflow the contents of the third one. Using this, change the FD of the third to __free_hook.
By requesting 0x40 chunks twice, we get __free_hook allocated. Then, we change it to system.
Last but not least, we create a chunk with content "/bin/sh" and free it to call system("/bin/sh").