❌

Normal view

There are new articles available, click to refresh the page.
Before yesterdayBlog - Somerset Recon

Hacking the Furbo Dog Camera: Part III Fun with Firmware

8 December 2022 at 19:07

We’re back with another entry in our Furbo hacking escapade! In our last post we mentioned we were taking a look at the then recently released Furbo Mini device and we are finally getting around to writing about what we found.

Background

Some time in the fall of 2021 we got a notification that Furbo was releasing a new product called the Furbo Mini. Having not gotten much of a response from Furbo regarding our previously discovered vulnerabilities, we were curious to see if either of them could be used to exploit the Mini.

Upon receiving a couple of devices, we setup and configured one and ran a port scan to see what we had to work with. Unlike the other devices, our port scan found no listening services on the device, greatly eliminating a remote attack service. However, we weren’t ready to admit defeat just yet.

Vulnerability Hunting

We tore down the Mini device and found that they had moved from an Ambarella SoC found in version 2 and 2.5T to an Augentix SoC.

After probing some of the test points on the main PCB, we found UART enabled similarly to the previous devices. After utilizing an FTDI and attaching to the UART pins, we were presented with a login prompt which we did not have the credentials for. When rebooting the device the bootlogs indicated that the device was using uboot (instead of amboot on the Ambarella based devices). Pressing any key during the boot process allowed us to interrupt and enter a uboot shell. We modified the uboot boot parameters to change the init value to be /bin/sh, which dropped us into a root shell upon booting.

After obtaining a root shell on the Furbo Mini device via UART, we noticed that the filesystem was read-only. The bootlogs showed that the device used a SquashFS for its root filesystem, which is read-only. This means we can’t simply add a new user to the device from our UART shell. When modifying the init parameters to be init=/bin/sh the Furbo was not functioning fully as all the Furbo libraries and features were not started. Ultimately we wanted root access on a fully initialized device so we began to investigate the firmware update process.

The device downloads firmware from a publicly accessible S3 bucket with listing enabled allowing us to view everything hosted in the bucket. Upon initial reverse engineering of the firmware update process it did not appear that the Furbo Mini was doing digital signature checking of the firmware. Additionally, by monitoring UART we could see the curl command used to download the firmware from the S3 bucket. The command used the -k option which skips certificate verification and allows for insecure TLS connections. We wrote a custom python HTTPS server, created a self-signed certificate, configured our local router with a DNS entry to resolve the S3 bucket address to one of our laptops, and supplied the firmware image to the device we wanted to update. This allowed us to verify that we could indeed get the device to download firmware from a host we control, and allowed us to work out exact expected responses.

The device has two different slots it can boot from. After the update, the device was booting from Slot B. From uboot, we switched the device back to Slot A to get it to boot with the out of date firmware version, allowing us to retest the update process. The next step was to modify the firmware to allow remote access after the update.

Exploitation

To exploit the Furbo Mini we needed to extract the firmware files and repackage the firmware with a backdoor installed to achieve remote code execution (RCE). The firmware file was an SWU file that could be downloaded directly from the S3 bucket. The firmware file contained a few layers. The first was extracted using the cpio command.

