In this blog, the second in the series, you will learn about how to build a database of Bluetooth Low-Energy (BTLE) Generic Attribute (GATT) Universally Unique Identifiers (UUIDs) capable of remotely identifying Bluetooth Low-Energy devices for the purposes of vulnerability research, exploitation, and quantifying impact.
The importance of understanding this subject matter is put into context by highlighting recent physiological harm caused by BTLE enabled insulin pumps. The methodologies are demonstrated via CVE-2024-40892 and CVE-2024-40893; vulnerabilities that were discovered in Firewalla firewall products as part of this research.
Recently, the FDA issued a Class I recall, the most serious type of recall, for software Version 2.7 of the Apple iOS t:connect mobile app used to interface with a t:slim X2 insulin pump. The reason for the recall is stated to be due to the app repeatedly crashing/restarting. This results in increased battery drain due to excessive bluetooth communications, ultimately ending with the insulin pump shutting down. There have been 224 reported injuries as of April 15, 2024 according to the FDA.
The physical
insulin pumphardware which resulted in injuries caused by excessive bluetooth communications was NOT recalled and presumably remains unchanged.
The unfortunate truth is the only issue resolved through this recall is that of the vendor removing access to a bluetooth client that resulted in injuries due to a bug in the software they are responsible. Excessive bluetooth communications (A.K.A. radio spam) resulting in battery drain or device crashes on medical devices requires no novel understanding of bluetooth to carry out. In fact, this is the second time I’m saying this publicly about BTLE enabled insuling pumps in particular.
Injuries relating to BTLE enabled devices are not theoretical. A cursory review of many devices will reveal that repeatedly reading a BTLE device’s battery service; a completely normal operation, will quickly drain the battery as a result of increased radio communications and negatively impact the user’s quality of life. I am not a healthcare or policy expert, but it appears someone (FDA? FCC? Vendors?) are failing miserably at due diligence when it comes to the impact of bluetooth on healthcare, particularly relating to vulnerable individuals.
As stated in the first blog in this series:
- Measuring the impact of security and privacy implications of Bluetooth is even harder.
The real world potential harm caused by BTLE vulnerabilities proveably extends beyond just privacy and security. It is imperative that as an increasing number of BTLE medical devices are introduced into circulation that we have some way to measure and quantify these systems. But enough about the mediocrity that is the current state of BTLE devices in healthcare.
Let’s learn how to take a measure of the BTLE ecosystem as a whole so that we can enable meaningful and informed conversations. For every section introducing complex and necessary background information you will find a proposed “shortcut” at the end, often allowing the task to be accomplished with nothing more than built in system tools you already have available.
How Bad is the Best-Case Scenario?
“The conclusion is: Bluetooth vulnerability assessment is not even a thing. For those of you that work enterprise security, I’m happy to tell you: Don’t worry, there’s nothing you have to do, because there’s nothing you could do even if you wanted to. I hope that makes you feel better.” - Xeno Kovah (Open Wounds: The Last 5 Years Have Left Bluetooth To Bleed)
If a vulnerability exists in a BTLE device, one of the overall best-case scenarios for a device to ever receive a patch for a software bug/vulnerability is through a companion smartphone app since a smartphone has both:
- An internet connection capable of downloading the patch.
- A BTLE radio capable of pushing the patch to the vulnerable BTLE device.
Despite this blog being Part 2, it was started many, many, many months before Part 1. I have now curated a massive collection of Android application PacKages (APK). If you don’t have that kind of patience, don’t fret, you can follow along at home with just a single APK, such as RoboRoach.
What is an APK and how does it help us with BTLE?
An android application package (APK) that interacts with a remote device over BTLE will contain all the the necessary code to do so. If we are able to curate a collection of these APK files, we can get a view into the BTLE ecosystem from a point-of-view that does not necessitate being within physical radio proximity to a device. Additionally, the dataset will encompass the best-case scenario mentioned before the break.
Reverse engineering and vulnerability analysis of Android APKs is a complex topic. This section aims solely to introduce the nature of the file structure and shortcuts that can be used to quickly determine “Does this APK use Bluetooth?” as a filter for curating our collection. Later sections in this blog will describe how to extract uniquely identifying attributes in the form of UUIDs to create a database for remote device identification in practice.
Android APK files are just ZIP files. If you rename their file extension to .zip, you can extract them to a folder to peek inside at the contents and get familiar. Contents will vary, but generally you’ll find the following files:
AndroidManifest.xml
Despite its file extension, this is not plaintext XML. This Android binary XML (A.K.A. “AXML”) defines the application name, permissions, and various metadata regarding the app.
classes<NUMBER>.dex
The DEX files are dalvik bytecode , a register-based machine. This is the core code that runs in a platform-independent way across various phone hardware and CPU architectures.
/lib/<CPU_ARCHITECTURE>/library.so
The SO files are Shared Object libraries containing CPU-architecture native assembly code. Typically these are shared object libraries that export Java Native Interfaces (JNI) which allow the platform-independent DEX code to load and execute platform-dependent SO code.
So how do we check if
unknown.apkuses Bluetooth?
Well, the app can’t use Bluetooth unless it’s registered with the correct permissions in the manifest. We can check this easily using apkanalyzer which is part of the official Android SDK.
$ apkanalyzer manifest permissions unknown.apk | grep "BLUETOOTH"
android.permission.BLUETOOTH_ADMIN
android.permission.BLUETOOTH_SCAN
android.permission.BLUETOOTH
android.permission.BLUETOOTH_CONNECTNote: If you’re sourcing your APKs from certain Android app marketplaces, they may have an API endpoint that allows for you to check for the permissions requested by the app before you download it.
We now know that unknown.apk registers Bluetooth permissions. However, this doesn’t necessarily mean it uses them to do the things we’re interested in regarding BTLE GATT. Many apps use location APIs for maps, for which Bluetooth is an important part of determining an accurate location of a phone, but isn’t directly relevant to this research.
How do we determine if
unknown.apkuses Bluetooth GATT?
While I believe it is technically possible to use Bluetooth purely from native assembly code, I’ve not found any examples of that occurring, and it looks quite painful to attempt. All observed developers will use the readily available android.bluetooth.BluetoothGatt classes. When their code is compiled to DEX the format for the name of the class changes slightly, but a class in the raw dalvik bytecode is prefixed with L.
We can use the following commands to determine if an APK utilizes the relevant GATT classes.
$ unzip -qq -c unknown.apk "*.dex" | grep 'Landroid/bluetooth/BluetoothGatt'
grep: (standard input): binary file matchesIt can be inferred that presence of the class string android.bluetooth.BluetoothGatt is enough to reasonably assert that the app also likely has the necessary permissions to use the class, thereby eliminating the need to explicitly check permissions as an independent step.
Does this Remote Identification System Work In Practice?
At time of writing there are ~3M Android apps available in the Google Play Store, with more available in other Android App stores worldwide.
For a sampling:
- 515,765 apps were indexed.
- 74,590 of those apps had
android.permission.BLUETOOTHpermissions.
- 45,735 of those apps were downloaded from the Google Play Store.
- 14,681 of those apps included classes for
android.bluetooth.BluetoothGatt.*.
These were used to create a database of UUIDs. Now, when scanning and indexing the service/characteristic GATT tree from a remote BTLE device I can instantly query the database through an HTTP endpoint to identify the corresponding Android APK that shares the most overlap with those UUID’s.
Sitting at my desk one night while tinkering on this project I had just finished a piece of code that scans remote BTLE devices and attempts to look up their corresponding Android apps in real time using an HTTP API I’d built. The system worked instantly, uniquely identifying a system out of thin air!

