
Uno strumento di ricerca sulla sicurezza che identifica e dimostra la vulnerabilità CVE-2025-36911: Fast Pair Pairing Mode Bypass
Un'analisi approfondita di CVE-2025-36911 e delle lacune di sicurezza nell'ecosistema Fast Pair di Google
Google Fast Pair è stato progettato per rendere l'associazione Bluetooth senza attriti: tocca una notifica e sei connesso. Ma cosa succede quando quell'esperienza senza attriti diventa un rischio per la sicurezza? WhisperPair-PoC-Tool è uno strumento di ricerca sulla sicurezza che espone due classi critiche di vulnerabilità che colpiscono milioni di accessori Bluetooth: il bypass non autorizzato dell'associazione e lo sfruttamento del tracciamento della rete Find My Device.
Questo articolo descrive i dettagli tecnici interni di WhisperPair-PoC-Tool, le debolezze del protocollo che sfrutta e cosa questo significa per l'ecosistema degli accessori Bluetooth.
La specifica Google Fast Pair afferma esplicitamente:
"Se il campo opzionale Public Key è presente: se il dispositivo non è in modalità di associazione, ignora la scrittura ed esci."
Questo è il controllo di sicurezza critico. I dispositivi dovrebbero solo rispondere alle richieste di Key-Based Pairing quando l'utente ha messo esplicitamente il dispositivo in modalità di associazione (in genere tenendo premuto un pulsante). Questo garantisce l'intenzione dell'utente, così non puoi associare gli auricolari di qualcuno mentre li sta indossando.
Il Problema: Molti produttori saltano del tutto questo controllo. Elaborano le richieste di associazione indipendentemente dallo stato della modalità di associazione, consentendo:
La rete Find My Device Network (FMDN) di Google consente di tracciare gli accessori Bluetooth tramite la rete di dispositivi Android basata sul contributo collettivo. Ciò richiede una Account Key, una chiave simmetrica di 16 byte che collega il dispositivo a un account Google.
Il Problema: La characteristic Account Key spesso accetta scritture senza autenticazione:
Prima di addentrarci nell'exploitation, comprendiamo il flusso Fast Pair legittimo:
┌─────────────────────────────────────────────────────────────┐
│ BLE Advertisement │
├─────────────────────────────────────────────────────────────┤
│ Service UUID: 0xFE2C (Fast Pair) │
│ Service Data: │
│ [Pairing Mode] → 3 bytes: Model ID only │
│ [Not Pairing] → 4+ bytes: 0x00 + Account Key Filter │
└─────────────────────────────────────────────────────────────┘
Il formato dell'advertisement rivela lo stato di associazione:
Seeker (Phone) Provider (Accessory)
│ │
│───── GATT Connect ──────────────────────────>│
│ │
│───── Discover Services ─────────────────────>│
│<──── Service: 0xFE2C ────────────────────────│
│ │
│───── Enable Notifications (0xFE2C1234) ─────>│
│ │
│───── 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 │ │
│ └────────────────────────────────────┘ │
│ │
│<──── Notification: Encrypted Response ───────│
│ [Provider's BR/EDR Address] │
│ │
│═══════ Bluetooth Classic Pairing ═══════════>│
La vulnerabilità si verifica quando i dispositivi saltano del tutto il riquadro "SECURITY CHECK".
WhisperPair-PoC-Tool è uno strumento di ricerca sulla sicurezza basato su Python, costruito sulla libreria BLE Bleak. Si articola in diverse fasi:
┌────────────────────────────────────────────────────────────────┐
│ 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) │
└────────────────────────────────────────────────────────────────┘
discovery.py)Lo scanner utilizza i callback di rilevamento di Bleak per catturare gli advertisement BLE:
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
Per ogni dispositivo, lo strumento estrae:
0xFE2C, FMDN 0xFD44, ecc.)0x00E0, Apple 0x004C)fastpair.py)La modalità di associazione viene determinata analizzando l'advertisement del dispositivo:
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
Questo è cruciale: se un dispositivo risulta non essere in modalità di associazione e risponde comunque alla richiesta di associazione, è vulnerabile.
fastpair_attack.py)Il test di vulnerabilità principale invia richieste di Key-Based Pairing e monitora le risposte:
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, ...)
Lo strumento implementa molteplici strategie di richiesta perché dispositivi diversi rispondono a diverse combinazioni di flag:
Quando un dispositivo vulnerabile risponde, lo strumento estrae l'indirizzo BR/EDR (Bluetooth Classic):
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
Questo indirizzo BR/EDR potrebbe essere usato per avviare l'associazione Bluetooth Classic (anche se WhisperPair-PoC-Tool si ferma al rilevamento).
La ricerca ha identificato errori di implementazione comuni:
Il problema più comune: i produttori semplicemente non implementano il controllo:
// 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
}
}
La characteristic Account Key dovrebbe richiedere l'autenticazione:
// 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));
}
I dispositivi che pubblicizzano dati del servizio Fast Pair quando non sono in modalità di associazione rivelano:
WhisperPair-PoC-Tool utilizza un approccio di rilevamento a livelli:
Nessuna connessione richiesta. Lo strumento analizza ciò che il dispositivo trasmette:
┌─────────────────────────────────────────────────────────────┐
│ 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)
Risultato: "Il dispositivo pubblicizza dati Fast Pair mentre NON è in modalità di associazione" → Potenziale violazione del gating (richiede un test attivo per conferma)
Richiede una connessione. Lo strumento interagisce con i servizi GATT:
┌─────────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────────┘
Viene calcolato un punteggio di rischio composito:
Livelli di Rischio:
WhisperPair-PoC-Tool include funzionalità di exploitation controllata per dimostrare l'impatto:
ring)Attiva la characteristic FMDN Beacon Actions per riprodurre il suono di localizzazione:
OSCURATO PER LA PUBBLICAZIONE
Impatto: L'attaccante può molestare la vittima attivando ripetutamente il suono, oppure usarlo per localizzare un dispositivo che vuole rubare.
set account-key)Scrive una nuova Account Key sul dispositivo:
OSCURATO PER LA PUBBLICAZIONE
Impatto:
WhisperPair-PoC-Tool si ferma intenzionalmente prima della piena exploitation:
if (has_public_key(request) && !is_in_pairing_mode()) {
return; // Ignore request per spec
}
Richiedere l'autenticazione per le scritture della Account Key:
Minimizzare l'esposizione degli advertisement:
Meccanismo di aggiornamento del firmware:
Questo strumento è destinato a:
WhisperPair-PoC-Tool dimostra che l'esperienza Fast Pair "senza attriti" comporta compromessi di sicurezza che molti produttori non riescono ad affrontare. Il controllo della modalità di associazione è una singola condizione che separa un dispositivo sicuro da uno vulnerabile, eppure viene spesso omesso.
Il modello di fiducia di Fast Pair presuppone che i dispositivi applichino l'intenzione dell'utente. Quando non lo fanno, gli attaccanti ottengono associazione silenziosa, capacità di tracciamento e vettori di denial-of-service contro i dispositivi delle vittime.
Questo strumento mira ad aiutare l'ecosistema a identificare e correggere questi problemi, rendendo gli accessori Bluetooth più sicuri per tutti.
WhisperPair-PoC-Tool è rilasciato esclusivamente per ricerca di sicurezza autorizzata. Non si assume alcuna responsabilità per l'uso improprio di questo strumento.
| Strategia | Flag | Descrizione |
|---|
RAW_KBP | 0x11 | INITIATE_BONDING | EXTENDED_RESPONSE |
WITH_PUBLIC_KEY | 0x11 | Richiesta da 80 byte con chiave pubblica ECDH |
RETROACTIVE | 0x0A | Elude alcuni controlli dei produttori |
EXTENDED | 0x10 | Per firmware di dispositivi più recenti |
| Segnale | Punteggio | Significato |
|---|
| Violazione del gating (passiva) | +2 | Pubblicizza FP quando non è in modalità di associazione |
| Bypass confermato (attivo) | +2 | Ha risposto a KBP quando non era in modalità di associazione |
| FMDN senza Account Key | +2 | Tracciabile tramite la rete Find My |
| Indirizzo BLE statico | +1 | Il dispositivo è tracciabile in modo persistente |
| Rotazione dell'indirizzo osservata | -1 | Comportamento che preserva la privacy |
| Capacità | Implementata | Motivazione |
|---|
| Rilevamento delle vulnerabilità | ✅ Sì | Scopo principale |
| Estrazione dell'indirizzo BR/EDR | ✅ Sì | Raccolta di prove |
| Associazione Bluetooth Classic | ❌ No | Richiede codice specifico per piattaforma |
| Dirottamento audio HFP | ❌ No | Oltre lo scopo dello strumento BLE |
| Impianto persistente | ❌ No | Capacità dannosa |