detecting-bluetooth-low-energy-attacks について
IoTなどのBLEデバイスを対象とする、許可を得たセキュリティ評価向けスキルです。デバイスとGATTの列挙、パケット分析を組み合わせ、ペアリングの弱点、リプレイ攻撃、MITMの兆候を調べます。
主な機能
- 01BLEデバイスとGATTの列挙
- 02パケットキャプチャとWireshark分析
- 03レガシーペアリング暗号の分析
- 04リプレイ攻撃への脆弱性テスト
- 05MITMとなりすましの監視
- 06BLE脅威の継続的な監視
活用シーン
- 01IoTデバイスやスマートロックのBLEセキュリティ評価
- 02ペアリング悪用やMITMのパケット分析
- 03無線環境でのリプレイとなりすましの監視
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill detecting-bluetooth-low-energy-attacksインストール後、Claude Code で/detecting-bluetooth-low-energy-attacksを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
BLE攻撃の検出
免責事項
このスキルは、認可されたセキュリティテスト、ペネトレーションテストの業務、CTFコンペティション、教育目的に限定して使用することを意図しています。認可なしにBluetooth通信を傍受、盗聴、または操作することは、連邦盗聴法および地域の規制に違反するおそれがあります。無線セキュリティ評価を実施する前には、必ず事前に書面による明示的な許可を取得してください。
使用するタイミング
このスキルは、次の場合に使用します。
- IoTデバイス、医療機器、スマートロックに対して、認可されたBLEセキュリティ評価を実施する場合
- BLEベースのリプレイ攻撃、なりすまし、または不正な列挙を監視するために無線環境を監視する場合
- BLEパケットキャプチャを分析し、Man-in-the-Middle攻撃またはペアリングの悪用を検出する場合
- BLEペリフェラルで安全でない読み取り/書き込み権限を特定するため、GATTサービスと特性を列挙する場合
- BLEの暗号化強度を評価し、解読可能なペアリング交換をテストする場合
- 無線セキュリティ監視のためのBLE侵入検知機能を構築する場合
侵入に対する明示的な認可なしにBLE通信を傍受するために使用しないでください。 無線監視が禁止されている環境では、BLEスキャンツールを展開しないでください。
前提条件
- パッシブBLE盗聴用のUbertooth Oneハードウェア、またはnRF Snifferファームウェアを搭載したNordic nRF52840 USBドングル
- pip を備えた Python 3.10 以上
- bleakライブラリ:
pip install bleak(クロスプラットフォームのBLE GATTクライアント) - パケット分析用のBLEディセクタプラグインを備えたWireshark
- BLE暗号化分析用のcrackleツール: github.com/mikeryan/crackle からソースをビルド
- ubertooth-btle CLIツール:
apt install ubertooth(Linux)またはソースからのビルド - bleakベースのスキャン用に、ホストシステムにBluetooth 4.0以上のアダプタ
- Ubertooth/nRFスニファーの完全なサポートには、Linuxを推奨
ワークフロー
ステップ1: BLE環境の検出とデバイススキャン
環境をスキャンして、BLEデバイスとそのアドバタイズデータを特定します。
# Scan for BLE devices using bleak (cross-platform)
python -c "
import asyncio
from bleak import BleakScanner
async def scan():
devices = await BleakScanner.discover(timeout=10.0)
for d in devices:
print(f'{d.address} | RSSI: {d.rssi} | Name: {d.name or \"Unknown\"}')
for uuid in d.metadata.get('uuids', []):
print(f' Service: {uuid}')
asyncio.run(scan())
"
# Passive BLE sniffing with Ubertooth One (promiscuous mode)
ubertooth-btle -p -r capture.pcapng
# Follow a specific BLE connection
ubertooth-btle -f -t AA:BB:CC:DD:EE:FF -r connection.pcapng
# Use nRF Sniffer with Wireshark (via extcap interface)
wireshark -i nRF_Sniffer -k
ステップ2: GATTサービスと特性の列挙
対象のBLEペリフェラルに接続し、そのGATTプロファイルを列挙します。
# Enumerate all services, characteristics, and descriptors
python -c "
import asyncio
from bleak import BleakClient
async def enum_gatt(address):
async with BleakClient(address) as client:
print(f'Connected: {client.is_connected}')
for service in client.services:
print(f'Service: {service.uuid} - {service.description}')
for char in service.characteristics:
props = ','.join(char.properties)
print(f' Char: {char.uuid} | Props: {props}')
for desc in char.descriptors:
val = await client.read_gatt_descriptor(desc.handle)
print(f' Desc: {desc.uuid} = {val}')
asyncio.run(enum_gatt('AA:BB:CC:DD:EE:FF'))
"
GATT列挙時のセキュリティ上重要な検出事項:
- 認証なしの
write-without-responseまたはwriteを持つ特性 - デバイス設定、認証情報、またはファームウェアバージョンを公開している読み取り可能な特性
- 通知用特性におけるClient Characteristic Configuration Descriptor (CCCD) 保護の欠如
ステップ3: BLEパケットキャプチャと分析
オフライン分析のためにBLEトラフィックをキャプチャします。
# Capture with Ubertooth in PcapNG format (recommended)
ubertooth-btle -f -r capture.pcapng
# Capture in PCAP/PPI format for crackle compatibility
ubertooth-btle -f -c capture_ppi.pcap
# Analyze capture in Wireshark
wireshark capture.pcapng
# Apply display filter: btle
# Filter connection requests: btle.advertising_header.pdu_type == 0x05
# Filter data packets: btle.data_header
# Extract pairing information with tshark
tshark -r capture.pcapng -Y "btle.control_opcode == 0x01" -T fields \
-e btle.master_bd_addr -e btle.slave_bd_addr
ステップ4: crackleによるBLE暗号化分析
キャプチャしたペアリング交換を分析し、暗号化強度をテストします。
# Crack BLE Legacy Pairing (Just Works / passkey)
crackle -i capture_ppi.pcap -o decrypted.pcap
# Crack with known Temporary Key (TK)
crackle -i capture_ppi.pcap -o decrypted.pcap -l 000000
# Analyze decrypted traffic
wireshark decrypted.pcap
BLEレガシーペアリングのJust Worksモードでは、TKがすべてゼロに設定されるため、容易に解読可能です。パスキー入力では6桁のPIN(000000〜999999)を使用し、1秒未満でブルートフォース攻撃が可能です。受動的な盗聴に対して十分な保護を提供するのは、BLEセキュアコネクション(ECDHを用いたLEセキュアコネクション)のみです。
ステップ5: リプレイ攻撃の検出とテスト
BLEリプレイ攻撃への脆弱性を監視し、テストします。
# Capture characteristic write operations
# Record the raw bytes written to a target characteristic
# Then replay the exact same bytes to test if the device accepts stale commands
python -c "
import asyncio
from bleak import BleakClient
TARGET = 'AA:BB:CC:DD:EE:FF'
CHAR_UUID = '0000fff1-0000-1000-8000-00805f9b34fb'
async def replay_test():
async with BleakClient(TARGET) as client:
# Step 1: Read current state
val = await client.read_gatt_char(CHAR_UUID)
print(f'Current value: {val.hex()}')
# Step 2: Write a command (captured from previous session)
captured_command = bytes.fromhex('0102030405')
await client.write_gatt_char(CHAR_UUID, captured_command)
print('Replayed captured command')
# Step 3: Verify if command was accepted
new_val = await client.read_gatt_char(CHAR_UUID)
print(f'New value: {new_val.hex()}')
if new_val != val:
print('VULNERABLE: Device accepted replayed command')
asyncio.run(replay_test())
"
リプレイ脆弱性の指標:
- デバイスが、以前にキャプチャされた書き込みコマンドを鮮度検証なしに受け入れる
- プロトコルにシーケンス番号、タイムスタンプ、またはチャレンジレスポンスの仕組みがない
- リプレイされたコマンドに応じてデバイスの状態が変化する
ステップ6: Man-in-the-Middle攻撃の検出
異常な動作を監視して、BLE MITM攻撃を検出します。
# Monitor for BLE address spoofing (device impersonation)
# Compare advertising data fingerprints over time
# Monitor for unexpected connection parameter changes
tshark -r capture.pcapng -Y "btle.control_opcode == 0x00" -T fields \
-e btle.control.interval.min -e btle.control.interval.max
# Detect GATTacker/BTLEjuice MITM patterns:
# - Cloned advertising data with different BD_ADDR
# - Rapid connect/disconnect cycles on the same channel
# - Duplicate service UUIDs from different addresses
# Monitor for suspicious pairing requests
tshark -r capture.pcapng -Y "btl2cap.cid == 0x0006" -T fields \
-e btsmp.opcode -e btsmp.io_capability -e btsmp.auth_req
ステップ7: 継続的なBLEセキュリティ監視
脅威検出のために、継続的なBLE監視を展開します。
# Run the agent in monitoring mode
python agent.py --mode monitor --duration 3600 --output ble_alerts.json
# Combine with Ubertooth for passive monitoring
ubertooth-btle -p -r - | python agent.py --mode analyze --pcap-stdin
# Alert on specific threat indicators
python agent.py --mode monitor --alert-on replay,spoofing,weak-pairing
主要な概念
| 用語 | 定義 |
|---|---|
| BLE (Bluetooth Low Energy) | IoT デバイス向けに最適化された低消費電力の無線プロトコル(Bluetooth 4.0 以降)。2.4 GHz 帯で動作し、40 チャネル(アドバタイジング 3、データ 37)を使用 |
| GATT (Generic Attribute Profile) | デバイスの機能をサービス、キャラクタリスティック、ディスクリプタに整理する BLE のデータモデル。BLE デバイスのデータの読み取りと書き込みを行う主要なインターフェース |
| Ubertooth One | すべての BLE チャネルでパッシブな BLE および Bluetooth Classic のスニッフィングが可能な、オープンソースの 2.4 GHz 無線開発プラットフォーム |
| nRF Sniffer | nRF52840 USB ドングル向けの Nordic Semiconductor 製ファームウェア。extcap を介した Wireshark 連携により BLE パケットキャプチャを可能にする |
| リプレイ攻撃 | 以前にキャプチャした BLE コマンドを、暗号化キーを知らなくてもデバイスに再送信し、不正な動作を引き起こす攻撃 |
| Just Works ペアリング | TK=0 を使用し、ユーザーによる確認を行わない BLE Legacy Pairing の方式。パッシブな盗聴や MITM 攻撃に対する保護はまったくない |
| LE Secure Connections | P-256 曲線を用いた ECDH 鍵交換を行う BLE 4.2 以降のペアリング方式。パッシブな盗聴に対する保護を提供し、Legacy Pairing より推奨される |
| Crackle | BLE Legacy Pairing の弱点を突いて Long Term Key (LTK) を復元し、キャプチャした BLE トラフィックを復号するオープンソースツール |
| GATTacker | ペリフェラルの GATT プロファイルとアドバタイジングデータを複製し、実際のデバイスと被害者のセントラルの間でトラフィックを中継する BLE MITM フレームワーク |
ツールとシステム
- Ubertooth One + ubertooth-btle: pcapng/pcap 形式でのパッシブな BLE パケットキャプチャ用のハードウェアスニッファおよびコマンドラインツール
- nRF52840 USB Dongle + nRF Sniffer: ネイティブな Wireshark extcap 連携を備えた Nordic Semiconductor 製 BLE スニッファ
- bleak: デバイスのスキャン、接続、キャラクタリスティックの読み取りと書き込みを行う、クロスプラットフォーム対応の Python asyncio 製 BLE GATT クライアントライブラリ
- crackle: キャプチャしたペアリングのやり取りから LTK を復元する、BLE Legacy Pairing の暗号解読ツール
- Wireshark: キャプチャしたトラフィックをパケット単位で検査するための、BLE/BTLE ディセクタを備えたネットワークプロトコルアナライザ
- GATTacker / BTLEjuice: セントラルとペリフェラルの間の BLE トラフィックを傍受・改変するための BLE Man-in-the-Middle フレームワーク
- tshark: スクリプトによる BLE パケットの抽出とフィールド解析のためのコマンドライン版 Wireshark
よくある落とし穴
- Ubertooth のチャネルホッピングの制限: Ubertooth は一度に 1 つの接続しか追跡できません。複数の BLE 接続がアクティブな場合は、
-tを使用して特定のデバイスアドレスを指定し、そのデータチャネルを追跡する必要があります。 - BLE 5.0 の拡張アドバタイジング: セカンダリチャネルで BLE 5.0 の拡張アドバタイジングを使用するデバイスは、古い Ubertooth ファームウェアではキャプチャできない場合があります。最新のファームウェアに更新してください。
- bleak のプラットフォーム間の違い: BLE のスキャン動作は OS のバックエンドによって異なります。Linux ではスキャンに root 権限または適切なケーパビリティが必要です。macOS ではデバイスアドレスはランダム化された UUID になります。
- crackle には Legacy Pairing が必要: crackle が有効なのは BLE Legacy Pairing(Bluetooth 4.0/4.1)に対してのみです。LE Secure Connections(4.2 以降)は ECDH を使用するため、この手法では解読できません。
- BLE アドレスのランダム化: 最近の多くの BLE デバイスは、定期的にローテーションするランダムなリゾルバブルプライベートアドレス(RPA)を使用するため、デバイスの追跡や接続の追跡がより困難になります。
- キャプチャ形式が重要: crackle との互換性のためには PPI ヘッダ付きの PCAP(
-cフラグ)を使用してください。PcapNG(-rフラグ)は Wireshark での解析には推奨されますが、crackle ではサポートされていません。
出力形式
## Finding: BLE Smart Lock Accepts Replayed Unlock Commands
**ID**: BLE-001
**Severity**: Critical (CVSS 9.3)
**Device**: SmartLock-Pro (AA:BB:CC:DD:EE:FF)
**Attack Type**: Replay Attack
**Description**:
The BLE smart lock accepts previously captured GATT write commands
on characteristic 0000fff1-0000-1000-8000-00805f9b34fb without
any freshness validation. An attacker who captures a single unlock
command can replay it indefinitely to unlock the device.
**Proof of Concept**:
1. Capture unlock command: ubertooth-btle -f -t AA:BB:CC:DD:EE:FF -r capture.pcap
2. Extract write payload from characteristic fff1: 01 42 A3 7F 00
3. Replay via bleak: await client.write_gatt_char(CHAR_UUID, bytes.fromhex('0142a37f00'))
4. Lock disengages without re-authentication
**Impact**:
Any attacker within BLE range (~100m with directional antenna) who
captures a single unlock event can replay it to gain physical access
to the protected area indefinitely.
**Remediation**:
Implement challenge-response authentication with per-session nonces.
Each command should include a server-generated challenge that expires
after use. Use LE Secure Connections for pairing to prevent passive
capture of the pairing exchange.