Bluetooth traffic analysis

Last update: June 29th, 2022

Introduction

Overview

In this part, we introduce the Bluetooth Low Energy protocol and how to use Wireshark and BlueZ to monitor packets.

Bluetooth Low Energy stack

A typical Bluetooth Low Energy stack is splitted in two main parts:

  • Host: handles the upper layers - Logical Link Control and Adaptation Protocol (L2CAP, shared with Bluetooth Classic), Attribute Protocol (ATT), Generic Attribute Protocol (GATT), Security Manager (SMP) and Generic Access Profile (GAP),
  • Controller: handles the lower layers - Link Layer (LL) and Physical Layer.
These two components may be implemented on different chips, and communicate together using a serial protocol standardized in the Bluetooth specification and called Host Controller Interface (HCI). In our case, the Bluetooth adapter implements the Controller while the Linux Bluetooth stack (named BlueZ) implements the Host part.

During a Bluetooth Low Energy operation, the Host transmits HCI commands to the Controller and receives HCI events from it. Several solutions exists to monitor these commands and events, allowing to facilitate the analysis of the protocol.

Monitoring HCI traffic

The first solution is to use the utility named btmon, provided by BlueZ stack. To test it, you can run in a first terminal the following command:


cyberinsophia@vm:~$ sudo btmon -i hci0
Bluetooth monitor ver 5.64
= Note: Linux version 5.18.5-100.fc35.x86_64 (x86_64)                 0.447778
= Note: Bluetooth subsystem version 2.22                              0.447781
= New Index: 94:E2:3C:62:C0:40 (Primary,USB,hci0)                     0.447783
= Open Index: 94:E2:3C:62:C0:40                                       0.447783
= Index Info: 94:E2:3C:62:C0:40 (Intel Corp.)                         0.447784
@ MGMT Open: bluetoothd (privileged) version 1.22
                    

In a second terminal, we will run a LE scan operation. It will allow us to identify our ESP32 which is currently transmitting advertisements in broadcast to indicate its presence:

cyberinsophia@vm:~$ sudo hcitool lescan
                    
You should see your device appearing in the list of scanned devices. Identify the commands and events associated to the scan operations in btmon output. Another solution is to use Wireshark, a popular graphical user interface to monitor network traffic. Open a terminal and launch wireshark as root user:
cyberinsophia@vm:~$ sudo wireshark
                    
Once opened, select the interface named bluetooth0 in the list and click on the start button.
You will now be able to monitor and dissect HCI commands and events in Wireshark interface:

Communicating with ESP32

Bluetooth Low Energy roles

Now, we are ready to establish a BLE connection with our ESP32 peripheral. We will use wireshark to monitor HCI commands and events and observe the pairing process during these operations.

In Bluetooth Low Energy, a device can act according to four main roles:

  • Broadcaster / Advertiser: the device is only able to transmit advertisements,
  • Observer / Scanner: the device is only able to scan advertisements,
  • Peripheral: the device is able to transmit advertisements and accept incoming connection,
  • Central: the device is only able to scan advertisements and initiate connections.
Our Bluetooth adapter will act as a Central: we will perform a scan operation, then initiate a connection with our ESP32 peripheral. During the connection, we will initiate a bonding operation and exchange the Long Term Keys.

Establishing a BLE connection

First, open Bluetooth settings using the Gnome interface:

You will see a list of scanned devices. Identify the name you choose for your ESP32, then click on the item to initiate a connection and the bonding operation:
The device should appear as Connected in the interface:

Monitoring Bluetooth Low Energy Pairing

Observing negotiation

Bluetooth Low Energy pairing starts by negotiating the security parameters, thanks to a Pairing Request and a Pairing Response:

We can observe this negotiation using wireshark. Try to identify the Pairing Request in the packets list:
In the packet overview, you can observe the parameters transmitted by the BlueZ stack acting as Central:
The Central indicates a maximum encryption key size of 16 bytes, the presence of a Display and a Yes/No input, and provides a list of preferred keys for distribution (the Link Key, the Signature Key and the Encryption Key (LTK)).

Now, identify the Pairing Response transmitted by the ESP32 Peripheral:

The Peripheral indicates no input and no output capabilities, a maximum encryption key size of 16 bytes and only the Long Term Key during preferred keys distribution.

Observing Legacy Pairing

In this case, ESP32 is not configured to use LE Secure Connections pairing, so the Legacy Pairing will be used :

When the input / output negotiation parameters allows it, a code named User input passkey will be computed on both side, forming the future Temporary Key. In our case, our ESP32 Peripheral does not provide output nor input, leading to a Temporary Key equals to zero. Then, devices will generate and transmit a Random number (one is generated by the Central and the other is generated by the Peripheral) and compute a Confirm value. Identify the corresponding packets in wireshark (PairingConfirm, PairingRandom) and observe their content.

Based on the random values and the Temporary Key, a Short Term Key can now be calculated on both side, allowing the Link to be encrypted. You can observe the Encryption being enabled in Wireshark using LE Start Encryption command.

Observing Key Distribution

Once the link has been encrypted, the devices will transmit their respective keys according to the negotiated key distribution:

In our case, only the Long Term Key and the associated Encrypted Diversifier and Random value will be transmitted, according to the negotiation parameters. Identify the corresponding packets in Wireshark and note the Long Term Keys exchanged: