
Extraction de BDADDR Bluetooth en trois étapes, DoS et détournement sur les appareils Fast Pair ; primitives non corrigées hors du périmètre de CVE-2025-36911 (aucun Ubertooth requis)
Outil de recherche sur l'extraction BDADDR Bluetooth, le déni de service et le détournement
© 2026 @Ymsniper — Pour la recherche en sécurité autorisée uniquement.
Whisper Bully est un outil de recherche en sécurité Bluetooth en trois étapes qui cible les appareils annonçant Google Fast Pair (UUID de service fe2c). Il démontre deux primitives d'attaque non corrigées qui sont hors du périmètre du correctif firmware CVE-2025-36911 :
⚠️ Cet outil n'implémente PAS le protocole Whisper Pair (GATT Fast Pair). Il n'écrit jamais sur la caractéristique Key-Based Pairing (UUID 1236) ni sur la caractéristique Account Key (UUID 1238). La surface d'attaque décrite ici est distincte du correctif de vérification du mode d'appairage CVE-2025-36911 et n'est pas traitée par celui-ci.
https://github.com/user-attachments/assets/67f2bcb6-38ad-4ba0-80c5-36dbb54f3f11
Cause racine : Lorsqu'une connexion BLE est établie, la pile hôte BlueZ de Linux traite l'événement LL_CONNECTION_COMPLETE et résout l'adresse privée résoluble (RPA) de l'appareil vers son adresse d'identité permanente, en la mettant en cache dans la table des appareils BlueZ. Cela se produit au niveau de la couche liaison / HCI, avant toute interaction avec les services GATT. Aucun protocole Fast Pair n'est impliqué.
Ce que fait réellement le code :
BleakScanner) pour les appareils annonçant l'UUID de service Fast Pair fe2c — utilisé uniquement pour l'identification des cibles, aucune interaction protocolaireBleakClient.connect() — aucune écriture GATT d'aucune sorteNoInputNoOutput en préparation de l'étape 4wb.py)bluetoothctl pair <rpa_addr> — tentative d'appairage SMP Bluetooth standard, pas Fast Pairbluetoothctl pour la sortie Bonded: yes, qui peut contenir l'adresse liéebluetoothctl devices et compare avec la RPA initiale — toute entrée avec le même nom d'appareil mais une adresse différente est l'adresse d'identité permanente, divulguée par BlueZ à l'étape 2Pourquoi le correctif ne résout pas ce problème :
Le correctif firmware CVE-2025-36911 ajoute une vérification du mode d'appairage au gestionnaire de la caractéristique GATT Key-Based Pairing Fast Pair sur l'accessoire. Cet outil n'écrit jamais sur cette caractéristique. La fuite d'adresse d'identité se produit sur l'hôte Linux de l'attaquant via le cache d'appareils de BlueZ lui-même — entièrement en dehors du firmware de l'accessoire.
Points clés de comportement :
bluetoothctl pair échoue ou expireNoInputNoOutput signifie aucune interaction utilisateur des deux côtés pour Just WorksUne fois l'adresse permanente connue, exécutez facultativement un déni de service L2CAP soutenu à l'aide d'une version modifiée de l2flood.
Deux modes sont utilisés dans l'outil :
Option -R — mode EMP (flood de l'étape 2)
Reconnexion en rafales silencieuse de type « fire-and-forget ». Tous les threads synchronisent leurs cycles connect → burst → fermeture forcée afin que la cible reçoive des démontages ACL complets périodiques plutôt que des réorganisations de canaux L2CAP échelonnées qu'elle peut absorber. Utilise SO_LINGER {1,0} pour un démontage RST immédiat à chaque fermeture. Ne produit aucune sortie stdout pendant le fonctionnement normal — les erreurs de connexion sont envoyées vers stderr et imprimées périodiquement uniquement.
Mode normal (sonde de détournement de l'étape 3)
Utilisé sans -R pour vérifier si la cible répond encore. Ce mode a également été amélioré — il gère désormais les reconnexions automatiquement et émet no response from <addr>: id N lorsque la cible cesse de répondre, c'est ce que wb.py surveille pour déclencher le détournement.
Résultat : L'appareil cible devient non réactif aux tentatives de connexion normales pendant que le flood est actif. L'appareil récupère complètement lorsque l'attaque s'arrête — aucun dommage permanent.
Comportement multithread :
Cause racine : Le flood L2CAP soutenu provoque le crash ou la réinitialisation de la pile Bluetooth de l'appareil cible. Pendant la fenêtre de récupération — avant que le service GATT Fast Pair ne soit ré-enregistré et avant que le Security Manager ne soit complètement ré-initialisé — l'appareil accepte une liaison SMP Just Works standard de NoInputNoOutput sans exiger la poignée de main GATT Fast Pair qui conditionnerait normalement la liaison. La liaison résultante est persistante : elle survit aux réinitialisations de l'adaptateur BT et affiche Paired: yes / Bonded: yes dans bluetoothctl info.
Pourquoi cette découverte est distincte de CVE-2025-36911 :
Le correctif CVE-2025-36911 impose une vérification du mode d'appairage dans le gestionnaire de la caractéristique GATT Key-Based Pairing FP. L'étape 3 ne touche jamais à cette caractéristique. La liaison est établie au niveau de la couche SMP pendant une fenêtre où le serveur GATT FP ne s'est pas ré-initialisé, donc la barrière de sécurité Fast Pair n'est même jamais atteinte. Un appareil entièrement corrigé reste vulnérable à cette attaque car le correctif n'a aucune visibilité sur la couche SMP pendant la récupération de la pile.
Ce que fait réellement le code :
l2flood -c -1 -t 2) pour confirmer que l'appareil est non réactif — recherche no response from <addr>: id N dans la sortiebluetoothctl connect <permanent_addr> dans une boucle de tentativesNoInputNoOutput / NoInputNoOutput → modèle d'association Just Works → la liaison aboutitbluetoothctl connect renvoie le code de sortie 0 en cas de succèsProbabilité de succès selon l'état de l'appareil :
| État de l'appareil | Résultat attendu |
|---|---|
| Activement en flood / non réactif | Succès le plus élevé — pile dans un état dégradé pendant la récupération |
| En cours de récupération après le flood | Succès élevé — fenêtre temporaire de ré-initialisation du SM |
| Entièrement récupéré | Succès plus faible — sécurité normale rétablie |
| Éteint |
Il s'agit d'un outil de recherche sur le déni de service et l'accès non autorisé.
Utiliser cet outil sur des appareils que vous ne possédez pas ou sans autorisation écrite explicite est un crime fédéral passible d'emprisonnement et d'amendes en vertu du Computer Fraud and Abuse Act (18 U.S.C. § 1030) et des lois équivalentes dans d'autres juridictions.
Vous pouvez utiliser cet outil uniquement sur :
bluetoothctl et l'accès BLE brut)bluetoothctl / BlueZ installé et fonctionnell2flood avec support OpenMP — voir kovmir/l2floodUbuntu / Debian :
sudo apt update
sudo apt install -y python3 python3-pip libdbus-1-dev libglib2.0-dev bluez
Fedora / RHEL / CentOS :
sudo dnf install -y python3 python3-pip dbus-devel glib2-devel bluez
Arch Linux :
sudo pacman -S python python-pip dbus glib bluez
Alpine Linux :
apk add --no-cache python3 py3-pip dbus-dev glib-dev bluez bluez-openrc
openSUSE :
sudo zypper install -y python3 python3-pip dbus-1-devel glib2-devel bluez
Void Linux :
sudo xbps-install -S python3 python3-pip dbus-devel glib-devel bluez
git clone https://github.com/Ymsniper/Whisper_Bully.git
cd Whisper_Bully
pip3 install -r requirements.txt
# Required for Stage 2/3 only:
make
sudo make install
# Auto-detect and extract all nearby Fast Pair devices
sudo python3 wb.py
# 20 second scan, save results
sudo python3 wb.py -s 20 -o targets.json
# 30 second scan, custom output file
sudo python3 wb.py -s 30 -o extracted.json
Remarque : Si un appareil a été précédemment connecté ou appairé par cet outil ou manuellement, BlueZ connaît déjà son adresse d'identité. Supprimez-le d'abord pour que l'extraction se déroule proprement :
sudo bluetoothctl remove <address>
sudo python3 wb.py -s 20 -o targets.json
# At completion: "Run aggressive L2CAP test... (yes/no)" → yes
# Stage 1 + Stage 2 only
sudo python3 wb.py -s 20 -o targets.json --aggressive
# Stage 1 + Stage 2 + Stage 3
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack
# With duration and thread count
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120 -t 8
# Flood from extracted targets file for 120 seconds
sudo python3 aggressive_test.py -f targets.json -d 120 -t 4
# Flood a single known address for 60 seconds
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -d 60
# Flood forever (Ctrl+C to stop)
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -f
# Integrated — extract, flood, then hijack
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120
# Manual standalone hijack on known address
sudo python3 wb.py -H AA:BB:CC:DD:EE:FF
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120 -t 4
Déroulement de l'exécution :
targets.json# Terminal 1
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -i hci0 -d 120 -t 4 &
# Terminal 2
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -i hci1 -d 120 -t 4
Double la pression DoS et augmente la probabilité de succès du détournement pendant la fenêtre de récupération.
L'UUID de service Fast Pair FE2C est utilisé uniquement comme filtre de scan pour identifier les cibles candidates. Une fois qu'une connexion BLE est établie :
LL_CONNECTION_COMPLETE vers l'hôtebluetoothctl devices affiche alors à la fois la RPA d'origine et l'adresse d'identité nouvellement enregistrée — même nom d'appareil, adresse différenteL'appel bluetoothctl pair exécuté en parallèle peut réussir ou non — le BDADDR est généralement déjà dans la table au moment où la commande pair aboutit ou échoue.
l2flood -R)Ce l2flood modifié a deux modes selon l'étape visée :
Option -R — mode EMP (DoS uniquement, pas de détournement)
Utilisé lors de l'exécution de l'étape 2 de manière autonome sans passer à l'étape 3.
Reconnexion en rafales silencieuse de type « fire-and-forget » — tous les threads synchronisent leurs
cycles connect → burst → fermeture forcée pour garantir des démontages ACL complets
périodiques. Ne produit aucune sortie stdout pendant le fonctionnement normal.
Mode normal (DoS + sonde de détournement)
Utilisé lorsque l'étape 3 est visée. Le mode normal a été amélioré pour gérer
automatiquement les reconnexions et émet no response from <addr>: id N
lorsque la cible cesse de répondre — c'est le signal que wb.py surveille
pour déclencher la tentative de détournement.
La liaison résultante n'est pas une connexion transitoire — c'est une liaison SMP complète stockée par BlueZ :
bluetoothctl info <addr> affiche Paired: yes, Bonded: yes, Trusted: nobluetoothctl power off/on/var/lib/bluetooth/)bluetoothctlAucun appareil trouvé
bluetoothctl fonctionne : sudo bluetoothctl list-s 30Échec de la connexion BLE / de l'extraction
sudo bluetoothctl remove <addr>Le flood n'a aucun effet
-t 16Permission refusée
sudobluetooth ou exécutez en rootErreur d'import bleak
sudo apt install libdbus-1-dev libglib2.0-devsudo dnf install dbus-devel glib2-develsudo pacman -S dbus glibErreurs D-Bus
sudo systemctl start dbus && sudo systemctl start bluetoothMIT. Voir LICENSE pour plus de détails.
Cet outil est destiné aux tests de sécurité autorisés et à la recherche défensive uniquement. L'accès non autorisé aux appareils Bluetooth est illégal. Utilisez-le uniquement sur des appareils que vous possédez ou pour lesquels vous disposez d'une autorisation écrite explicite de test. L'auteur décline toute responsabilité en cas d'utilisation non autorisée ou illégale.
| Échec |
| CVE-2025-36911 (WhisperPair) | Cet outil |
|---|
| Protocole utilisé | GATT Fast Pair KBP (écriture UUID 1236) | Aucun — connexion BLE simple uniquement |
| Chemin de fuite BDADDR | Notification KBP chiffrée (adresse BR/EDR) | Résolution RPA BlueZ sur LL_CONNECTION_COMPLETE |
| Chemin de contournement d'authentification | Vérification du mode d'appairage FP manquante | SMP Just Works pendant la fenêtre de récupération de la pile BT |
| Corrigé par le correctif 36911 ? | Oui | Non |
| Fonctionne sur les appareils corrigés ? | Non | Oui |
| CWE | CWE-287 | CWE-200 (étape 1) + CWE-362/CWE-287 (étape 3) |
| Option | Description |
|---|
-s, --scan-time | Durée du scan BLE en secondes (défaut : 10) |
-o, --output | Enregistre les adresses extraites dans un fichier JSON |
--aggressive | Ignore les invites, exécute l'étape 2 immédiatement (requiert une autorisation écrite préalable) |
-H, --hijack | Tente le détournement de l'étape 3 après l'étape 2 (requiert --aggressive ou oui interactif) |
-d, --duration | Durée du flood en secondes (défaut : 60) ou f pour illimité |
-t, --threads | Threads de flood L2CAP parallèles (défaut : nombre de CPU) |
-i, --hci | Adaptateur HCI à utiliser (par ex. hci0, hci1) |