ble_master

Presentation

ble_master simulates a master’s behaviour. It is a core module for the framework, allowing to quickly build recurrent behaviours during a security audit, and is also used in chained operations (for example with ble_hijack). If a scenario is provided, the module is launched in “scenario” mode, with events given as callbacks on specific packet types, allowing to implement complex interactions. Otherwise, it is launched in “interpreter” mode, opening a CLI for the user.

Input parameters

Name

Default value

Possible values

Description

INTERFACE

hci0

hciX, microbitX, sniffleX, butterflyX

Interface to use

TARGET

<BD address>

Target address

CONNECTION_TYPE

public

public|random

Connection mode

SCENARIO

<scenario>

Scenario to use

Scenario signals

The behaviour of this module can be modified using scenarios. If you need more details about Mirage scenarios, their usage is described here. The following signals are generated by this module if a scenario is provided using the SCENARIO input parameter :

Signal

Parameters

Activation

Default behaviour

onStart

when the module starts its execution

nothing is executed

onEnd

when the module stops its execution

nothing is executed

onKey

key

when a key is pressed

nothing is executed

onSlaveConnect

packet

when an incoming connection request is received (from slave)

the prompt is updated

onSlaveDisconnect

packet

when an incoming disconnection request is received (from slave)

the prompt is updated

Commands

The following commands are available in the CLI interface :

  • clear : clears the screen

  • connect <BD address> : calls the ble_connect module to initiate a connection with the device at the given address

  • connect <BD address> <type> : calls the ble_connect module to initiate a connection with the device at the given address, with the specified connection type

  • connections : lists the current connections

  • switch <connection> : switch the active connection (connection on which we make the commands) to the specified one

  • disconnect : disconnects from the active connection

  • scan : calls the calls the ble_scan module to list near BLE devices

  • scan <duration> : calls the ble_scan module for the specified duration to list near BLE devices

  • discover <what> <start> <end> <filter_by> <filter> : calls the ble_discover module with the specified (optional) parameters

  • read <handle> : sends a Read Request on the specified handle on the active connection

  • write_cmd <handle> <value> : sends a Write Command on the specified handle with the specified value on the active connection

  • write_req <handle> <value> : sends a Write Request on the specified handle with the specified value on the active connection

  • pairing <active> <parameters>: calls the ble_pairing using the specified parameters :

    • <active> : this parameter indicates if the pairing process is active or passive

    • <parameters> : this parameter allow to indicate multiple parameters in order to customize the pairing process, separated by the symbol | :

      • inputOutput : indicates the input output capabilities (yesno,display,keyboard)

      • authentication : indicates the authentication flag (bonding,ct2,mitm,secureConnections,keypress)

      • ltk : indicates the Long Term Key

      • ediv : indicates the ediv

      • rand : indicates the rand

      • irk : indicates the Identity Resolution Key

      • addr : indicates the address

      • addr_type : indicates the address type

      • csrk : indicates the Connection Signature Resolving Key

      • pin : indicates the PIN to use

      Example :

      inputOutput=yesno|authentication=bonding|ltk=112233445566778899aabbccddeeff |rand=1122334455667788|ediv=12

  • disconnect : disconnects from the current connection

  • exit : ends the execution

Usage

CLI mode

If you want to use this module in CLI mode, just calls the module without input parameters :

$ sudo mirage ble_master
[INFO] Module ble_master loaded !
[SUCCESS] HCI Device (hci0) successfully instanciated !
[MASTER]:

You can easily scan the devices using the scan command :

