The Furbo is a dog camera. It connects to the phone via BLUE and connects over the local WiFi network as well. The device uses RTSP on port 554 to stream video and audio.
By fuzzing the RTSP service, a crash was caused by sending a corrupted packet. In particular, the username was quite long. So, we've got a crash on an IoT device: it is time to open it up!
The Ambarella SoC was the primary target: as a highly-capable ARM Cortex-A9 SoC running Linux (compared to the fairly limited PIC16 and wireless chips), it performs all the important functions of the Furbo. With the datasheet easily accessible online, they found UART test points on the board, which were easy to connect to.
The terminal is protected by login credentials. However, the Das U-Boot can be interrupted! By changing the boot-time parameters, a shell can be popped on the device. At this point, a user can be added to /etc/passwd to get persistent access to the device.
On the device was a single script that turned everything on. By manually running the script and causing the crash, lots of nice information about the process was printed out. At this point, they added statically compiled versions of ssh and gdb to make debugging significantly easier.
GDB showed that the segfault occurred because the address of the stack address was set to 0x41414141 or a bunch of A's from fuzzing. The system has ASLR enabled, NX enabled on the binary but the binary is not compiled with PIE.
The address of the binary (when not compiled with PIE) had leading nullbytes, which made this exploit not possible. As a quick POC, they disabled ASLR on the system and found a group of 3 gadgets within LibC to get code execution. But, we still need a memory leak!
Instead of looking for a memory leak, they attempted to brute force the space. The address of LibC was always loaded at 0x76CXX000 where XX varied. Additionally, C would sometimes be D. Brute forcing this is a 1/4096 chance or 12 bits of entropy.
If the program would crash, the watchdog script would turn the program right back on. By abusing the lack of randomness flaw, this would take anywhere from 2 minutes to 4 hours.