The first half of the article explains how to trigger the bug. At first glace, this appears to be a very simple heap overflow. However, triggering the code in the HTTP routing to actually hit this was very complex (with many conditions having to be met).
The overflow relied on the value of the Content-Length header coming out of a proxy. This proxy actually recalculates the length of the request incorrectly. This, paired, with an unsafe memcpy, creates a heap overflow, in the HTTP routing of file upload requests.
Exploiting the bug was also fairly interesting! First, they write out the considerations for the exploit. Being able to understand the landscape of the attack surface is crucial for exploit dev.
- Heap overflow can write arbitrary length data with arbitrary characters (including NULL bytes)
- ASLR is not in use
- uClibc is used, which is a minimal version of C
- malloc calls: 0x60 and 0x1000 from calls to fopen. These are freed afterwards in the same order as allocation
The classic attack here, to gain easy primitives, is to use the fastbin dup attack. The fastbin dup overwrites an fd pointer while in the fastbin. This overwrite allows us to control an arbitrary address to be returned from malloc, creating an easy write-what-where primitive.
There is a final interesting issue to this though: fastbins are only used with small allocations; allocations that are larger than 0x1000 trigger a call to malloc_consolidate, which puts all fastbin chunks into the unsorted_bin.
In order to still have the ability to use the fastbin dup technique, the author overwrites the value of max_fast within malloc_state by creating a chunk of size 0x8. Now, when the check for the max_fast is done to check for consolidation, the consolidation will no longer be triggered!
To actually complete the exploit, a author chooses the GOT table entry of free for the fastbin dup attack. With control over the free function pointer, the address of system is replaced. When a call for free is made, if the beginning of the chunk is set to a string (/bin/sh) then the code is executed.
Naturally, when viewing the exploit code, there is a significant amount of heap grooming that is taking place in order for everything to line up exactly as we wanted. The important allocations and aspects are described above.