ReadySHARE is a feature of Netgear router feature that is used connecting to a printer via USB as if it were a network printer. When a printer is plugged into the router, this feature is automatically turned on for the router.
The router takes in a connection on port 631 by creating a new thread. This accepts a HTTP-like request (but made from scratch with very little validation. The code snippets in this are quite large and Hex Rays dumps, making them not so easy to read.
While parsing the content of the body, the contents of our request are copied into a stack buffer via a memcpy. Since we control BOTH the size of the overflow and the bytes with no character restrictions, this is a pretty awesome bug to exploit.
In terms of binary protections, there is no stack canary, Nx is turned on, no PIE (.bss and .text randomness), no RELRO and ASLR is partially enabled. The libraries and stack are randomized but the heap is not. Additionally, the location of the overflow is at the address furthest away from the return pointer. As a result, we are going to have to craft a set of fake objects in order to allow for our exploit to happen.
The first thing they did was find a path that hit the least amount of possible things. In particular, they escaped the while loop that the buffer overflow occurred in by editing the index value to be
They decided to create a leak primitive in order to be able to reference pointers and call specific functions in LibC. In order to do this, they found a pointer and a size they could overwrite that would return data over the socket to them. However, along the way, they overwrote a socket fd. So, they brute forced the socket fd between different runs.
The final road block was that the pointer would be freed prior to returning the data. This meant that they could only leak data information that was on a valid heap pointer. For whatever reason, a few spots in the Global Offset Table (GOT) in the .bss section wouldn't crash on this but they never investigated why. They could have just gotten their leak from the heap as well, especially considering the heap was not randomized.
With the LibC address in hand, they could calculate the address of system. We still need a place to reference a string and we do not have a stack leak. So, they used a known trick with 32-bit and mmap not being randomized so well. By making a large enough allocation in LibC, it creates an mmap call directly, making it trivial to find our string.
From there, they create a ROP chain to call system with our string placed in the mmaped chunk. To pop a shell, they used the command "nvram set http_passwd=nccgroup && sleep 4 && utelnetd -d -i br0" to backdoor the device. Now, The password is reset and we can take full control of the router.
I really enjoyed this article since it showed the messiness of hacking and making things work. There are a few interesting tricks in here as well, making it all the more enjoyable!