
Extracción de BDADDR Bluetooth en tres etapas, DoS y secuestro en dispositivos Fast Pair; primitivas no parcheadas fuera del alcance de CVE-2025-36911 (no se necesita Ubertooth)
Extracción de BDADDR Bluetooth, Denegación de Servicio y Herramienta de Investigación de Secuestro
© 2026 @Ymsniper — Solo para investigación de seguridad autorizada.
Whisper Bully es una herramienta de investigación de seguridad Bluetooth de tres etapas que apunta a dispositivos que anuncian Google Fast Pair (UUID de servicio fe2c). Demuestra dos primitivas de ataque sin parche que están fuera del alcance del parche de firmware CVE-2025-36911:
⚠️ Esta herramienta NO implementa el protocolo Whisper Pair (Fast Pair GATT). Nunca escribe en la característica de Emparejamiento Basado en Clave (UUID 1236) ni en la característica de Clave de Cuenta (UUID 1238). La superficie de ataque descrita aquí es independiente y no está cubierta por el parche de verificación de modo de emparejamiento CVE-2025-36911.
https://github.com/user-attachments/assets/67f2bcb6-38ad-4ba0-80c5-36dbb54f3f11
Causa raíz: Cuando se establece una conexión BLE, la pila de host BlueZ de Linux procesa el evento LL_CONNECTION_COMPLETE y resuelve la Dirección Privada Resoluble (RPA) del dispositivo a su dirección de Identidad permanente, almacenándola en caché en la tabla de dispositivos de BlueZ. Esto ocurre a nivel de Capa de Enlace / HCI, antes de cualquier interacción con el servicio GATT. No hay protocolo Fast Pair involucrado.
Lo que realmente hace el código:
BleakScanner) en busca de dispositivos que anuncien el UUID de servicio Fast Pair fe2c — usado solo para identificación del objetivo, sin interacción con el protocoloBleakClient.connect() — sin escrituras GATT de ningún tipoNoInputNoOutput en preparación para el Paso 4wb.py)bluetoothctl pair <rpa_addr> — intento de emparejamiento SMP Bluetooth estándar, no Fast Pairbluetoothctl en busca de la salida Bonded: yes, que puede contener la dirección vinculadabluetoothctl devices y compara con la RPA inicial — cualquier entrada con el mismo nombre de dispositivo pero una dirección diferente es la Dirección de Identidad permanente, filtrada por BlueZ en el paso 2Por qué el parche no soluciona esto:
La corrección de firmware CVE-2025-36911 agrega una verificación de modo de emparejamiento al manejador de la característica de Emparejamiento Basado en Clave GATT de Fast Pair en el accesorio. Esta herramienta nunca escribe en esa característica. La fuga de dirección de identidad ocurre en el host Linux del atacante a través del propio caché de dispositivos de BlueZ — completamente fuera del firmware del accesorio.
Notas clave de comportamiento:
bluetoothctl pair falla o expiraNoInputNoOutput significa que no hay interacción del usuario en ninguno de los lados para Just WorksUna vez que se conoce la dirección permanente, opcionalmente se ejecuta una denegación de servicio L2CAP sostenida utilizando una versión modificada de l2flood.
Se utilizan dos modos en la herramienta:
Bandera -R — Modo EMP (inundación de Etapa 2)
Ráfaga-reconexión silenciosa de "dispara y olvida". Todos los hilos sincronizan sus ciclos de conectar → ráfaga → cierre forzado para que el objetivo reciba desmontajes ACL completos periódicos en lugar de una reorganización escalonada de canales L2CAP que pueda absorber. Utiliza SO_LINGER {1,0} para un desmontaje RST inmediato en cada cierre. No produce salida estándar durante la operación normal — los errores de conexión se suprimen a stderr y solo se imprimen periódicamente.
Modo normal (sonda de secuestro de Etapa 3)
Se utiliza sin -R para sondear si el objetivo todavía está respondiendo. Este modo también fue mejorado — ahora maneja reconexiones automáticamente y genera no response from <addr>: id N cuando el objetivo deja de responder, que es lo que wb.py monitorea para activar el secuestro.
Resultado: El dispositivo objetivo se vuelve no receptivo a intentos de conexión normales mientras la inundación está activa. El dispositivo se recupera por completo cuando el ataque se detiene — sin daño permanente.
Comportamiento de múltiples hilos:
Causa raíz: La inundación L2CAP sostenida provoca que la pila Bluetooth del dispositivo objetivo se bloquee o reinicie. Durante la ventana de recuperación — antes de que el servicio GATT de Fast Pair se haya vuelto a registrar y antes de que el Administrador de Seguridad se haya reinicializado por completo — el dispositivo acepta un vínculo SMP Just Works estándar desde NoInputNoOutput sin requerir el intercambio GATT de Fast Pair que normalmente bloquearía el vínculo. El vínculo resultante es persistente: sobrevive a reinicios del adaptador BT y muestra Paired: yes / Bonded: yes en bluetoothctl info.
Por qué esto es un hallazgo separado de CVE-2025-36911:
El parche CVE-2025-36911 aplica una verificación de modo de emparejamiento en el manejador de la característica de Emparejamiento Basado en Clave GATT de FP. La Etapa 3 nunca toca esa característica. El vínculo se establece a nivel SMP durante una ventana donde el servidor GATT de FP no se ha reinicializado, por lo que la puerta de seguridad de Fast Pair nunca se alcanza. Un dispositivo completamente parcheado sigue siendo vulnerable a esto porque el parche no tiene visibilidad sobre la capa SMP durante la recuperación de la pila.
Lo que realmente hace el código:
l2flood -c -1 -t 2) para confirmar que el dispositivo no responde — busca no response from <addr>: id N en la salidabluetoothctl connect <permanent_addr> en un bucle de reintentosNoInputNoOutput / NoInputNoOutput → modelo de asociación Just Works → el vínculo se completabluetoothctl connect devuelve código de salida 0 en caso de éxitoProbabilidad de éxito según el estado del dispositivo:
| Estado del Dispositivo | Resultado Esperado |
|---|---|
| Activamente bajo inundación / sin respuesta | Mayor éxito — pila en estado degradado durante la recuperación |
| Recuperándose de la inundación | Alto éxito — ventana temporal de reinicialización de SM |
| Totalmente recuperado | Menor éxito — seguridad normal restaurada |
| Apagado |
Esta es una herramienta de investigación de denegación de servicio y acceso no autorizado.
Usar esta herramienta en dispositivos que no posea o sin autorización escrita explícita es un delito federal castigable con prisión y multas bajo la Ley de Fraude y Abuso Informático (18 U.S.C. § 1030) y estatutos equivalentes en otras jurisdicciones.
Solo puede usar esta herramienta en:
bluetoothctl y acceso BLE sin procesar)bluetoothctl / BlueZ instalado y funcionall2flood con soporte OpenMP — ver 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
# Requerido solo para Etapa 2/3:
make
sudo make install
# Detectar y extraer automáticamente todos los dispositivos Fast Pair cercanos
sudo python3 wb.py
# Escaneo de 20 segundos, guardar resultados
sudo python3 wb.py -s 20 -o targets.json
# Escaneo de 30 segundos, archivo de salida personalizado
sudo python3 wb.py -s 30 -o extracted.json
Nota: Si un dispositivo fue previamente conectado o emparejado por esta herramienta o manualmente, BlueZ ya conoce su dirección de identidad. Elimínelo primero para que la extracción se ejecute limpiamente:
sudo bluetoothctl remove <address>
sudo python3 wb.py -s 20 -o targets.json
# Al finalizar: "Run aggressive L2CAP test... (yes/no)" → yes
# Solo Etapa 1 + Etapa 2
sudo python3 wb.py -s 20 -o targets.json --aggressive
# Etapa 1 + Etapa 2 + Etapa 3
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack
# Con duración y número de hilos
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120 -t 8
# Inundar desde archivo de objetivos extraídos durante 120 segundos
sudo python3 aggressive_test.py -f targets.json -d 120 -t 4
# Inundar una dirección conocida única durante 60 segundos
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -d 60
# Inundar para siempre (Ctrl+C para detener)
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -f
# Integrado — extraer, inundar, luego secuestrar
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120
# Secuestro manual independiente en dirección conocida
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
Flujo de ejecución:
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
Duplica la presión DoS y aumenta la probabilidad de éxito del secuestro durante la ventana de recuperación.
El UUID de servicio FE2C de Fast Pair se usa solo como filtro de escaneo para identificar objetivos candidatos. Una vez que se establece una conexión BLE:
LL_CONNECTION_COMPLETE al hostbluetoothctl devices muestra tanto la RPA original como la dirección de identidad recién registrada — mismo nombre de dispositivo, diferente direcciónLa llamada bluetoothctl pair que se ejecuta concurrentemente puede tener éxito o no — el BDADDR típicamente ya está en la tabla para cuando el comando pair se completa o falla.
l2flood -R)Este l2flood modificado tiene dos modos dependiendo de la etapa prevista:
Bandera -R — Modo EMP (solo DoS, sin secuestro)
Se usa cuando se ejecuta la Etapa 2 de forma independiente sin proceder a la Etapa 3.
Ráfaga-reconexión silenciosa de "dispara y olvida" — todos los hilos sincronizan sus
ciclos de conectar → ráfaga → cierre forzado para garantizar desmontajes ACL completos
periódicos. No produce salida estándar durante la operación normal.
Modo normal (DoS + sonda de secuestro)
Se usa cuando se prevé la Etapa 3. El modo normal fue mejorado para manejar
reconexiones automáticamente y genera no response from <addr>: id N
cuando el objetivo deja de responder — esta es la señal que wb.py monitorea
para activar el intento de secuestro.
El vínculo resultante no es una conexión transitoria — es un vínculo SMP completo almacenado por BlueZ:
bluetoothctl info <addr> muestra Paired: yes, Bonded: yes, Trusted: nobluetoothctl power off/on/var/lib/bluetooth/)bluetoothctlNo se encontraron dispositivos
bluetoothctl esté funcionando: sudo bluetoothctl list-s 30Conexión BLE fallida / extracción falla
sudo bluetoothctl remove <addr>La inundación no tiene efecto
-t 16Permiso denegado
sudobluetooth o ejecute como rootError de importación bleak
sudo apt install libdbus-1-dev libglib2.0-devsudo dnf install dbus-devel glib2-develsudo pacman -S dbus glibErrores de D-Bus
sudo systemctl start dbus && sudo systemctl start bluetoothMIT. Consulte LICENSE para más detalles.
Esta herramienta es solo para pruebas de seguridad autorizadas e investigación defensiva. El acceso no autorizado a dispositivos Bluetooth es ilegal. Úsela solo en dispositivos que posea o para los cuales tenga permiso explícito por escrito para realizar pruebas. El autor no asume ninguna responsabilidad por el uso no autorizado o ilegal.
| Falla |
| CVE-2025-36911 (WhisperPair) | Esta Herramienta |
|---|
| Protocolo utilizado | Fast Pair GATT KBP (escritura UUID 1236) | Ninguno — solo conexión BLE simple |
| Ruta de fuga de BDADDR | Notificación KBP cifrada (dirección BR/EDR) | Resolución RPA de BlueZ en LL_CONNECTION_COMPLETE |
| Ruta de omisión de autenticación | Falta verificación de modo de emparejamiento FP | SMP Just Works durante ventana de recuperación de pila BT |
| ¿Parcheado por la corrección 36911? | Sí | No |
| ¿Funciona en dispositivos parcheados? | No | Sí |
| CWE | CWE-287 | CWE-200 (Etapa 1) + CWE-362/CWE-287 (Etapa 3) |
| Bandera | Descripción |
|---|
-s, --scan-time | Duración del escaneo BLE en segundos (predeterminado: 10) |
-o, --output | Guardar direcciones extraídas en archivo JSON |
--aggressive | Saltar prompts, ejecutar Etapa 2 inmediatamente (requiere autorización escrita previa) |
-H, --hijack | Intentar secuestro de Etapa 3 después de Etapa 2 (requiere --aggressive o sí interactivo) |
-d, --duration | Duración de la inundación en segundos (predeterminado: 60) o f para siempre |
-t, --threads | Hilos de inundación L2CAP paralelos (predeterminado: número de CPU) |
-i, --hci | Adaptador HCI a usar (ej. hci0, hci1) |