6 Ways to Help Your Penetration Test Vendor Find More Vulnerabilities
Learn how to help your penetration test vendors find more security vulnerabilities and ensure maximum coverage.
In the second part of our Hacking Furbo blog series we will focus on the mobile application and P2P communications from it. We will detail our process of identifying the mobile-side of the P2P communications and hooking them with Frida for a deeper understanding of how they work.
The Furbo mobile application is where all of the magic happens for a device owner. From here you can configure your device, surveil your pet, and toss treats (on the Furbo 360). They have also added, as many companies unfortunately do these days, an AI chat feature which allows you to get advice about your pet and query data.
Pulling the app down with adb, we gave it a quick run through MobSF to pick up any low hanging fruit and found that there was surprisingly little to report on from that review.
We also performed some mobile-specific tests, looking at things like exported services, service providers, activities and the like, without much success. We were able to get one finding from this however: insecure storage of sensitive information in the device's memory.
When you are assessing a mobile application and its handling of sensitive information in memory you must first identify several things you'd like to hunt for. As we would learn in the subsequent sections of this article, the Furbo device and mobile app perform some authentication to each other. We could see some of the API requests to the Furbo servers which initiated this authentication flow in the proxy history. These would be a valuable target.
Additionally, there were the CognitoTokens which were used to authenticate each request which we could hunt for. Any of these being found in memory could mean that an attacker could retrieve it and re-use it to take over the victim's account or Furbo device.
So, to test this we would have to do the following on a jail broken Android device with Frida installed:
This creates a dump of the device's memory in its current state. In a perfectly configured app, no sensitive information should reside in memory after the application has been terminated. Once the dump is completed we navigate into the output directory and grep for some of those previously identified sensitive details from the web proxy history.
Grepping through the Fridump output directory, we found that each of these aforementioned values have been stored in memory, after the application has been logged out from and terminated.
Next, we focused our attention on identifying how the device and the mobile application communicated with each other. We knew a few things, the device was communicating outbound over UDP port 10001, we found several Shared Object Libraries referencing TUTK, and we had seen some references to TUTK in the UART logs. All of this helped us determine that the P2P communication protocol in use was ThroughTek's Kalay Platform, from here on out we'll simply refer to it as TUTK P2P since that is how it was referenced in the code for the Furbo device and mobile application.
This was a drastic change in direction from the previous research we had seen. For those unfamiliar with the work of SomersetRecon, they had done a review in 2021 of the Furbo 2.5 and first edition of the Furbo Mini in a three part blog series, the first part can be found here. These devices were relying upon a RTSP stream to allow owners to view their cameras. Unfortunately for us the TUTK P2P protocol is much more secure and has far less public documentation available.
We spent quite a number of hours looking for public documentation on the protocol and came up with little. What we did find was that a researcher who goes by Kroo had released a Python library which could be used to communicate with Wyzecam devices, which also use TUTK P2P. This wouldn't exactly work for us—the level of effort to get it ported to Furbo wasn't reasonable for our research. We also came across some great research done by Mandiant into the protocol itself in 2021 which resulted in some huge headlines. Mandiant's paper which details this research, "Mandiant Discloses Critical Vulnerability Affecting Millions of IoT Devices" can be found here. We attempted to reach out to the authors of this report in the hopes that they may be able to shed some additional light on their exploits but to no avail.
In spite of this, we were able to glean a lot of information as the research was very detailed and gave us a far better understanding about how these communications worked. Seen below is an illustration, taken from their research paper, of how devices, mobile apps, and the Kalay network communicate with each other.
Based on this, we decided (after spending quite a bit of time trying to set up our own Python implementation) to forego the hard path and stick to something a bit easier instead: hooking the communications from the mobile application with Frida which could allow us to monitor and tamper with the traffic.
As we now knew the protocol in use, we decided to try to find the files which handled the P2P communications from the decompiled application. This would allow us to understand the command structure, the expected inputs, and to see if there were any hidden features, all of which would help us once we hooked the functions.
We found that the TUTK files resided under ./sources/com/tutk/, fairly straight forward and easy to guess.
Then, grepping for some of the various names we saw in the UART logs we found that the P2P command handling is implemented in the files which reside in: /sources/com/tomofun/furbo/device/p2p/cmd
After having reviewed each of these, our best guess was that the FurboP2pCmdImplTutkV3.java was what we would need to hook. This was because within this file we found the names of each P2P command as well as their definitions which explained what was expected for input.
Seen below is one of the commands which we will return to later.
With all of this information in tow, we used ChatGPT to generate a couple of Frida scripts with each having varying degrees of success. After a lot of debugging, a common experience for us when doing this kind of stuff with any LLM, we were able to get a working hook on the FurboP2pCmdImplTutkV3 function. With this Frida script we could monitor the content of the outbound and inbound communications between the device and mobile application.
Much of what we saw was quite basic, a command was issued, a confirmation of that command was received, without much data being sent in the payload of the request. This was not true for all commands though. The first device we had purchased for our research was the top of the line Furbo 360, which allowed you to toss treats at your pets which were accompanied with a noise. This noise could be customized in the mobile application to be a recording of anything! This sound could be configured from the device settings page. While hooked, we decided to record our own sound and change the treat toss noise. This resulted in the following command being issued.
Each recording would result in a request to obtain an S3 pre-signed URL, where the recording would be then uploaded, and finally the link was sent to the Furbo device where it would be retrieved and saved. Now, this was very, very interesting.
Using another Frida script, we re-hooked the same function but this time wrote it to replace any URLs sent in a command with a URL which we specified. Our hope with this was that we could get an arbitrary file upload to the device.
And, we were successful! We could have the Furbo 360 make a GET request to our specified URL.
We wanted to better understand how this was working and determine if we could elevate this SSRF into something a bit better. For that we would need to find the binary and the corresponding function which handled the request and saved the output. From our limited review of the binaries within the root filesystem in the previous article, we guessed it would likely be contained within the p2p_manager binary.
Our guess was right; this was all handled by the tfp2p_cmd_handler_receive_command function within the p2p_manager binary. When the command with the URL was received, no checks were performed on the URL and the device would download the file, unfortunately though it would always be saved as custom.wav. Meaning, we could not use this technique to upload a new firmware file or a reverse shell for execution. The only other hope was that the wav file parser would be written incorrectly, perhaps enabling us to do something like a buffer overflow. However, reviewing the function which handled this yielded no obvious routes to exploitation, the Tomofun development team did an excellent job handling all possibilities for this file—a consistent pain for us across many device functions.
So, with remote code execution off the table, what were we to do? Well, our binary analysis revealed that while the file would always be named custom.wav, there was no file size limit. This means we could upload any length of sound to the device for playing. With that in mind, we decided that we should get the device to play none other than Darude Sandstorm.
Converting a copy of the song to a wav file format, we hosted it on a Python server and sent the command to the device.
When hunting for a path to exploit the wav file upload, we found that the function which handled the playing of sounds was single-threaded. This meant that if we sent multiple requests to issue treat toss sounds we may be able to use up all of the threads, and trigger a Denial of Service.
Using the previous Frida script as a reference, we modified it to send multiple Treat Toss commands in unison.
Once we went into the app and selected the treat toss option from the video feed, a distorted sound would play once. Following that, we could no longer play any noises from the device until it had been rebooted. This may be far from the most exciting vulnerability, and not nearly as fun as the previous, but a vulnerability nonetheless.
And so that concludes part two in this six-part blog series. The knowledge we gained from this section regarding the mobile application's inner workings, specifically as it pertains to the P2P communications proved invaluable to us in the rest of our research. While we were unable to compromise the device through this, directly, we were able to gain a more thorough understanding of its authentication scheme, the traffic we were observing on our network, and we even got our Furbo to play Darude Sandstorm, all in all a win in our books.
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