[MASTER]: scan
┌Devices found──────┬──────┬─────────┬───────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────┐
│ BD Address        │ Name │ Company │ Flags                                             │ Advertising data                                                   │
├───────────────────┼──────┼─────────┼───────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ 1C:1E:E3:88:4A:C0 │      │         │ LE General Discoverable Mode                      │ 0201021107fc9dd0b3cb84e0840642f3f7e1e0bfcb (ADV_IND)               │
│ 44:7E:03:CC:4C:4F │      │ Google  │                                                   │ 03039ffe17169ffe0000000000000000000000000000000000000000 (ADV_IND) │
│                   │      │         │                                                   │ 09ffe0000130ca72fc5b (SCAN_RSP)                                    │
│ C7:FD:F2:07:36:2E │ Tile │         │ LE General Discoverable Mode,BR/EDR not supported │ 0201060303edfe050954696c65 (ADV_IND)                               │
└───────────────────┴──────┴─────────┴───────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────┘
┌Devices found──────┬───────┬────────────────────────┬───────────────────────────────────────────────────┬────────────────────────────────────────────────────────────────────┐
│ BD Address        │ Name  │ Company                │ Flags                                             │ Advertising data                                                   │
├───────────────────┼───────┼────────────────────────┼───────────────────────────────────────────────────┼────────────────────────────────────────────────────────────────────┤
│ 1C:1E:E3:88:4A:C0 │       │                        │ LE General Discoverable Mode                      │ 0201021107fc9dd0b3cb84e0840642f3f7e1e0bfcb (ADV_IND)               │
│ 44:7E:03:CC:4C:4F │       │ Google                 │                                                   │ 03039ffe17169ffe0000000000000000000000000000000000000000 (ADV_IND) │
│                   │       │                        │                                                   │ 09ffe0000130ca72fc5b (SCAN_RSP)                                    │
│ C7:FD:F2:07:36:2E │ Tile  │                        │ LE General Discoverable Mode,BR/EDR not supported │ 0201060303edfe050954696c65 (ADV_IND)                               │
│ C4:BE:84:39:8E:07 │ Salon │ Texas Instruments Inc. │ LE General Discoverable Mode,BR/EDR not supported │ 0201060bff0d0086484f4d45424545 (ADV_IND)                           │
│                   │       │                        │                                                   │ 100953616c6f6e00000000000000000000051228005000020a00 (SCAN_RSP)    │
└───────────────────┴───────┴────────────────────────┴───────────────────────────────────────────────────┴────────────────────────────────────────────────────────────────────┘

Then, you can connect on a specific device using connect :

[MASTER]: connect C4:BE:84:39:8E:07
[INFO] Trying to connect to : C4:BE:84:39:8E:07 (type : public)
[INFO] Updating connection handle : 16
[SUCCESS] Connected on device : C4:BE:84:39:8E:07
[MASTER|C4:BE:84:39:8E:07]: connections
┌Active connections──────────────┬────────┐
│ Identifier │ Address           │ Handle │
├────────────┼───────────────────┼────────┤
│ 1          │ C4:BE:84:39:8E:07 │ 16     │
└────────────┴───────────────────┴────────┘

You can discover the GATT layer using the discover command :

[MASTER|C4:BE:84:39:8E:07]: discover
[INFO] Services discovery ...
┌Services──────┬────────────┬────────┬──────────────────────────────────┬────────────────────┐
│ Start Handle │ End Handle │ UUID16 │ UUID128                          │ Name               │
├──────────────┼────────────┼────────┼──────────────────────────────────┼────────────────────┤
│ 0x0001       │ 0x000b     │ 0x1800 │ 0000180000001000800000805f9b34fb │ Generic Access     │
│ 0x000c       │ 0x000f     │ 0x1801 │ 0000180100001000800000805f9b34fb │ Generic Attribute  │
│ 0x0010       │ 0x001e     │ 0x180a │ 0000180a00001000800000805f9b34fb │ Device Information │
│ 0x001f       │ 0x002f     │        │ a8b3fff04834405189d03de95cddd318 │                    │
│ 0x0030       │ 0x0039     │        │ a8b3ffe04834405189d03de95cddd318 │                    │
│ 0x003a       │ 0xffff     │        │ f000ffc004514000b000000000000000 │                    │
└──────────────┴────────────┴────────┴──────────────────────────────────┴────────────────────┘
[INFO] Characteristics by service discovery ...
┌Service 'Generic Access'(start Handle = 0x0001 / end Handle = 0x000b)──────────┬────────────────────────────────────────────┬─────────────┬──────────────────┬─────────────┐
│ Declaration Handle │ Value Handle │ UUID16 │ UUID128                          │ Name                                       │ Permissions │ Value            │ Descriptors │
├────────────────────┼──────────────┼────────┼──────────────────────────────────┼────────────────────────────────────────────┼─────────────┼──────────────────┼─────────────┤
│ 0x0002             │ 0x0003       │ 0x2a00 │ 00002a0000001000800000805f9b34fb │ Device Name                                │ Read        │ Salon            │             │
│ 0x0004             │ 0x0005       │ 0x2a01 │ 00002a0100001000800000805f9b34fb │ Appearance                                 │ Read        │                  │             │
│ 0x0006             │ 0x0007       │ 0x2a02 │ 00002a0200001000800000805f9b34fb │ Peripheral Privacy Flag                    │ Read        │                  │             │
│ 0x0008             │ 0x0009       │ 0x2a03 │ 00002a0300001000800000805f9b34fb │ Reconnection Address                       │ Write       │                  │             │
│ 0x000a             │ 0x000b       │ 0x2a04 │ 00002a0400001000800000805f9b34fb │ Peripheral Preferred Connection Parameters │ Read        │ 5000a0000000e803 │             │
└────────────────────┴──────────────┴────────┴──────────────────────────────────┴────────────────────────────────────────────┴─────────────┴──────────────────┴─────────────┘

