TahuBulat
overlapping heap chunk to tcache poisoning gaining almost arbitrary write
Problem
Description
Dadakan
nc 103.181.183.216 17005
Hint : overwrite GOT?
Disclaimer
unsolved during the CTF, manage to solve after the event has ended
During the CTF, I already get the correct idea of the challenge however during the execution it didn't quite work and spent quite a lot of time debugging my exploit. This writeup covers another method to solve the challenge which relatively easier to understand and implement.
Proof of Concept
Analysis
given compiled binary, we'll check its basic executable information and security perimeter. We're also given a Glibc version 2.31
next, after interacting with the binary a little bit it seems this is a typical CRUD heap challenge, just without the Update functionality. Next, I immediately jump into ghidra.
the main function act as a router, prompting user a choice and redirect to its according function. Let's take a look at each function one by one.
Option 1 provide us with with an allocation functionality of size max 0x420 bytes and max 3 chunks at the same time. Both of the pointer to the chunk and its corresponding size is stored at SP global variable which seems hold this structure:
the function provides us the functionality to fill the allocated chunk user data. Here lies the main vulnerability which we'll exploit. For some reason, it allows us to write 0x10 bytes more than the actual size of the chunk, allowing us to corrupt some of the metadata of adjacent chunks.
the other functions that provide READ and DELETE functionality won't be showed here because of the lack of apparent vulnerability exist there since it implements the correct checking and does the correct removal of pointers on the SP to avoid dangling pointers.
oh yea, forgot to mention there's exist a win function.
Exploitation
Since RELRO is partial and the existence of a win function, my instant thought is a GOT overwrite. To do that we'll need an arbitrary write primitive. The easiest way to do this with the heap is through tcache poisoning. Here's how we'll achieve that:
First, Let's allocate three chunks, first and last one of similar size, and smaller size in the between.
Next, we will corrupt the 2nd chunk's size, tricking the tcache to thought the chunk is bigger than it should be.
Next, lets delete the chunks in order of 1 -> 3 -> 2. this will insert all of the chunk into the same 0x50 tcache bin although the 2nd chunk was suppossed to be 0x20 in size. Just to be sure, lets check this within GDB
Now, if we make another allocation the chunks should look something like this,
thus creating an overlapping chunk. And since we are able to edit chunk 2's data, chunk 3's fd is completely within our control. Since the fd controls where the allocation will be located after that chunk is returned for reallocation, we achieve arbitrary write almost anywhere.
Rest is just overwrite one of the GOT table with the win function.
Flag
hacktoday{soalnya_dibikin_dadakan_karena_ada_probset_yang_buat_soal_tapi_gaada_solvernya_muehehehe___ZafiN}
Appendix
Last updated