This router handles a lot of its functionality through a CGI interface. Because we fully control the HTTP request being made to the server and this is a C binary, it's time for memory corruption!
The vulnerability is in a memcpy based upon the Content-Length and the size of the file being uploaded. Because the size of the copy and the size of the buffer are controlled by the attacker, this creates a buffer overflow. This was the original bug here but it had a terrible patch.
The patch simply checks to see if the character before the Content-Length is a newline or not. By conforming to this, the original bug still exists but it makes exploitation a lot harder.
The exploit uses a fd overwrite (or fastbin dupping) in order to control the next location of the chunk from the heap of this requested size. However, malloc_consolidate is called with a later LARGE allocation (which destroys our bin). So, a way around this needed to be discovered.
On older versions of Malloc there is a negative indexing bug with chunks being freed. If a size of 0x8 is used, then the fastbinsY array index is set to -1 and overwrites another value in the malloc_state. What's this value? max_fast! This controls the consolidation is done at. Hurray!
So, the attack looks like this:
- Trigger heap overflow to create a fake heap chunk with a size of 0x8.
- When the fake chunk is freed, it will overwrite the
max_fastvariable.
- Overwrite 'fd' pointer of a heap chunk.
- Allocate our fake chunk (with our controlled data) overwrite the a GOT entry with the PLT of system.
- Trigger the function with the overwritten GOT to pop a shell.
The article has a nice POC at the end of it as well! It is fun seeing real world heap exploitation of older versions of GLibC malloc.