Bluetooth specification
In the Bluetooth specification, a Central device is defined as a device able to listen to any advertising device and to initiate a connection to any device that is advertised as connectable.
WHAD provides a tool called wble-central that acts as a Central device and allows:
In the Bluetooth specification, a Central device is defined as a device able to listen to any advertising device and to initiate a connection to any device that is advertised as connectable.
This tool also implements an interactive shell that is very useful to explore devices
without having to write some Python code. To run wble-central in
interactive mode, simply execute the following command:
(whad)$ wble-central -i hci0
The -i option passed to wble-central specifies a Bluetooth Low Energy hardware
device that will be used by this tool. This option is mandatory as WHAD CLI tools
are not designed to automatically search for a compatible interface to avoid messing
up with compatible devices possibly used by other applications. You should be greeted
with the following prompt:
wble-central>
The scan command starts an active scan and lists every advertising device based on the
received advertisements, with their names extracted from their advertising information:
wble-central> scan
RSSI Lvl Type BD Address Extra info
[-050 dBm] [RND] 6f:e5:8d:32:a2:eb name:"LE-Bose NC 700 HP"
[-080 dBm] [RND] 69:dc:e8:53:8c:a3
[-078 dBm] [RND] ef:3f:1a:37:c7:72
[-078 dBm] [RND] ed:af:38:86:1b:70
[-072 dBm] [PUB] ff:22:07:06:1e:e0 name:"iTAG "
[-066 dBm] [PUB] ff:22:07:05:0d:c3 name:"iTAG "
[-036 dBm] [PUB] ff:ff:30:03:70:72 name:"iTAG "
[-080 dBm] [RND] eb:b9:17:db:e4:cd
Each device discovered during a scan is kept in a cache with all its corresponding details
including its Bluetooth Device address, its address type and its name if provided. The
list of cached devices can be displayed at any time thanks to the devices command:
wble-scan> devices
RSSI Lvl Type BD Address Extra info
[-050 dBm] [RND] 6f:e5:8d:32:a2:eb name:"LE-Bose NC 700 HP"
[-080 dBm] [RND] 69:dc:e8:53:8c:a3
...
In the Bluetooth specification, a Bluetooth Device or BD address is a unique identifier for a specific device, that not only identifies a specific device at a specific time but also gives some additional information about the type of address. Some devices use resolvable addresses that have some specific bits set. These addresses are often mistakenly called MAC addresses as a reference to the well-known network Media Access Control addresses used by network interfaces as their unique identifiers, but the name “BD address” is preferred to avoid confusion.
This cache is used by wble-central to feed its auto-completion feature and make it easier
to select a device BD address thanks to this feature. Typing the first digits of
an address followed by a press on the [TAB] key will spawn a drop-down list containing all
the matching devices.
The connect command is used to initiate a connection to a given device based on its advertised
name or its BD address:
wble-central>connect ff:ff:30:03:70:72
Successfully connected to target ff:ff:30:03:70:72
wble-central|ff:ff:30:03:70:72>
Initiating a connection can take from a few milliseconds to many seconds depending on the target device advertising settings. If no connection can be established within 30 seconds, the operation fails and a timeout error is shown. If a connection has successfully been established, the prompt will reflect this state by indicating the BD address of the active connection.
Once a connection established, we get access to the device’s exposed GATT server. This server, like many web and other application servers, allows a client application to exchange data with it and to dynamically interact with the device’s firmware. This firmware reacts to data received from the client and may send back data in response, all of this relying on the Generic ATTribute Protocol and its specific data model.
A GATT server uses characteristics to exchange data between the embedded application and a GATT client connected to it, and one or more services to group a set of characteristics that are part of the same feature like those used to store the device’s generic information or expose a UART-over-BLE interface. The GATT server hosts its own attributes database, a hierarchical structure composed of one or more services with one or more characteristics defined in each of them, and a few more different structure used to provide more information about characteristics. Each element defined in this database is an attribute, referenced by a unique 16-bit handle, a type UUID and a dedicated buffer used to store the attribute’s value (bytes), as defined in the ATT protocol upon which is based GATT.
GATT simply describes a set of basic attributes and how they are defined, organized and cross-referenced. The following diagram shows the relations between a primary service, some characteristics and their values and descriptors.

