ilusm.dev

ble

Bluetooth Low Energy - scan for devices, connect, read/write/notify GATT characteristics, enumerate services, inject packets, sniff channels, brute-force PINs, and replay captures.

Load with: use ble

What this module does

ble is a Bluetooth Low Energy toolkit for security research, hardware interfacing, and device automation. It scans for nearby BLE advertisements, connects to devices by MAC address, discovers and reads/writes GATT characteristics, subscribes to notifications, and can inject arbitrary packets.

The security-oriented functions cover packet injection, channel sniffing, PIN brute-forcing against a short list of common PINs, replay of captured packets, and key extraction.

All low-level operations delegate to host natives (__ble_*) - the ilusm layer provides the API surface, filtering, and higher-level logic.

Quick example

use ble

# Scan for 5 seconds and filter by name prefix
devices = blesc(5, "HeartRate")
prn(devices)

# Connect to the first device
h = bleco(devices[0].mac)

# Discover all GATT services and characteristics
profile = blega(h)

# Read a characteristic by UUID
val = blega(h, "00002a37-0000-1000-8000-00805f9b34fb")

# Subscribe to notifications
blega(h, "00002a37-0000-1000-8000-00805f9b34fb", \(data) prn(data))

# Disconnect
bledi(h)

Functions

Scanning

blesc(timeout_secs)

Scans for BLE advertisements for timeout_secs seconds using the host native __ble_scan. Returns a list of device objects.

blesc(timeout_secs, name_prefix)

Scans then filters the results to only devices whose name field starts with name_prefix. Devices without a name field are excluded.

Device connection

blein(mac_addr)

Gets device information for a MAC address via __ble_info.

bleco(mac_addr)

Connects to a BLE device by its MAC address via __ble_connect. Returns a connection handle used for all subsequent operations.

bledi(h)

Disconnects from the device associated with handle h via __ble_disconnect.

GATT operations

blega is overloaded - the number of arguments determines the operation.

blega(h)

Discovers all GATT services and characteristics for connection h. Returns the full GATT profile object.

blega(h, uuid)

Reads the characteristic with the given UUID from connection h.

blega(h, uuid, data)

Writes data to the characteristic with the given UUID on connection h.

blega(h, uuid, callback)

Subscribes to notifications on the characteristic with the given UUID. callback is called each time a notification arrives with the notification data.

Characteristic enumeration

blech(h)

Discovers the GATT profile and returns a flat list of all characteristics across all services. Each entry has {uuid, props, svc} - the characteristic UUID, its properties, and the UUID of the service it belongs to.

Common UUIDs

Convenience functions that return well-known Bluetooth GATT service and characteristic UUIDs.

bleuu()

Returns the Battery Service UUID: "0000180f-0000-1000-8000-00805f9b34fb".

bleuu()

Returns the Battery Level characteristic UUID: "00002a19-0000-1000-8000-00805f9b34fb".

bleuu()

Returns the Device Information Service UUID: "0000180a-0000-1000-8000-00805f9b34fb".

bleuu()

Returns the Heart Rate Service UUID: "0000180d-0000-1000-8000-00805f9b34fb".

Security research

blefu(h, uuid, iterations)

Fuzzes a GATT characteristic by writing iterations random 20-byte payloads to the given UUID. Captures any errors. Returns a list of {iter, error, data} results - useful for finding input validation bugs in firmware.

blein(mac_addr, data)

Injects a raw packet to a device via __ble_inject.

blesn(channel)

Starts sniffing BLE advertisements on the given channel number via __ble_sniff_start.

blesn()

Stops sniffing (__ble_sniff_stop) or retrieves captured packets (__ble_sniff_get).

blepa(mac_addr, pin)

Attempts to pair with a device using a specific PIN via __ble_pair.

blebr(mac_addr)

Brute-forces the pairing PIN against a short list of common PINs: ["000000", "123456", "111111", "0000", "1234"]. Returns {found: tru, pin} on success or {found: fls}.

blere(mac_addr, captured_data)

Replays captured BLE packet data to a device via packet injection.

bleke(mac_addr)

Attempts to extract bonding keys from a device via __ble_key_extract.

Notes

  • All low-level operations (__ble_scan, __ble_connect, __ble_gatt_*, etc.) require the host runtime to provide these native bindings - they will error if the runtime doesn't support BLE.
  • blega is overloaded on argument count: 1 arg = discover, 2 args = read, 3 args = write or notify (depending on whether the third arg is data or a function).
  • The fuzzer (blefu) uses cry.cryrn to generate random data, so cry must be available.
  • Requires trl and txt.