Hacking Furbo - A Hardware Research Project: Part 6 – The Finale
Final chapter: insecure Wi-Fi credentials, risky S3 log uploads, long-lived device tokens, and global MQTT activity exposure, plus our June 23, 2025 disclosure to Tomofun.
In Part 4 of the Hacking Furbo blog series we will detail our dynamic analysis of the Furbo devices. We will show how the device was logging information, how that helped us better understand the binaries and their functions, as well as some developer features that we discovered after reviewing the file system. Using the information collected from our debugging we were able to exploit two more vulnerabilities: a Denial of Service and an Application Logic Bypass which allowed us to have unlimited trial licenses!
We used three techniques for debugging the different functions within the Furbo devices. The first method was simply monitoring the UART output; a lot of different data is logged to the UART console as the device is operating. This was very useful in the early stages of our research when we had yet to gain shell access to the device.
The second method was simple: we monitored the log files that were written under /tmp/log; the main Furbo binaries (p2p_mngr, manager, net_mngr, and others) were configured to log their information to this location. Once we had access over a shell we could tail these logs and see what functions were called when we interacted with the device.
Lastly, we used custom wrappers to generate logs for binaries that did not have logging enabled. As we had the ability to modify the firmware directly we were able to create wrapper files which would log details about the different services and scripts that were calling particular binaries.
We were able to replace the original binary with a wrapper file which would log details such as the PID, PPID, Process Name and even the full command line argument that was used to call the binary. The wrapper would then send that information to syslog and the original binary would be run using exec /bin/busybox [binary].
Here is an example wrapper created for logging ifconfig calls:
The MAC address of the device was being set using a script located in /etc/init.d/ called wifi_ble_init. This script contained the following logic which would check to see if the MAC address and Bluetooth MAC (BTMAC) address were specified in /mnt/hw/factory.json. If the MAC and BTMAC were present, it would write these details to the Wi-Fi adapter's configuration file: ssw114bs-wifi.cfg.
However, If MAC and BTMAC were not located in the factory.json file the device would then use e-fuse to specify the MAC address. This fallback functionality is specified in /tmp/ssw114bs-wifi.cfg.
Out of the box the Furbo's MAC address was being provided via the embedded information on the device's Wi-Fi chip (e-fuse technology). However, based on the logic we discovered in the wifi_ble_init script we could control the MAC address by modifying the addresses specified in the factory.json file.
In theory, all we had to do was add "system/info/mac" and "system/info/btMac", along with a defined MAC address for each, to the file in order to control the MAC address of our device. When the wifi_ble_init script was run, it would grab those values and save them to the Wi-Fi adapter's configuration file. Once saved to the configuration file these values would be used to set each of the respective MAC addresses when the interfaces were brought online.
After adding the required information to factory.json and rebooting the device we were able to confirm that our device's MAC addresses corresponded to the values supplied. The device was no longer using e-fuse to set the MAC address, which meant we had full control over the DeviceID used to register and maintain connectivity.
Furbo sells two types of devices, subscription and non-subscription devices and from this point on we will refer to these as "Sub" and "Non-Sub".
Sub devices receive a 30 day free trial upon first registration, to allow you to experience the full features of the device. However, a Sub device that is not activated, either by a trial license or a valid subscription plan is unusable. When you attempt to access the device within the Furbo mobile application you will be presented with a lock icon and the message, "Subscription Activation Required".
Once the trial has expired, you must purchase a monthly subscription plan which "Activates" the device, enabling all of the premium features.
As we hate subscriptions as much as the next person, we set our sights on identifying how these were assigned to a device with the goal of obtaining free trials for life!
We began by comparing two Sub devices, one which had an active free trial and one which did not. We identified clear differences within their "FeatureSet" which was visible to us in the UART logs. These features were also listed in the "permission" object located within the setup_info.json file.
This information provided us with the identifiers we needed to determine if we had successfully activated our device, resulting in another 30-day free trial.
An activated Sub device had the following features available:
An inactive or expired Sub device was limited to the following features:
The only obvious difference we could identify between an activated device and an inactive device was their DeviceIDs.
Our theory was simple: if we could change the Furbo's DeviceID, as we had done earlier, we may be able to "re-register" the device and get a new trial!There are a couple different ways to re-register a device but the simplest way we identified was by removing the setup_info.json file. If this file is not present on boot it will be re-generated and the "register_done" value within the object will be set to 0, putting the device into a state where it can be registered using the mobile app.
After making these changes to the inactive Sub device, we attempted to re-register it using the mobile app. While re-registering the device we monitored the UART Logs as well as the permissions object to see what features would become available. Once the registration was complete we saw a full feature setup appear in the logs and the permissions object was updated, the entire FeatureSet was available! This confirmed that a fresh trial license had been assigned to our device.
Within the Furbo application we saw a completely new device added to our account with a fully functional video stream.
Device with an expired trial license
Re-registered device with the new trial license
Limited testing of this attack revealed that there was not a specific range the address had to be within; the only limitation we found was that the MAC address you assign has to be a multicast-compliant Layer 2 address which isn't a limit enforced by Furbo, simply just a protocol level requirement.
After making this discovery around how DeviceID's were used for registering devices we immediately asked ourselves, "What would happen if you register someone else's device?"
Now that we could register new devices by simply changing the MAC address of the device we wanted to see what would happen if you registered the DeviceID of one which had not yet been purchased or registered. With the limited dataset we had developed from purchasing a handful of Furbo devices, we were able to identify a common structure for at least some of these addresses.
Two of the devices we had used the same four hexadecimal pairs for their MAC address: 14:C9:CF:0C:XX:XX. This meant there was a high likelihood that the DeviceIDs were sequential. Side note: we were able to determine that AccountIDs are generated sequentially which lends credence to this theory, although we could not find a technique to exploit this fact.
So as to responsibly test our theory, we limited our targeting to the DeviceIDs of cameras we owned.
In this scenario an attacker has a Furbo device of their own and they modify the DeviceID following the same procedure required for re-registering a device, only this time they set the MAC address to a value within the pool of addresses assigned to devices.
Once the camera restarts they can complete the activation and registration process for that DeviceID within the Furbo application and device will be added to their account
Attacker Registers Victim’s Camera:
Now, when the victim in this scenario receives their new camera and tries to register the device within the Furbo application they are presented with a generic error, “Something went wrong with your internet” and they are unable to register or use the device.
When we review the UART logs of the victim camera we find an error which states that their account doesn't own the camera and therefore they are unable to register their device.
Victim Attempts Registration:
If these DeviceIDs are indeed sequential, an attacker could start registering hundreds of devices, each time removing an address from the pool and "bricking" the device for future customers. In this scenario, there is nothing a victim can do as their device would be associated with an attacker account. It's likely that this Denial of Service can only be resolved by the Tomofun support team.
A keen eye may have noticed one area from Part 1 of the blog series that we have yet to explore, the web directory. As we had mentioned in our initial reconnaissance of the device and its exposed services, we had not found any open ports. This was true throughout our testing, no ports were opened in the default configuration. However, within the web directory there were several files which piqued our curiosity.
By this point we had obtained shell access over UART and were able to run various services as needed during our testing—including the web_srv binary which, of course, started the Furbo web server.
This webpage returned a number of options to us which would allow some interesting exploits including, without any doubt, Remote Code Execution. This could be achieved by re-packing a firmware file or software package with a reverse shell and uploading it here for execution.
Unfortunately though, as these binaries had to be run manually and we could not find another means by which we could ensure they would run without access to a terminal, we could not report this as an issue. It did, however, give us an interesting interface to play around with and modify system settings more easily.
One of these buttons, snapshot, allowed us to view the camera feed through the URL parameter value.
Interestingly—and we still have yet to determine why or how this ended up here—we found the following URL in the HTML source.
Navigating to the first IP address showed us a camera feed, from somewhere in the world.
We also discovered a hidden "factory mode", which would open up a root telnet shell for anyone to connect to, unauthenticated.
We found this factory mode by reviewing the rcS file which checked whether network/usb was enabled or not present within the factory.json file, to determine whether it should enable the shell.
This made life a bit easier for us, by running sed to replace the contents of the factory.json file we had another path to a root shell and didn't have to worry about getting connected to UART.
This concludes part four of the six-part blog series. In this part we were able to use different logging techniques in order to discover how the DeviceID was being set during boot. This enabled us to spoof devices not under our control, resulting in a denial of services to other consumers and unlocking unlimited trial licenses for our own physical device. We also discovered the hidden factory mode during our filesystem analysis and a web server used by developers. In the next part of our blog series we will detail our successes from analyzing the BLE services offered by Furbo devices!
Julian is an intermediate penetration tester with nearly five years of experience working in cybersecurity, dedicated to penetration testing, open-source intelligence gathering, and moving the needle forward for organizations across Canada. He regularly engages with the community through presentations at conferences, on a range of topics including vulnerability research and OSINT investigations. This is work is underlined by several CVEs which have been attributed to his research on open-source applications.
Security
Can be easily manipulated without detection if not properly secured.
Digitally signed and can be validated on the server. Manipulation can be detected.
Size
Limited to 4KB.
Can contain much more data, up to 8KB.
Dependency
Often used for session data on the server-side. The server needs to store the session map.
Contains all the necessary information in the token. Doesn’t need to store data on the server.
Storage Location
Browser cookie jar.
Local storage or client-side cookie.
The cybersecurity SaaS market is crowded and confusing. Many tools promise one-click safety yet ship noisy dashboards that do not plug into developer workflows.
Providing the quality of the biggest names in security without the price tag and complications.
Manual penetration testing
Full time Canadian hackers
Remediation support