The rootfs.cpio.uboot.bin file was a UBI image. We used the ubireader tools (https://github.com/jrspruitt/ubi_reader) to extract the contents.

This left us with the SqaushFS file, which was extracted with the unsquashfs command.

As with any good challenge, we are greeted with a file named "THIS_IS_NOT_YOUR_ROOT_FILESYSTEM". Challenge accepted! We decided to modify the firmware and add a new user ("user") by changing the /etc/shadow and /etc/passwd files. The "user:x:0:0:root:/root:/bin/sh" string was added to /etc/passwd and "user:$1$TRFAGWPb$xwzaBH19Er5xEdJatZVwO0:10933:0:99999:7:::" was added to /etc/shadow.

Additional analysis of the firmware showed us that the device could be put into developer mode which enables telnet and another custom binary called unicorn. The unicorn binary itself was very interesting and will be the subject of another blog post. For our purposes we wanted telnet for an easy remote connection after the update. We modified an init script to start telnetd and then repackaged the firmware.

The SquashFS file was rebuilt with the mksquashfs command.

The next trick was padding the firmware file to match the size of the prior firmware file.Β Notice that the files have a different size below.

We wrote a small python script to pad the new SquashFS with the correct amount of data.

Next we re-wrapped the squashfs onto a UBI block with the ubinize tool. To get this step correct we needed to check the GD5F2GQ5xExxH NAND flash datasheet (https://www.gigadevice.com/datasheet/gd5f2gq5xexxh/) to find the block size (128KiB) and page size (2048 bytes).

The last step was to repackage the SWU file with our modified rootfs in the correct order. We used a small bash script to accomplish this.

With the modified file matching the format of the original, we spun up our python server running with our self-signed certificate, and attempted another firmware update. After waiting for the update process to complete, we attempted to login to the device via telnet using the credentials we added and it worked!

The result demonstrates that any Furbo Mini can be compromised with an active man-in-the-middle attack and a specially crafted firmware file. This could result in an attacker viewing the camera feed, listening to audio, stealing WiFi credentials, transmitting malicious audio or tossing treats.

Disclosure and Timeline

Similar to our last Furbo 2.5T vulnerabilities, we have disclosed the Furbo Mini vulnerabilities to Furbo but the devices still remain vulnerable and unpatched.


Event Date
Purchased Furbo Mini 10/2/2021
Successfully backdoored firmware 10/7/2021
Attempted to contact furbo to disclose issues 10/8/2021

Hacking the Furbo Dog Camera: Part II

12 October 2021 at 16:49

As mentioned in our previous post, Part II is a continuation of our research sparked by changes found in the revised Furbo 2.5T devices. This post specifically covers a command injection vulnerability (CVE-2021-32452) discovered in the HTTP server running on the Furbo 2.5T devices. If you happened to watch our talk at the LayerOne conference, you may have already seen this in action!

Background

After purchasing an additional Furbo to test a finalized version of our RTSP exploit on a new, unmodified Furbo, we found that our RTSP exploit wasn’t working. The RTSP service still appeared to be crashing, however it was not restarting so our strategy of brute-forcing the libc base address was no longer valid. After running an nmap scan targeting the new device we quickly realized something was different.

This Furbo had telnet and a web server listening. Physical inspection of the device revealed that the model number was 2.5T vs 2.

We disassembled the new Furbo and while there were some slight hardware differences, we were still able to get a root shell via UART in the same manner as the Furbo 2.

We decided to take a look at the web server first to see what functionality it included.

Web Server Reverse Engineering

Browsing to the IP of the Furbo presented us with an Authentication Required window. Observing the request indicated that the server was utilizing Digest Authentication, which was confirmed by looking at the server configuration.

The following is a snippet from /etc/lighttpd/lighttpd.conf:

...
auth.debug = 0                                                       
auth.backend = "htdigest"                                            
auth.backend.htdigest.userfile = "/etc/lighttpd/webpass.txt"                                                                               
                                                                     
auth.require = ( "/" =>                                              
  (                                                                  
  "method" => "digest",                                              
  "realm" => "ambarella",                                            
  "require" => "valid-user"                                          
  )                                                                  
)    
...

And the contents of /etc/lighttpd/webpass.txt:

admin:ycam.com:913fd17138fb6298ccf77d3853ddcf9f

We were able to quickly determine that the hashed value above is admin by utilizing the formula HASH = MD5(username:realm:password).

$ echo -ne "admin:ycam.com:admin" | md5
913fd17138fb6298ccf77d3853ddcf9f

However, when entering the credentials admin:admin we were still met with an Access Denied response. If you have a keen eye you may have noticed that the realm specified in the lighttpd.conf file is different from that specified in the webpass.txt file. This mismatch was preventing the authentication from succeeding. After some additional testing, we found that we could intercept the server response and modify the realm the Furbo was sending to the browser to create the Digest Authentication header. Intercepting the response and setting the realm to ycam.com allowed us to successfully authenticate to the web server.

Note the browser prompt displays ycam.com after we modified the response in Burp Suite. After entering the username and password we had access to the web server.

Once we were able to interact with the web application,Β observing some requests in burp immediately revealed some interesting responses. The web application was utilizing a CGI executable, ldc.cgi, which appeared to be taking multiple parameters and inserting them into a command, /usr/local/bin/test_ldc, which then gets executed on the Furbo.

This looked like a good candidate for command injection and after a few more tests, we found our suspicions were correct! We attempted to inject cat /etc/passwd into various parameters.

As seen above, a payload of ;+cat/etc/passwd+; in the X parameter was injected into the /usr/local/bin/test_ldc command and the results were included in the response! The web server was also running as root, so we had code execution as root on the new Furbo. The mode, X, Y, zoom_num, zoom_denum, pano_h_fov parameters were all vulnerable. This exploit is much more reliable than the RTSP buffer overflow as it does not involve memory corruption and the web server does not crash.

After confirming via dynamic testing, we grabbed the ldc.cgi executable off of the Furbo and popped it into Ghidra to see exactly what was happening under the hood.

The above snippet shows the various parameters we observed being retrieved and stored in variables, which then are used to build the cmd variable via the first snprintf() call. No sanitization is performed on any of the values received from the HTTP request. The cmd variable is then passed directly to a system() call seen at the bottom of the screen shot.

We created a python script that calculates the Authorization Digest header using the proper realm to automate the command injection and retrieval of results:

We also turned the exploit into a metasploit module:

Both scripts can be found on our GitHub page!

Disclosure


Event Date
Vulnerability discovered 03/12/2021
Vulnerability PoC 03/12/2021
Attempt to contact Ambarella via LinkedIn, web form, and email 3/17/2021
Attempt to re-establish contact with Tomofun 3/19/2021
Attempt to contact Ambarella via web form 4/26/2021
Applied for CVE 5/6/2021
Presented at LayerOne 5/29/2021
Assigned CVE-2021-32452 10/6/2021
Publish Blog Post 10/12/2021

Conclusion

The command injection vulnerability allows for consistent, reliable exploitation as it does not involve memory corruption like the RTSP buffer overflow which proved more difficult to exploit. We suspect that the command injection vulnerability may also be present in other devices that utilize Ambarella chipsets with the lighttpd server enabled. We would love to hear from you if you successfully test this on your devices!

Lastly, we've recently got our hands on the newly released Furbo Mini Cam, which saw some hardware changes including a new SoC. Stay tuned for our next post!

❌
❌