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 : .. include:: list.ble-modules.rst Importing the Bluetooth Low Energy software components ------------------------------------------------------- Every software component described in this page can be easily imported from a :doc:`module ` or a :doc:`scenario `_ 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 :doc:`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 : * `BLEControlPDU `_ * `BLEEncryptedPacket `_ * `BLEEmptyPDU `_ * `BLEExchangeMTURequest `_ * `BLEExchangeMTUResponse `_ * `BLEConnect `_ * `BLEConnectResponse `_ * `BLEDisconnect `_ * `BLEConnectionCancel `_ * `BLEAdvertisement `_ * `BLEAdvInd `_ * `BLEAdvDirectInd `_ * `BLEAdvNonConnInd `_ * `BLEAdvScanInd `_ * `BLEScanRequest `_ * `BLEScanResponse `_ * `BLEConnectRequest `_ * `BLEFindInformationRequest `_ * `BLEFindInformationResponse `_ * `BLEReadByGroupTypeRequest `_ * `BLEReadByGroupTypeResponse `_ * `BLEReadByTypeRequest `_ * `BLEReadByTypeResponse `_ * `BLEErrorResponse `_ * `BLEWriteRequest `_ * `BLEWriteCommand `_ * `BLEWriteResponse `_ * `BLEHandleValueNotification `_ * `BLEHandleValueIndication `_ * `BLEHandleValueConfirmation `_ * `BLEReadRequest `_ * `BLEReadResponse `_ * `BLEReadBlobRequest `_ * `BLEReadBlobResponse `_ * `BLEConnectionParameterUpdateRequest `_ * `BLEConnectionParameterUpdateResponse `_ * `BLESecurityRequest `_ * `BLEPairingRequest `_ * `BLEPairingResponse `_ * `BLEPairingConfirm `_ * `BLEPairingRandom `_ * `BLEPairingFailed `_ * `BLEEncryptionInformation `_ * `BLEMasterIdentification `_ * `BLEIdentityInformation `_ * `BLEIdentityAddressInformation `_ * `BLESigningInformation `_ * `BLELongTermKeyRequest `_ * `BLELongTermKeyRequestReply `_ If you use a sniffer such as `BTLEJack `_,`NRFSniffer `_ 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 ----------------- .. image:: att.png :align: center 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 :math:`E`, :math:`S1` or :math:`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.