
No-dongle, no-root Bluetooth security assessment tool for wireless earbuds affected by the Airoha SDK vulnerability chain (CVE-2025-20700/20701/20702)
Version 1.0.0
Bluetooth security assessment tool for wireless earbuds affected by the
Airoha SDK vulnerability chain (CVE-2025-20700 / CVE-2025-20701 /
CVE-2025-20702). Scans for nearby devices, fingerprints known-affected
Airoha-based chipsets, and probes for unauthenticated GATT access and RACE
protocol reachability - entirely through the OS Bluetooth stack (BlueZ) via
bleak. No external Bluetooth dongle is required and root is not needed.
Results are reported in plain language alongside the technical detail, so you
can act on them without deep Bluetooth knowledge.
This tool is for assessing devices you own or have explicit authorisation to
test. GATT and RACE probing are active operations: they connect to and send
commands to the target device. Do not run --gatt, --race, --firmware,
--bd-address, --assess, --baseline, --check-drift, or --memory-read
against a device that isn't yours or that you haven't been given permission
to test. --scan is passive and only listens to advertisements already
being broadcast publicly, so it's safe to run against whatever's in range.
--memory-read goes a step further than the other active probes: it
retrieves one real, read-only page (256 bytes) of the device's actual flash
content, at a fixed address, as a definitive confirmation of CVE-2025-20702
when the reachability-only --race probe gets no response. It is read-only
(flash reads carry no wear or bricking risk, unlike write/erase/FOTA
commands, which this tool never sends), opt-in, and requires its own
separate confirmation beyond the standard ownership prompt describing
exactly what it does before it runs anything.
Probing an arbitrary nearby device isn't just a policy concern - it can have
real side effects. --gatt attempts a read or notify-subscribe on every
characteristic it finds, and some consumer devices expose provisioning-style
services (e.g. Google's Fast Pair service) that react to that by kicking off
a real pairing handshake on the target device, independent of anything this
tool explicitly requests. A characteristic requiring encryption can trigger
the same thing even against your own device, since BlueZ can silently route
that authentication request to whatever agent your desktop has registered
(e.g. KDE's pairing prompt) - every active command therefore also registers
its own temporary BlueZ agent that auto-rejects any such request for the
duration of the probe, so no pairing prompt can appear at all. Every active
command also still prompts for confirmation that the target address is
yours before doing anything on the radio; pass --yes to skip the prompt
for scripted use once you've already confirmed it's your device:
buds_audit.py --assess --target AA:BB:CC:DD:EE:FF --yes
--watch is passive, like --scan - it only listens to advertisements
already being broadcast and never connects to anything, so it doesn't
prompt for confirmation.
python3 -m venv venv
venv/bin/pip install -r requirements.txt
Requires Python 3.10+ (developed against 3.14) and a Linux system running BlueZ with a powered-on Bluetooth adapter.
Linux only, and not automatically every Linux system:
bleak itself has a Windows backend, but
this tool doesn't rely on bleak alone - Bluetooth Classic discovery
(core/scanner.py) and bonding-state checks (core/gatt.py) both shell
out directly to bluetoothctl, a BlueZ-only CLI tool that doesn't exist
on Windows. Those code paths would just fail with "command not found."bluetoothctl on PATH, not just any Linux
kernel. Most desktop distros ship this; a minimal or server image without
the bluez package installed won't have it out of the box. Verified
root-free on BlueZ 5.86 - other versions should work the same way since
bleak targets BlueZ's standard D-Bus API, but that's not independently
re-verified.usbipd-win, which only forwards USB-attached
adapters. Most laptops' built-in Bluetooth is wired in over a non-USB
bus (SDIO/PCIe, alongside Wi-Fi), which usbipd-win generally can't
forward - so this depends entirely on the specific hardware.You don't need a Linux machine of your own - you just need Linux with real access to a Bluetooth radio. Two practical ways to get that:
Either way, the rule is the same: the tool itself is unchanged - it just needs Linux with a Bluetooth adapter BlueZ can actually reach.
Many TWS earbuds stop advertising (and drop any active connection) after a period of inactivity to save power, and some fully power off on their own. If a scan can't find a device it found a minute ago, or a probe fails partway through, that's usually the earbuds going idle, not a bug - take them out of the case or press the pairing button again and retry.
This also affects address stability: this project's confirmed test unit (a Sony WF-1000XM3) kept the same BLE address across every power cycle tested, which is expected for earbuds designed for companion-app reconnection - they typically use a fixed/public BLE address rather than a rotating one (unlike phones, which do rotate private addresses and aren't a suitable target for this tool for that reason). That's not guaranteed for every earbud model, though - some vendors use resolvable private addresses even in pre-pairing/reconnect mode, which would appear as a different address after each power cycle to an unpaired scanner like this tool.