UUID’s collected from a local BTLE device (Left) and the corresponding 95% accurate APK identification for
com.firewalla.chancellor(Right)
- Unbeknownst to me at the time, my internet connectivity had dropped.
- Lack of internet connectivity triggered a behavior which exposed an undocumented BTLE interface on my Firewalla firewall.
- My real-time API identified the corresponding Android APK to communicate with the device in my local proximity.
- A downloadable filepath is provided to me to immediately begin decompiling the APK and extract the relevant APIs and protocols needed to interact with the device.
At this point in time, I opened the APK for manual analysis in Ghidra and immediately spotted the text -----BEGIN RSA PRIVATE KEY----- in code with close proximity to the utilization of several of the BTLE UUIDs, prompting further investigation due to the fact that private keys should ideally be…private.
Firewalla Analysis
My analysis of the Firewalla App, Hardware, and Web services were explicitly scoped to bluetooth functionality. I performed this analysis not as a comprehensive audit, but as a deliberate demonstration of generic point-and-shoot bluetooth device identification for the purposes of vulnerability research and exploitation. The vulnerabilities identified were for the purposes of enhancing the narrative and subject matter of this blog, nothing more.
Firewalla Device Introduction:
The Firewalla Purple/Purple SE/Gold/Gold Pro is a next generation firewall for home, small to medium businesses, and Managed Service Providers. It features network flow insights, control policies, IDS/IPS, cloud-based behavioral analytics, and VPN functionality. All configuration and logs are synced and controlled by https://my.firewalla.com for a unified cloud based management interface.
By default, no network protocol ports are available on the WAN interface. Even inbound ICMP is disallowed.
The firmware as deployed on these devices is open source and a combination of https://github.com/firewalla/firewalla and https://github.com/firewalla/firerouter/. For initial setup where internet may not be immediately available for cloud synchronization, an out-of-band management interface (backdoor) binary named firereset is spawned which advertises a Bluetooth Low-Energy (BTLE) interface. As part of the setup flow, the end-user is prompted to scan the QR code on the bottom of the device which contains the license UUID of form 00000000-0000-0000-0000-000000000000 in order to register the device to the firewalla cloud. The initial setup configuration values are persisted to a redis service running locally on the device.
After initial configuration, the firereset binary remains present and inactive unless WAN connectivity to the internet is disrupted. This is determined by checkWanConnectivity.
By default, a disruption in WAN connectivity is determined using the following values:
checkWanConnectivity(
defaultPingTestIP = ["1.1.1.1", "8.8.8.8", "9.9.9.9"],
defaultPingTestCount = 8,
defaultPingSuccessRate = 0.5,
defaultDnsTestDomain = "github.com",
forceExtraConf = {},
sendEvent = false
){...}If greater than 4 ICMP ping responses to a defaultPingTestIP are exceeded or if the DNS hostname github.com cannot be resolved to an IP, the BTLE firereset service is started for a number of minutes.
Remotely disrupting the WAN connectivity checks in order to expose the out-of-band management interface is trivial. Methods include but are not limited to: Spoofed erroneous ICMP/DNS responses, DDoS, copper wire wrapped around a ferrite bead attached to a piezoelectric propane grill igniter.
CVE-2024-40892
The license UUID located in the QR code on the bottom of the hardware is the primary authenticating factor for the device, cannot be changed by the end-user, and exists for the lifetime of the device’s operation. In the event a network disruption occurs resulting in the firereset service starting, Android/iOS devices that are paired with the Firewalla hardware will automatically fall back to BTLE as a communication mechanism. The end-user will transmit their license UUID in plain text contained in the token field, as well as any other information relevant to the running state of the Firewalla hardware.
As an example the readConfig action is shown below which is available on the BTLE service ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a8b at characteristic ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a8c. This action is triggered automatically by the app, in part to assist the end user in diagnosing recent changes which may have resulted in the network disruption.
{
"begin": true,
"end": true,
"token": "00000000-0000-0000-0000-000000000000",
"payload": "{\"action\":\"readConfig\"}"
}On the BTLE firereset service, all write operations require at minimum the token field containing the license UUID. There is a credential service that is used to provision SSH credentials available via BTLE service ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a7b at characteristic ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a7c that allows unauthenticated read operations. The returned values contain the gid which is the unique device identifier as registered in Firewalla cloud as well as the mac which is used in combination with the license UUID for registration with the Firewalla cloud.
{
"bc": true,
"gid": "ae75a104-dabb-4a6d-adab-f349283ebec6",
"v": 10,
"fv": 0,
"fb": false,
"mac": "20:6d:31:00:00:00",
"name": "Firewalla",
"cs": "fgcf2bAj7Y8="
}The last remaining value cs is a “checksum” of the registered license UUID. The following python code is equivalent to its operation.
import hashlib
import base64
def checkSum(uuidString):
str2 = uuidString[:8]
m = hashlib.sha256()
m.update(str2.encode())
arrayofByte = bytearray(m.digest())
return base64.standard_b64encode(arrayofByte[:8])It is possible to recover the first 8 characters of the license UUID in a manner of seconds by either using a pre-computed lookup table or SHA-256 intrinsics.
At a minimum, this negatively affects the predictability of the license UUID.
For legacy reasons, in some cases only the first 8 characters of a license are validated. However, this section of logic directly interacts with the “Bone” registration/authentication API for Firewalla’s cloud management platform and I did not explore it further.
Equipped with a license UUID obtained by plain-text BTLE sniffing, bruteforce of remaining keyspace from unauthenticated checksum, physical access to the device, or a logic bug in the unexplored Bone API: A malicious actor has permanent irrevocable remote access via BTLE to configure the device.
There is a credential service that is used to provision SSH credentials available via BTLE service ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a7b at characteristic ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a7c. As this is a sensitive interface, the JSON-in-JSON protocol for this service also utilizes another layer of JSON with signed JSON Web Tokens.
The public key as used by firereset can be quickly retrieved from the UPX-compressed pre-compiled Golang binary in their open source repository with the following commands:
wget https://raw.githubusercontent.com/firewalla/firerouter/629683aa24fe7c527cf6570815a513bb006dcd75/platform/purple/bin/firereset
upx -d firereset
strings firereset | grep -A 13 "\-\-\-\-\-BEGIN PUBLIC KEY\-\-\-\-\-"The private key used to sign the JSON Web Tokens is the same for every Firewalla user/device and is readily available in plain-text within the Firewalla Android app:
We demonstrate this below by signing a fake license UUID payload for which the signature is validated using the public key:

By default SSH access is only available on the LAN side of the Firewall. WiFi configuration, access, and credentials can be provisioned via BTLE network configuration service ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a8b at characteristic ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a8c at which point SSH access over WiFi is trivial.
CVE-2024-40893
If you prefer not to stay within WiFi radio proximity, the BTLE network configuration service ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a8b at characteristic ed4cc6a8-3fcf-4b2b-a15a-157fa8a70a8c exposes multiple trivial command-injection vulnerabilities that can be used to establish a reverse shell over the WAN interface. As a network appliance enjoying the benfits of a memory-safe programming language, everything passes through the system shell eventually, as is shown by the ~340 unsanitized .exec() calls throughout the firerouter/firewalla codebases.
Throwing a ; into the configurations for the WAN interfaces surfaces 3 separate command injection vulnerabilities right away. sudo can also be utilized without requiring a password. Since the PingTestIP and DNSTestDomain values are used for health checks, they will be executed in perpetuity every 10-15 seconds.
networkConfig.Interface.Phy.Eth0.Extra.PingTestIP = []string{";touch /tmp/pwn5"}
networkConfig.Interface.Phy.Eth0.Extra.DNSTestDomain = ";touch /tmp/pwn6"
networkConfig.Interface.Phy.Eth0.Gateway6 = ";touch /tmp/pwn7"
Operationally, these parameters can be prefixed with space characters " " to visually push the command injection payload beyond the bounds that are viewable by the end user through the app/webapp.
Additionally, the firewalla does not persist filesystem changes across reboots, but the vulnerable parameters for network configuration are stored in redis which is the exception to that rule.
Additionally, since these parameters are synced to the Firewalla cloud and device restore/migration is supported, an attacker can trivially persist internet based remote access even if the hardware is reset and/or firmware is re-flashed.
Proof of Concept
Code:
Leveraging CVE-2024-40893 to execute a reverse shell and achieve remote code execution as root on a Firewalla Purple.
What have we learned?
Quantifying the security and privacy impacts of Bluetooth is hard due to the disparate availability of resources, complexity of analysis, and further complicated by the constraints of physically being within radio proximity. These attributes create difficulty in achieving a holistic understanding of the BTLE ecosystem.
However, once the subject matter is understood, simple shortcuts can be applied to instantly identify and profile remote devices that meet a best-case scenario of ever receiving software updates.
From insulin pumps to firewalls, the best-case scenario of BTLE security and privacy is abysmal. It is imperative that we educate ourselves and strive to do better as an industry. Problems that are introduced in BTLE devices are likely to be permanent and impossible to resolve after the fact. Until that changes, we must do better from the start.