## https://sploitus.com/exploit?id=8096C441-F073-583C-A999-B26FA59DEC05
# WhisperPair-PoC-Tool and Research
A deep dive into CVE-2025-36911 and the security gaps in Google's Fast Pair ecosystem
[Blog Post](https://personal-site-9ax.pages.dev/posts/whisperpair-poc-post)
## Executive Summary
Google Fast Pair was designed to make Bluetooth pairing seamless: tap a notification and you're connected. But what happens when that seamless experience becomes a security liability? **WhisperPair-PoC-Tool** is a security research tool that exposes two critical vulnerability classes affecting millions of Bluetooth accessories: unauthorized pairing bypass and Find My Device Network tracking exploitation.
This post details the technical internals of WhisperPair-PoC-Tool, the protocol weaknesses it exploits, and what this means for the Bluetooth accessory ecosystem.
---
## Table of Contents
1. [The Vulnerabilities](#the-vulnerabilities)
2. [Fast Pair Protocol Primer](#fast-pair-protocol-primer)
3. [How WhisperPair-PoC-Tool Works](#how-WhisperPair-PoC-Tool-works)
4. [The Attack Surface](#the-attack-surface)
5. [Detection Methodology](#detection-methodology)
6. [Exploitation Capabilities](#exploitation-capabilities)
7. [Remediation Guidance](#remediation-guidance)
8. [Ethical Considerations](#ethical-considerations)
---
## The Vulnerabilities
### CVE-2025-36911: Fast Pair Pairing Mode Bypass
The Google Fast Pair specification explicitly states:
> "If the optional Public Key field is present: If the device is not in pairing mode, ignore the write and exit."
>
> - [Google Fast Pair GATT Procedure Specification](https://developers.google.com/nearby/fast-pair/specifications/service/gatt)
This is the critical security gate. Devices should **only** respond to Key-Based Pairing requests when the user has explicitly put the device into pairing mode (typically by holding a button). This ensures user intent, so you can't pair with someone's earbuds while they're wearing them.
**The Problem:** Many manufacturers skip this check entirely. They process pairing requests regardless of pairing mode state, enabling:
- **Silent pairing** without user interaction
- **Accessory hijacking** in proximity attacks
- **Privacy violations** by connecting to victims' devices
### Find Hub Account Key Exposure
Google's Find My Device Network (FMDN) allows tracking Bluetooth accessories via the crowd-sourced Android device network. This requires an **Account Key**, a 16-byte symmetric key linking the device to a Google account.
**The Problem:** The Account Key characteristic often accepts writes without authentication:
- Attacker can **overwrite** an existing Account Key
- Victim's Find My Device integration **breaks**
- Attacker can **track the device** using their own key
- This persists until factory reset
---
## Fast Pair Protocol Primer
Before diving into the exploitation, let's understand the legitimate Fast Pair flow:
### Advertisement Phase
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ BLE Advertisement โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Service UUID: 0xFE2C (Fast Pair) โ
โ Service Data: โ
โ [Pairing Mode] โ 3 bytes: Model ID only โ
โ [Not Pairing] โ 4+ bytes: 0x00 + Account Key Filter โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
The advertisement format reveals pairing state:
- **3 bytes** = Model ID only = Device is discoverable (pairing mode)
- **4+ bytes** = Version byte + Account Key Data = Not in pairing mode
### Key-Based Pairing Handshake
```
Seeker (Phone) Provider (Accessory)
โ โ
โโโโโโ GATT Connect โโโโโโโโโโโโโโโโโโโโโโโโโโ>โ
โ โ
โโโโโโ Discover Services โโโโโโโโโโโโโโโโโโโโโ>โ
โโ
โ โ
โโโโโโ Write Key-Based Pairing Request โโโโโโโ>โ
โ [16-byte encrypted block] โ
โ [64-byte ECDH Public Key] (optional) โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ SECURITY CHECK: โ โ
โ โ If Public Key present AND โ โ
โ โ device NOT in pairing mode: โ โ
โ โ โ IGNORE and EXIT โ โ
โ โ Else: โ โ
โ โ โ Process request โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โโ
```
The vulnerability occurs when devices skip the "SECURITY CHECK" box entirely.
---
## How WhisperPair-PoC-Tool Works
WhisperPair-PoC-Tool is a Python-based security research tool built on top of the [Bleak](https://github.com/hbldh/bleak) BLE library. It operates in several phases:
### Architecture Overview
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ WhisperPair-PoC-Tool โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ CLI Layer โ
โ โโโ Argument parsing (--target-name, --scan-duration) โ
โ โโโ TargetPolicy construction โ
โ โโโ REPL initialization โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Discovery Engine โ
โ โโโ BLE scanning via Bleak โ
โ โโโ Advertisement parsing โ
โ โโโ Protocol detection (Fast Pair, FMDN, Swift Pair) โ
โ โโโ Device fingerprinting (Model ID, OUI lookup) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Check Engines โ
โ โโโ FastPairCheckEngine (passive advertisement analysis) โ
โ โโโ FastPairBypass (active CVE-2025-36911 testing) โ
โ โโโ FindHubCheckEngine (Account Key status detection) โ
โ โโโ RiskScorer (composite vulnerability assessment) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Connection Manager โ
โ โโโ GATT connect with MTU negotiation โ
โ โโโ Service/characteristic discovery โ
โ โโโ Read/Write/Notify operations โ
โ โโโ Error handling and retry logic โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Exploitation Modules โ
โ โโโ ring_device() - Trigger locator sound โ
โ โโโ set_account_key() - Write Account Key โ
โ โโโ Response parsing (BR/EDR address extraction) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
### Core Components
#### 1. Discovery Engine (`discovery.py`)
The scanner uses Bleak's detection callbacks to capture BLE advertisements:
```python
async def _detection_callback(
self, device: BLEDevice, advertisement_data: AdvertisementData
) -> None:
"""Process each detected BLE advertisement."""
discovered = DiscoveredDevice(
address=device.address,
name=device.name or advertisement_data.local_name,
rssi=advertisement_data.rssi,
advertisement=self._convert_advertisement(advertisement_data),
first_seen=datetime.now(UTC),
last_seen=datetime.now(UTC),
)
self._devices[device.address] = discovered
```
For each device, the tool extracts:
- Service UUIDs (detecting Fast Pair `0xFE2C`, FMDN `0xFD44`, etc.)
- Manufacturer data (Google `0x00E0`, Apple `0x004C`)
- Service data (parsed for Model ID and pairing state)
#### 2. Pairing Mode Inference (`fastpair.py`)
Pairing mode is determined by analyzing the device's advertisement:
```python
def _analyze_service_data(self, evidence: FastPairEvidence) -> None:
"""Analyze Fast Pair service data to infer pairing mode."""
data = evidence.service_data_bytes
# 3 bytes = Model ID only = Pairing Mode (discoverable)
if len(data) == 3:
evidence.inferred_pairing_mode = PairingModeState.IN_PAIRING_MODE
return
# 4+ bytes with version 0x00 = Not in pairing mode
if data[0] == 0x00:
akd_byte = data[1]
akd_type = akd_byte & 0x0F # Lower 4 bits
# Type 0x00 = Show UI, Type 0x02 = Hide UI
# Both indicate NOT in pairing mode
evidence.inferred_pairing_mode = PairingModeState.NOT_IN_PAIRING_MODE
```
This is crucial: if a device is determined to be **not** in pairing mode, and it still responds to the pairing request, it's vulnerable.
#### 3. Vulnerability Detection (`fastpair_attack.py`)
The core vulnerability test sends Key-Based Pairing requests and monitors for responses:
```python
async def check_vulnerability(self, device: DiscoveredDevice) -> BypassCheckResult:
"""Test if device responds to pairing requests when not in pairing mode."""
# Enable notifications to receive response
await self.connection_manager.start_notify(
KEY_BASED_PAIRING_CHAR,
self._notification_handler,
)
# Build and send request (multiple strategies)
for strategy in self.strategies:
request, flags = self._build_strategy_request(device.address, strategy)
await self.connection_manager.write_characteristic(
KEY_BASED_PAIRING_CHAR,
request,
)
# Wait for response
try:
await asyncio.wait_for(
self._response_received.wait(),
timeout=self.response_timeout,
)
# Response received = VULNERABLE
return BypassCheckResult(result=BypassResult.VULNERABLE, ...)
except asyncio.TimeoutError:
# No response = Device correctly ignored request
continue
return BypassCheckResult(result=BypassResult.NOT_VULNERABLE, ...)
```
The tool implements **multiple request strategies** because different devices respond to different flag combinations:
| Strategy | Flags | Description |
|----------|-------|-------------|
| `RAW_KBP` | `0x11` | INITIATE_BONDING \| EXTENDED_RESPONSE |
| `WITH_PUBLIC_KEY` | `0x11` | 80-byte request with ECDH public key |
| `RETROACTIVE` | `0x0A` | Bypasses some manufacturer checks |
| `EXTENDED` | `0x10` | For newer device firmware |
#### 4. Response Parsing
When a vulnerable device responds, the tool extracts the BR/EDR (Bluetooth Classic) address:
```python
def _parse_response(self, response_data: bytes) -> str | None:
"""Extract provider's BR/EDR address from response."""
# Strategy 1: Standard response (type 0x01)
if response_data[0] == 0x01:
return self._extract_address(response_data, offset=1)
# Strategy 2: Extended response (type 0x02)
if response_data[0] == 0x02:
addr_count = response_data[2]
return self._extract_address(response_data, offset=3)
# Strategy 3: Brute force pattern matching
for offset in range(len(response_data) - 5):
addr = self._extract_address(response_data, offset)
if self._is_valid_mac(addr):
return addr
```
This BR/EDR address could be used to initiate Bluetooth Classic pairing (though WhisperPair-PoC-Tool stops at detection).
---
## The Attack Surface
### What Makes Devices Vulnerable?
Research identified common implementation failures:
#### 1. Missing Pairing Mode Check
The most common issue: manufacturers simply don't implement the check:
```c
// VULNERABLE: No pairing mode check
void handle_kbp_write(uint8_t* data, size_t len) {
if (len >= 80 && has_public_key(data)) {
// Should check: if (!is_in_pairing_mode()) return;
process_pairing_request(data); // Processes regardless
}
}
```
#### 2. Unprotected Account Key Writes
The Account Key characteristic should require authentication:
```c
// VULNERABLE: No authentication required
void handle_account_key_write(uint8_t* key, size_t len) {
if (len == 16) {
store_account_key(key); // Accepts any key from anyone
}
}
// SECURE: Verify caller knows existing key
void handle_account_key_write_secure(uint8_t* encrypted_key, size_t len) {
if (!verify_encrypted_with_existing_key(encrypted_key)) {
return; // Reject unauthorized writes
}
store_account_key(decrypt(encrypted_key));
}
```
#### 3. Advertisement Leakage
Devices advertising Fast Pair service data when **not** in pairing mode reveal:
- That they support Fast Pair (attack surface identification)
- Account Key Filter (can be used for device fingerprinting)
- Potentially their Model ID (identifies exact device model)
---
## Detection Methodology
WhisperPair-PoC-Tool uses a layered detection approach:
### Layer 1: Passive Advertisement Analysis
**No connection required.** The tool analyzes what the device broadcasts:
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Passive Checks โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ Fast Pair service UUID present (0xFE2C) โ
โ โ FMDN service UUID present (0xFD44) โ
โ โ Pairing mode inferred from service data length โ
โ โ Model ID extracted (when in pairing mode) โ
โ โ Account Key Filter detected (when not in pairing mode) โ
โ โ Address type analysis (static vs. random) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Result: "Device advertising Fast Pair data while NOT in pairing mode"
โ Potential gating violation (needs active test to confirm)
```
### Layer 2: Active GATT Probing
**Requires connection.** The tool interacts with GATT services:
```
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Active Checks โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 1. Connect to device via BLE โ
โ 2. Discover Fast Pair service (0xFE2C) โ
โ 3. Locate Key-Based Pairing characteristic (0xFE2C1234) โ
โ 4. Enable notifications โ
โ 5. Write Key-Based Pairing request โ
โ 6. Wait for response (with timeout) โ
โ 7. Response received โ VULNERABLE โ
โ Timeout/Rejected โ NOT VULNERABLE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
```
### Layer 3: Risk Scoring
A composite risk score is computed:
| Signal | Score | Meaning |
|--------|-------|---------|
| Gating violation (passive) | +2 | Advertising FP when not in pairing mode |
| Bypass confirmed (active) | +2 | Responded to KBP when not in pairing mode |
| FMDN without Account Key | +2 | Trackable via Find My network |
| Static BLE address | +1 | Device is persistently trackable |
| Address rotation observed | -1 | Privacy-preserving behavior |
**Risk Levels:**
- **LOW** (โค0): No significant issues detected
- **MEDIUM** (1-2): Some concerning signals
- **HIGH** (โฅ3): Multiple vulnerabilities confirmed
---
## Exploitation Capabilities
WhisperPair-PoC-Tool includes controlled exploitation features to demonstrate impact:
### 1. Device Ringing (`ring` command)
Triggers the FMDN Beacon Actions characteristic to play the locator sound:
> REDACTED FOR RELEASE
**Impact:** Attacker can harass victim by repeatedly triggering sound, or use it to locate a device they want to steal.
### 2. Account Key Manipulation (`set account-key` command)
Writes a new Account Key to the device:
> REDACTED FOR RELEASE
**Impact:**
- Breaks victim's Find My Device integration
- Attacker can track device using their known key
- Only recoverable via factory reset
### What Is Not Implemented
WhisperPair-PoC-Tool intentionally stops short of full exploitation:
| Capability | Implemented | Reason |
|------------|-------------|--------|
| Vulnerability detection | โ Yes | Core purpose |
| BR/EDR address extraction | โ Yes | Evidence collection |
| Bluetooth Classic pairing | โ No | Requires platform-specific code |
| HFP audio hijacking | โ No | Beyond scope of BLE tool |
| Persistent implant | โ No | Malicious capability |
---
## Remediation Guidance
### For Device Manufacturers
1. **Implement the pairing mode check:**
```c
if (has_public_key(request) && !is_in_pairing_mode()) {
return; // Ignore request per spec
}
```
2. **Require authentication for Account Key writes:**
- Encrypt new key with existing key
- Verify before storing
3. **Minimize advertisement exposure:**
- Only advertise Fast Pair UUID when in pairing mode
- Use rotating addresses when possible
4. **Firmware update mechanism:**
- Push fixes to affected devices in the field
### For End Users
1. **Keep firmware updated** on Bluetooth accessories
2. **Factory reset** if you suspect compromise
3. **Be cautious** with devices that auto-pair without pressing a button
4. **Check Find My Device** settings periodically
---
## Intended Use
This tool is intended for:
- โ Security researchers evaluating accessory implementations
- โ QA engineers testing their company's products
- โ Device owners checking their own accessories
- โ **NOT** for unauthorized access to others' devices
---
## Conclusion
WhisperPair-PoC-Tool demonstrates that the "seamless" Fast Pair experience comes with security tradeoffs that many manufacturers fail to address. The pairing mode check is a single conditional that separates a secure device from a vulnerable one, yet it's frequently omitted.
Fast Pair's trust model assumes devices will enforce user intent. When they don't, attackers get silent pairing, tracking capabilities, and denial-of-service vectors against victims' devices.
This tool aims to help the ecosystem identify and remediate these issues, making Bluetooth accessories safer for everyone.
---
## References
- [WhisperPair Original Research](https://whisperpair.eu)
- [Google Fast Pair Specification](https://developers.google.com/nearby/fast-pair/specifications)
- [CVE-2025-36911](https://vulners.com/cve/CVE-2025-36911)
- [Find My Device Network Protocol](https://developers.google.com/nearby/find-my-device)
- [Bluetooth Core Specification](https://www.bluetooth.com/specifications/specs/core-specification/)
- [Bleak BLE Library](https://github.com/hbldh/bleak)
---
*WhisperPair-PoC-Tool is released for authorized security research only. No responsibility is assumed for misuse of this tool.*