sudo bluetoothctl
scan on
# wait for the device to show up
scan off
quit
BDADDR=<target device address>
go install github.com/fracturelabs/iot-tools/ble-enum@latest
sudo ./ble-enum -scan
sudo ./ble-enum -b DE:AD:BE:EF:CA:FE
# Docker (no Apple Silicon)
docker run -it --privileged --net=host bettercap/bettercap
# Go
go install github.com/bettercap/bettercap@latest
# inside bettercap
>> ble.recon on
>> ble.enum <BDADDR>
>> ble.recon off
>> quit
# List characterists
gatttool -b $BDADDR --characteristics
# Read a handle
gatttool -b $BDADDR --char-read -a $handle | \
awk -F':' '{print $2}' | tr -d ' ' | xxd -r -p; printf '\n'
# Interactive mode (single persistent connection — gentler on devices)
gatttool -b $BDADDR -I
connect
primary # List all primary services
characteristics # List all characteristics with properties
char-desc # List all descriptors (shows full handle map)
char-read-hnd 0x000B # Read by handle (use handles from char-desc)
char-write-req 0x0025 01 # Write with response (ATT Write Request)
char-write-cmd 0x0025 01 # Write without response (ATT Write Command)
disconnect
quit
# If the device uses a random BLE address (connection fails without this)
gatttool -b $BDADDR -t random --characteristics
# Read all handles in a range (useful for finding hidden characteristics)
for h in $(seq 1 80); do
gatttool -b $BDADDR --char-read -a $(printf '0x%04X' $h) 2>/dev/null && echo " <- handle $h"
done
# Discover service UUIDs
gatttool -b $BDADDR --primary
# Read a specific UUID instead of a handle
gatttool -b $BDADDR --char-read -u 00002a00-0000-1000-8000-00805f9b34fb
# Listen for notifications (subscribe to a characteristic)
gatttool -b $BDADDR --listen --char-write-req -a 0x000F -n 0100
# Decode common characteristic values
# Device Name (UUID 0x2A00)
gatttool -b $BDADDR --char-read -u 00002a00-0000-1000-8000-00805f9b34fb | \
awk -F':' '{print $2}' | tr -d ' ' | xxd -r -p; printf '\n'
# Manufacturer Name (UUID 0x2A29)
gatttool -b $BDADDR --char-read -u 00002a29-0000-1000-8000-00805f9b34fb | \
awk -F':' '{print $2}' | tr -d ' ' | xxd -r -p; printf '\n'