The authors decided to take a look at the TP-Link ER605 router and attack it from the WAN network. When looking at the attack surface, they decided to check out the dynamic DNS (DDNS) provider Comexe that was used by the router. There are many custom components to the DDNS, which is super scary on something that's externally accessible.
The device tries to access its DDNS servers of the Comexe servers. To get the servers IP, it tries to resolve it with a regular DNS query. After getting the IP address, a connection over UDP is made with encrypted data with a hardcoded key. Since there is no host validation via TLS or something similar, an attacker can just impersonate the process to receive and send requests to the client device! This requires a MitM to do.
With an easy authentication bypass in the bag, there is now more attack surface. When parsing the response code, it assumes it uses the length of the bytes for the length of a strncpy and copies the bytes, leading to a buffer overflow on the stack. With 800 bytes at their disposal, they could trivially overwrite EIP on the stack to get code execution. They found several more overflows like this but this was the most juicy.
Not so fast! Even though there are no stack canaries, the device has ASLR. Another buffer overflow they found was the copying of a user controlled buffer into the globals section that should only be 0x80 in size. Using this overflow, we can corrupt various parts of the globals to affect the program. For instance, even though the length of a DNS entry was 0x80, this can be corrupted to allow for larger values. Using this bug, we can write more data to the stack to corrupt a return length on the call, resulting in a large OOB. With this, they can read the address of libc from the stack.
Now, they can use the RET2LibC attack to get code execution on the device! From there, they wanted to pivot to another
target - the Synology IP camera. Within this, they found a fairly simple buffer overflow onto the stack when parsing JSON data via
sscanf(). Since this API requires no authentication, we're in business!
On the stack, was a function pointer that they could set to system and the parameter happened to be controlled by them as well! The binary used many protections, such as RELRO and NX but not stack canaries. Additionally, ASLR/PIE was used on the device but only 8 bits of random for the app code and 12 bits of random for the heap. So, how do we defeat this? Brute force!
The heap can easily be sprayed by providing a ton of data. The location of system appears to be brute forced, since 1/256 is doable on this program. They had some troubles with encoding as well, since everything had to be valid UTF-8 characters and couldn't contain actual nullbytes. But, they worked through this.
Overall, a solid post on the bug hunting experience in pwn2own! There's a major difference between real world exploits and CTFs which I enjoy seeing