This program allows us to build planes, which we can name, as well as build airports, which we can also name and list information about.
We can fly planes to different airports and also sell different planes and airports which frees them.
The planes are allocated on the heap and maintained in a doubly-linked list, the head of which, is a global in the .BSS.
Similarly, the airports are also allocated on the heap and a maintained in an global array of pointers.
There are many different vulnerabilities in this program.
Firstly, there is a out-of-bounds read vulnerability which allows us to leak a libc and heap pointer.
In the following diassembly, choice_ is an index that we get to specify that has no checks performed on it.
companies is a global array that contains 4 pointers, each pointing to a different string.
Eventually, we can print out the contents of whatever pointer is associated with the choice_ index into this array that we specify.
But as we can see, there is nothing preventing us from specifying an index greater than 4.
We can simply free a couple airports to get a libc pointer and heap pointer into some heap chunks, and then specify 14 and 15 as our indices for 2 planes that we fly to an airport.
Then we just list the information for all the planes in that airport to get our leaks
Additionally, there is a double-free vulnerability as well as a use-after-free (UAF) vulnerability.
We can use these vulnerabilities to perform a fast-bin attack.
However, instead of overwriting a *_hook functions, as I’ve done in the past, we will instead, overwrite a specialFree function pointer that is just a wrapper around free() that is called whenever a plane is directly sold.
The struct for a plane object looks something like the following.
We can see the function pointer we want to overwrite at offset +0x40 into the plane object.
Our target plane fast chunk looks like the following.
We can again use a misaligned address as our target fake chunk for our fastbin attack, since malloc() does not check to see that the requested chunk is aligned.
Only realloc() and free() perform alignment checks!
One catch is that in order for us to be able to use this fake chunk to satisfy a malloc() request, the size field has to be 0x56 and not 0x55.
This is due to an extra check that is performed if the IS_MMAPED bit is turned off.
What we don’t want to do, is end up here:
If our fake size is 0x55, this causes a crash.
A SIGGEV access violation occurs @ the mov rcx,QWORD PTR [rax] instruction on line 0x7ffff7a91630 because 0x55 AND 0x2 = 0x0 whereas 0x56 AND 0x2 = 0x2.
The former causes the conditional jmp @ 0x7ffff7a91619 to not be taken, eventually leading us to 0x7ffff7a91630.
So, long story short, our exploit only works when the heap base address starts with 0x56 and not 0x55.
After overwriting the specialFree function pointer, with a magic one-gadget RCE address, we simply sell the plane with the corrupted function pointer to get a shell.
Putting everything together, we can get the flag using the following exploit.