[...]

┌Service f000ffc004514000b000000000000000(start Handle = 0x003a / end Handle = 0xffff)─┬─────────────────────────────────────┬───────┬────────────────────────────────────────────────┐
│ Declaration Handle │ Value Handle │ UUID16 │ UUID128                          │ Name │ Permissions                         │ Value │ Descriptors                                    │
├────────────────────┼──────────────┼────────┼──────────────────────────────────┼──────┼─────────────────────────────────────┼───────┼────────────────────────────────────────────────┤
│ 0x003b             │ 0x003c       │        │ f000ffc104514000b000000000000000 │      │ Notify,Write,Write Without Response │       │ Client Characteristic Configuration :          │
│                    │              │        │                                  │      │                                     │       │ Characteristic User Description : Img Identify │
│ 0x003f             │ 0x0040       │        │ f000ffc204514000b000000000000000 │      │ Notify,Write,Write Without Response │       │ Client Characteristic Configuration :          │
│                    │              │        │                                  │      │                                     │       │ Characteristic User Description : Img Block    │
└────────────────────┴──────────────┴────────┴──────────────────────────────────┴──────┴─────────────────────────────────────┴───────┴────────────────────────────────────────────────┘

You can easily initiate a specific request using read, write_req or write_cmd :

[MASTER|C4:BE:84:39:8E:07]: read 0x0021
[INFO] Read Request : handle = 0x0021
[SUCCESS] Response : handle = 0x0021 / Values (hex) = 00
[MASTER|C4:BE:84:39:8E:07]: write_req 0x0021 5510000d0a
[INFO] Write Request : handle = 0x0021 / value = 5510000d0a
[SUCCESS] Response : success
[MASTER|C4:BE:84:39:8E:07]: write_cmd 0x0021 5510010d0a
[SUCCESS] Write Command : handle = 0x0021 / value = 5510010d0a

You can initiate a pairing process using the following command :

