Bluetooth Low Energy protocol¶
Mirage includes a lot of software components allowing to communicate with Bluetooth Low Energy (BLE) devices. This page presents a subset of these components, and provides some basic examples presenting their usage.
Bluetooth Low Energy modules¶
Mirage includes many modules allowing to analyze the security of Bluetooth Low Energy communications. These modules can perform attacks or useful actions in order to manipulate a Bluetooth Low Energy device. The available modules and the links to the corresponding documentation pages are listed in the following table :
Name |
Description |
Documentation |
---|---|---|
ble_info |
This module displays useful informations about a given interface. |
|
ble_connect |
This module connects to a Peripheral’s device as Central. |
|
ble_master |
This module simulates a Central device. |
|
ble_slave |
This module simulates a Peripheral device. |
|
ble_discover |
This module allows to dump the ATT/GATT database of a Peripheral. |
|
ble_adv |
This module sends advertisements. |
|
ble_scan |
This module discovers Advertisers and Peripherals by scanning advertisements. |
|
ble_pair |
This module performs a pairing with a Peripheral or a Central. |
|
ble_mitm |
This module performs a Man-in-the-Middle attack. |
|
ble_sniff |
This module sniffs the advertisements and new / existing connections. |
|
ble_jam |
This module jams the advertisements or connections. |
|
ble_hijack |
This module hijacks an existing connection. |
|
ble_crack |
This module cracks a Temporary Key. |
|
ble_monitor |
This module monitors an HCI communication. |
Importing the Bluetooth Low Energy software components¶
Every software component described in this page can be easily imported from a module or a :doc:`scenario <scenarios>`_ environment using the following statement :
from mirage.libs import ble
Then, every component is available using the ble
namespace :
packet = ble.BLEReadRequest(handle=0x0021)
Interacting with the protocol¶
Mirage can use multiple hardware component in order to interact with the protocol : it provides some drivers supporting standard HCI devices or the most used sniffers (such as BTLEJack, Ubertooth or NRFSniffer). You can also monitor an HCI communication using ADB or HCIDump. Finally, you can read or write a PCAP file containing Link Layer packets using the PCAP Device. Every devices can be used to send and/or receive BLE frames but can also provide some specific features by providing shared methods. The supported Devices are listed here.
If you want to manipulate a specific device, you need to use the corresponding Emitter and / or Receiver with an interface related to your device. The following page explains how to use these software components.
Bluetooth Low Energy packets¶
Mirage manipulates the Bluetooth Low Energy packets as child classes of BLEPacket
(mirage.libs.ble_utils.packets.BLEPacket), which is itself a child class of Packet
(mirage.libs.wireless_utils.packets.Packet). The following list describes the available packets and provides some links to the corresponding documentation pages :
If you use a sniffer such as BTLEJack,`NRFSniffer <devices.html#nrfsniffer-device>`_ or Ubertooth, some additional informations provided by the sniffer can be included in the packet using the additionalInformations
attribute. The additional informations are stored as instance of the class BLESniffingParameters
(mirage.libs.ble_utils.packets.BLESniffingParameters).
ATT, GATT and Security Manager Dissectors¶
Some Bluetooth Low Energy packets may include complex fields, that’s why Mirage provides some dissectors allowing to easily manipulate them. A dissector is a class allowing to easily convert a complex data structure to the corresponding raw bytes, or the raw bytes to the corresponding data structure. Every Bluetooth Low Energy dissectors inherits from Dissector
(mirage.libs.wireless_utils.dissectors) and are documented here.
The Dissector
class includes some magic methods in order to facilite the manipulation of the complex data structure. Indeed, it is represented as a dictionary, but every key of this dictionary can be accessed as a standard attribute of the class. Two main methods are provided, build
(allowing to convert the data structure to the corresponding raw bytes) and dissect
(allowing to convert the raw bytes to the corresponding data structure). The complex data structure is stored in the attribute named content
while the raw bytes are stored in the attribute named data
.
Mirage provides a dissector for the permissions Flag linked to the ATT/GATT layers (mirage.libs.ble_utils.dissectors.PermissionsFlag):
- Example
>>> dissector=PermissionsFlag(permissions=["Write", "Read"]) >>> dissector.data.hex() '0a' >>> dissector2=PermissionsFlag(data=bytes.fromhex("0a")) >>> dissector2.permissions ['Write', 'Read'] >>> for permission in dissector2: ... print(permission) ... Write Read >>> dissector2.permissions += ["Write Without Response"] >>> dissector2.data.hex() '0e' >>> dissector.data = bytes.fromhex("0e") >>> dissector.dissect() >>> dissector.permissions ['Write', 'Write Without Response', 'Read']
You can also manipulate the UUID, commonly used in Bluetooth Low Energy communications (mirage.libs.ble_utils.dissectors.UUID) :
- Example
>>> UUID(name="Generic Access").data.hex() '1800' >>> UUID(data=bytes.fromhex('1800')).name 'Generic Access' >>> UUID(data=bytes.fromhex('1800')).UUID16 6144 >>> UUID(data=bytes.fromhex('1800')).UUID128.hex() '0000180000001000800000805f9b34fb' >>> UUID(data=bytes.fromhex('1801')) UUID(128bits:00001801-0000-1000-8000-00805f9b34fb, 16bits:0x1801, name:Generic Attribute )
Mirage allows to manipulate some datas stored in an ATT / GATT server using the following dissectors :
CharacteristicDeclaration (mirage.libs.ble_utils.dissectors.CharacteristicDeclaration) :
- Example
>>> CharacteristicDeclaration(data=bytes.fromhex('2a00000302')) Characteristic Declaration( UUID=UUID(128bits:00002a00-0000-1000-8000-00805f9b34fb, 16bits:0x2a00, name:Device Name ) , valueHandle=0x3 , permissionsFlag=Flag(Read)) >>> CharacteristicDeclaration(data=bytes.fromhex('2a00000302')).UUID UUID(128bits:00002a00-0000-1000-8000-00805f9b34fb, 16bits:0x2a00, name:Device Name ) >>> CharacteristicDeclaration(data=bytes.fromhex('2a00000302')).valueHandle 3 >>> CharacteristicDeclaration(data=bytes.fromhex('2a00000302')).permissionsFlag Flag(Read) >>> CharacteristicDeclaration(UUID=UUID(name="Device Name"),valueHandle=0x0003,permissionsFlag=PermissionsFlag(permissions=["Read"])).data.hex() '2a00000302'CharacteristicDescriptor (mirage.libs.ble_utils.dissectors.CharacteristicDescriptor) : :Example:
>>> CharacteristicDescriptor(data=bytes.fromhex("2901")) Characteristic Descriptor( UUID=UUID(128bits:00002901-0000-1000-8000-00805f9b34fb, 16bits:0x2901, name:Characteristic User Description ) ) >>> CharacteristicDescriptor(UUID=UUID(UUID16=0x2901)).data.hex() '2901'Service (mirage.libs.ble_utils.dissectors.Service) : :Example:
>>> Service(data=bytes.fromhex("1800")) Service( UUID=UUID(128bits:00001800-0000-1000-8000-00805f9b34fb, 16bits:0x1800, name:Generic Access ) ) >>> Service(data=bytes.fromhex("1800")).UUID UUID(128bits:00001800-0000-1000-8000-00805f9b34fb, 16bits:0x1800, name:Generic Access ) >>> Service(UUID=UUID(UUID16=0x1800)).data.hex() '1800'
Finally, Mirage allows to manipulate some complex data structure used in the Security Manager (SM) layer :
InputOutputCapability (mirage.libs.ble_utils.dissectors.InputOutputCapability) : :Example:
>>> InputOutputCapability(display=True, yesno=False, keyboard=True).data.hex() '04' >>> InputOutputCapability(data=data=bytes.fromhex("04")) Input Output Capability(0x4,keyboard:yes|yesno:no|display:yes)AuthReqFlag (mirage.libs.ble_utils.dissectors.AuthReqFlag) : :Example:
>>> AuthReqFlag(bonding=True, mitm=True).data.hex() '05' >>> AuthReqFlag(data=data=bytes.fromhex("05")) AuthReq Flag(0x5,bonding:yes|mitm:yes|secureConnections:no|keypress:no|ct2:no)KeyDistributionFlag (mirage.libs.ble_utils.dissectors.KeyDistributionFlag) : :Example:
>>> KeyDistributionFlag(idKey=True,encKey=True).data.hex() '03' >>> KeyDistributionFlag(data=bytes.fromhex("03")) Key Distribution Flag(0x3,encKey:yes|idKey:yes|signKey:no|linkKey:no)
ATT / GATT server¶
The Bluetooth Low Energy provides two main applicative layers : ATT (Attribute Protocol) and GATT (Generic Attribute Profile). If you want to implement a Peripheral device, you need to instantiate a GATT Server in order to send the right responses to the Central’s ATT requests. Mirage provides a basic ATT Server implementation (mirage.libs.ble_utils.att_server.ATT_Server) and a GATT Server (mirage.libs.ble_utils.att_server.GATT_Server) based on it. Please refer to the documentation of the submodule named att_server
for more details (mirage.libs.ble_utils.att_server).
Cryptographic functions¶
Mirage provides multiple cryptographic functions, commonly used in the Security Manager layer of the Bluetooth Low Energy protocol stack. These functions are stored in two main classes, included in the crypto
submodule (mirage.libs.ble_utils.crypto) :
BLECrypto (mirage.libs.ble_utils.crypto.BLECrypto) : this class provides multiple class methods implementing the cryptographic functions listed in the Security Manager specification, such as \(E\), \(S1\) or \(C1\) and their inverse functions. It also provides a method named
crackTemporaryKey
, allowing to crack a temporary key by providing the corresponding paremeters.BLELinkLayerCrypto (mirage.libs.ble_utils.crypto.BLELinkLayerCrypto) : this class provides an API allowing to encrypt and decrypt the link layer frames.
Warning
The implementation of BLELinkLayerCrypto is not mature nor user friendly. It may be improved in the next release.