A characteristic, a service and even a descriptor is an attribute, all exposed by a GATT server. Characteristics are the most interesting type of attributes as they define the key storage structure we use to exchange data with a Bluetooth Low Energy device. They are defined by:
We need to retrieve this information from a GATT server by following an enumeration procedure defined in the specification
and implemented in WHAD’s BLE stack. This enumeration procedure can be performed thanks to the profile command.
This command will enumerate every service, characteristic, value and descriptor attributes and populate them in a cached
GATT database used by wble-central. wble-central is then able to match a characteristic’s UUID with its 16-bit handle
and use this handle to exchange information through standard GATT procedures. Handles are used instead of UUIDs to
identify attributes because of their fixed size. Since handles are not quite easy to remember, this enumeration process
provides a better view of the hierarchy of services and characteristics, as well as what we are supposed to be allowed
to do with them.
Let’s use the profile command to start this enumeration on our target device:
wble-central|ff:ff:30:03:70:72>profile
Service Generic Access (0x1800)
Device Name (0x2A00) handle: 2, value handle: 3
| access rights: read, notify
Appearance (0x2A01) handle: 4, value handle: 5
| access rights: read
Service Battery (0x180F)
Battery Level (0x2A19) handle: 7, value handle: 8
| access rights: read, notify
Service Immediate Alert (0x1802)
Alert Level (0x2A06) handle: 10, value handle: 11
| access rights: write, write_without_response, notify
Service FFE0
FFE1 handle: 13, value handle: 14
| access rights: read, notify
wble-central performs this attribute enumeration procedure and displays the discovered hierarchy, detailing
each attribute depending on its type. This hierarchy of attributes defines the device’s GATT profile, and is
kept in cache by the tool to avoid performing this enumeration procedure each time we need to find the handle
of an attribute to read or write. Note that all characteristics have specific access rights set by the device,
and these define the type of operations a client GATT application can performed:
read access right can be read,write access right can be written into with a write request,write_without_response access right can be written into with a write command,notify access right can send notifications,indicate access right can send indications.Once the GATT profile retrieved, we can read some data exposed by the GATT server. The read
command implements the GATT read procedure to retrieve the value of a given characteristic, defined by either its
UUID or handle. The two read commands issued below target the same characteristic: the first one uses the characteristic’s
16-bit UUID while the second one the corresponding handle value.
wble-central|ff:ff:30:03:70:72>read 2a00
00000000: 69 54 41 47 20 20 20 20 20 20 20 20 20 20 20 20 iTAG
wble-central|ff:ff:30:03:70:72>read 3
00000000: 69 54 41 47 20 20 20 20 20 20 20 20 20 20 20 20 iTAG
When referring to a characteristic’s UUID in wble-central, like the Device Name characteristic showed above,
the provided UUID is 2a00 and not 0x2a00. The 0x prefix is deliberately omitted to avoid confusion between
a characteristic’s handle value (an integer) and its UUID. Trying to invoke the read command with 0x2a00 would
cause the tool to issue a read request on handle 0x2a00, which should not match any valid handle and lead to an
error or no answer at all, depending on how the BLE stack follows (or not) the specification.
WHAD is very permissive by design to allow security researchers to try actions that are not normally supposed to happen, like trying to read data from a characteristic’s value that is marked as write-only for instance:
wble-central|ff:ff:30:03:70:72>read 2a06
00000000: 00
In the example above, we received the value of the characteristic identified by UUID 0x2A06, that is the Alert Level
characteristic defined in the GATT profile as write-only:
...
Service Immediate Alert (0x1802)
Alert Level (0x2A06) handle: 10, value handle: 11
| access rights: write, write_without_response, notify
...
Well, that should not be possible based on the access rights defined for this characteristic but it looks like the device’s BLE stack behaves quite oddly on this target device and allows us to read the characteristic’s value.
The same way we read a characteristic’s value, we can update its value by using the write command. This command takes
a characteristic’s UUID or handle in parameter, and the new value to write into it. The value to write can be:
By default, the second argument passed to write is considered as a text string and is written into the characteristic’s
value. If the text string to write contains whitespaces, it can be put between quotes: "Some text". If the value to write
is not a text string, the second parameter must be ‘hex’ and be followed by one or more hexadecimal 8-bit values. This series
of 8-bit hexadecimal bytes will be written into the characteristic’s value.
We can trigger an alert for our target device by writing a byte of value 0x01 into the Alert Level characteristic’s value,
that will put the device in alert mode and forces it to emit a repetitive sound to drag attention:
wble-central|ff:ff:30:03:70:72>write 2a06 hex 01
Similarly to the GATT read procedure, WHAD is very permissive and allows to write into read-only characteristics:
wble-central|ff:ff:30:03:70:72>read 3
00000000: 69 54 41 47 20 20 20 20 20 20 20 20 20 20 20 20 iTAG
wble-central|ff:ff:30:03:70:72>write 3 "Ooops..."
wble-central|ff:ff:30:03:70:72>read 3
00000000: 4F 6F 6F 70 73 2E 2E 2E 20 20 20 20 20 20 20 20 Ooops...
It looks like read-only characteristics can also be written into (oops).
Some characteristics have a specific Client Configuration Characteristic descriptor defined in the device’s GATT
profile, and this descriptor is used to tell the device that the GATT client would like to be notified whenever the
characteristic’s value changes. wble-central has a dedicated command to subscribe to notifications, sub. It accepts
a single parameter specifying the target characteristic either by its UUID or handle:
wble-central|7f:f4:b9:df:a1:8a>sub c65b8f2f-aee2-4c89-b758-bc4892d6f2d8
Successfully subscribed to notification for characteristic c65b8f2f-aee2-4c89-b758-bc4892d6f2d8
Once subscribed for notifications, wble-central will show the characteristic’s updated value
whenever the device send notifications to our Central.
To close an active Bluetooth Low Energy connection, we simply use the disconnect command:
wble-central|7f:f4:b9:df:a1:8a>disconnect
Peripheral has just disconnected
wble-central>
This section details some tips and tricks that could be useful to get the most of wble-central, that we discovered
while developing this tool or even during our previous workshops held during many cybersecurity conferences.
WHAD’s command-line tools that provide an interactive shell provide specific commands to set, recall and destroy environment variables. These environment variables are different from the system’s, but can basically be used in a similar way.
If you plan to connect, disconnect and connect again to a target device, it could save you a lot of time to define a custom variable and assign the target BD address to it to later easily recall this value, as shown below:
wble-central>set TARGET ff:ff:30:03:70:72
wble-central>connect $TARGET
Successfully connected to target ff:ff:30:03:70:72
wble-central|ff:ff:30:03:70:72>disconnect
Peripheral has just disconnected
wble-central>info $TARGET
Device ff:ff:30:03:70:72
RSSI: -50 dBm
Address type: public
Raw advertising records
wble-central>connect $TARGET
Successfully connected to target ff:ff:30:03:70:72
The env command lists every defined environment variable:
wble-central|ff:ff:30:03:70:72>env
TARGET=ff:ff:30:03:70:72
To destroy the $TARGET variable, just execute the unset TARGET command.
Whenever a WHAD command-line tool provides an interactive shell, this shell keeps an history of every previous command typed for the active session. By pressing the up arrow key of your keyboard, it will successively recall the previous commands from the more recent to the oldest. Pressing the down arrow key allows to navigate back to more recent commands. Hitting enter will run the recalled command.