The beginning of the article goes through dumping the firmware from a serial flash chip and accessing UART interface. In the UART interface, they noticed that the Linux OS was not giving any output. To fix this, they modified some UBoot settings to turn on the output. They popped them into a limited but not root shell, limiting their initial capabilities. Now, time for a chain of vulnerabilities!
In the sonia binary, they found a super simple unauthenticated stack buffer overflow. The systems has ASLR enabled, stack canaries and the write is via a strcpy, which limits the amount of NULL bytes we can write. Luckily, there is no PIE. By using a partial overwrite of the stack address (3 bytes), we don't need to break ASLR. In some cases, the 4th byte will be NULL and we will write to that with our NULL byte then. I'm guessing they brute forced this 1/256 chance.
This really limits our exploitation though. We can't write bytes after our address or any null bytes before that. The authors used this exploit to open up a new attack surface: the Image Quality Service (IQ). By calling the function sonia!thread_listen_handle, an unauthenticated listener is created that will loop infinitely. Neat!
Within the IQ functionality, they found a heap out-of-bounds read that returns information directly to the caller. Typically, this is used for an ASLR leak, but the authors had a better idea. In a separate service (DHIP) on the same binary, there are several unauthenticated commands like resetPassword that require a special 8-byte Auth Code with secrets known to the device and technican. By using the heap leak, the secrets for the string can be leaked by continually calling checkAuthCode! Wow, that's a pretty neat exploit and usage of an information leak!
The DHIP service contains an authenticated buffer overflow as well - it's a stack-based overflow into a stack buffer in JSON parsing. Now that we have leaked the password reset information, we have authenticated access to the service. The overflow occurs in a strncpy, which doesn't allow the writing of nullbytes with [ being overwritten with nullbytes after the overflow occurs.
The bug above allows writing a single pointer so the gadget must be chosen wisely and then overwrite the return address of the function. At 0x002C0A2C, there is a gadget that will execute arbitrary bash commands from a single provided stack buffer input. I'm slightly confused on how this works alongside ASLR but they say it does :) They had to do some shenanigans to force this not to crash after this point too. Now, we have a command execution on the system!
For whatever reason, this wasn't enough for them - they wanted the ability to execute arbitrary binaries. Since the kernel had ELF binary signature verification, this wasn't directly possible though. LD_PRELOAD can be used to load a library in an approved command to easily circumvent this protection though.
Overall, it is a super interesting blog post on the exploitation of this device. The usage of pre-existing functions to exploit the binary twice instead of a traditional ROP chain is cool to see. Additionally, the heap OOB read to leak secrets is a rare feat as well. To me, this means that binary exploitation will never die but the tricks may become different.
I was curious about the
order in which the bugs were found and got a
response from the author. They found the RCE bug first to allow for better debugging. Then, they wanted an auth bypass, which led to them finding the overflow and OOB read in the IQ stack. Upon realizing this wasn't hittable code, they found a way to turn it on. So, they effectively did this in reverse!