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. Compatible devices ------------------ * `HCI Device `_ * `BTLEJack Device `_ * `ButteRFly Device `_ * `Sniffle Device `_ Input parameters ----------------- +----------------------------------------+---------------------------------------+-------------------------------------------------------------+--------------------------------------------------------------------------+ | Name | Default value | Possible values | Description | +========================================+=======================================+=============================================================+==========================================================================+ | INTERFACE | hci0 | hciX, microbitX, sniffleX, butterflyX | Interface to use | +----------------------------------------+---------------------------------------+-------------------------------------------------------------+--------------------------------------------------------------------------+ | TARGET | | | Target address | +----------------------------------------+---------------------------------------+-------------------------------------------------------------+--------------------------------------------------------------------------+ | CONNECTION_TYPE | public | public|random | Connection mode | +----------------------------------------+---------------------------------------+-------------------------------------------------------------+--------------------------------------------------------------------------+ | 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 ** : calls the `ble_connect `_ module to initiate a connection with the device at the given address - **connect ** : 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 ** : 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 ** : calls the `ble_scan `_ module for the specified duration to list near BLE devices - **discover ** : calls the `ble_discover `_ module with the specified (optional) parameters - **read ** : sends a *Read Request* on the specified handle on the active connection - **write_cmd ** : sends a *Write Command* on the specified handle with the specified value on the active connection - **write_req ** : sends a *Write Request* on the specified handle with the specified value on the active connection - **pairing **: calls the `ble_pairing `_ using the specified parameters : * ** : this parameter indicates if the pairing process is *active* or *passive* * ** : 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 !