[MASTER|C4:BE:84:39:8E:07]: pairing active inputOutput=yesno|authentication=bonding|ltk=112233445566778899aabbccddeeff|rand=1122334455667788|ediv=12
┌Input parameters────┬────────────────────────────────┐
│ Name               │ Value                          │
├────────────────────┼────────────────────────────────┤
│ INTERFACE          │ hci0                           │
│ MODE               │ master                         │
│ PIN                │                                │
│ ACTIVE             │ yes                            │
│ LTK                │ 112233445566778899aabbccddeeff │
│ EDIV               │ 12                             │
│ RAND               │ 1122334455667788               │
│ IRK                │                                │
│ ADDR_TYPE          │                                │
│ ADDR               │                                │
│ CSRK               │                                │
│ KEYBOARD           │ no                             │
│ YESNO              │ yes                            │
│ DISPLAY            │ no                             │
│ CT2                │ no                             │
│ MITM               │ no                             │
│ BONDING            │ yes                            │
│ SECURE_CONNECTIONS │ no                             │
│ KEYPRESS           │ no                             │
└────────────────────┴────────────────────────────────┘
[PACKET] << BLE - Pairing Request Packet | outOfBand=no | inputOutputCapability=0x3 | authentication=0x1 | maxKeySize=16 | initiatorKeyDistribution=0x1 | responderKeyDistribution=0x1 >>
[PACKET] << BLE - Pairing Response Packet | outOfBand=no | inputOutputCapability=0x0 | authentication=0x5 | maxKeySize=16 | initiatorKeyDistribution=0x1 | responderKeyDistribution=0x1 >>
[INFO] At least one of the devices doesn't support LE secure connections
┌─────────────┬─────────────────┬────────────┐
│ Out Of Bond │ IO Capabilities │ Just Works │
├─────────────┼─────────────────┼────────────┤
│ no          │ yes             │ no         │
└─────────────┴─────────────────┴────────────┘
[SUCCESS] Pairing Method selected : JustWorks
[SUCCESS] Generating random : 6f416801c7aa05a6e64efab61e7f13f9
[SUCCESS] Generating Temporary Key : 00000000000000000000000000000000
[SUCCESS] Generating MConfirm : 1909705fe9ce9fdfb373a3a4b4d8a0e9
[PACKET] << BLE - Pairing Confirm Packet | confirm=e9a0d8b4a4a373b3df9fcee95f700919 >>
[PACKET] << BLE - Pairing Confirm Packet | confirm=2cf9eb1070422dbd2ff5baae89da323a >>
[PACKET] << BLE - Pairing Random Packet | random=6f416801c7aa05a6e64efab61e7f13f9 >>
[PACKET] << BLE - Pairing Random Packet | random=32bbdfd78919c8e56c96ee6dc60eac90 >>
[SUCCESS] Confirm Value correct !
[SUCCESS] Generating Short Term Key (STK): 864dfbf09cb46478581894d9ccf67a1d
[SUCCESS] Encryption enabled !
[PACKET] << BLE - Encryption Information Packet | ltk=2a9d8a1d78a5db22091a8005d820d9da >>
[SUCCESS] Long Term Key (LTK) received : dad920d805801a0922dba5781d8a9d2a
[PACKET] << BLE - Master Identification Packet | rand=a179123b95cffdac | ediv=0x59d9 >>
[SUCCESS] EDIV and RAND received :  0x59d9 / a179123b95cffdac
[INFO] Sending LTK...
[SUCCESS] Sent !
[SUCCESS] Active pairing enabled !

Finally, you can use the disconnect command in order to disconnect from the target device :

[MASTER|C4:BE:84:39:8E:07]: disconnect
[INFO] Disconnected !
[SUCCESS] Disconnected !

Customizing the behaviour using scenarios

If you want to use a scenario, you can use the create_scenario command in order to generate a basic code :

$ mirage --create_scenario
[QUESTION] Scenario's name : master_test
[SUCCESS] Scenario master_test successfully generated : /home/user/.mirage/scenarios/master_test.py
[INFO] Mirage process terminated !

Then, you can modify the code as you want, the following example allow to send a specific Write Command if the user press the space key:

from mirage.core import scenario
from mirage.libs import io,ble,bt,utils

class master_test(scenario.Scenario):

        def onStart(self):
                self.emitter = self.module.emitter
                self.receiver = self.module.receiver
                self.emitter.sendp(ble.BLEConnect("C4:BE:84:39:8E:07"))
                self.value = bytes.fromhex("5510000d0a")
                return True

        def onEnd(self):
                return True

        def onKey(self,key):
                if key == "space":
                        self.emitter.sendp(ble.BLEWriteCommand(handle=0x0021, value=self.value))
                        self.value = bytes.fromhex("5510010d0a") if self.value == bytes.fromhex("5510000d0a") else bytes.fromhex("5510000d0a")
                elif key == "q":
                        self.emitter.sendp(ble.BLEDisconnect())

If you want to use this scenario, just provide its name as the value of the input parameter SCENARIO :

$ sudo mirage ble_master SCENARIO=master_test
[INFO] Module ble_master loaded !
[SUCCESS] HCI Device (hci0) successfully instanciated !
[INFO] Scenario loaded !
[INFO] Updating connection handle : 16
 [INFO] Write command : 5510000d0a
 [INFO] Write command : 5510010d0a
 [INFO] Write command : 5510000d0a
 [INFO] Write command : 5510010d0a
q[INFO] Disconnected !
[INFO] Mirage process terminated !