ble_monitor

Presentation

This module allows to monitor an HCI interface, using adb or hcidump. It’s a very simple module, allowing to easily analyze the HCI frames generated by a specific smarphone application or a computer application. By default, it only displays the received frames on the screen. However, this module can use a scenario (thanks to the input parameter named SCENARIO), allowing the user to select specific frame or monitor a specific connection.If you need more details about Mirage scenarios, their usage is described here. It provides two modes, according to the TIME input parameter :

  • if no value is specified (“”) : the module never stops and runs an infinite loop

  • if a positive integer is specified (e.g. “3”) : the module runs during the specified duration

Note

Please note the fact that this module receives every HCI packet transmitted, even if it is not known by Mirage. However, the default mode only prints the known packets. That’s the reason why two scenario signals are provided in order to receive packets : the first one (onPacket) receives every packet, even if it is not known by Mirage, and if it recognizes a packet already described in the framework, it calls the method onKnownPacket, generating a scenario signal using the same name.

Compatible devices

Input parameters

Name

Default value

Possible values

Description

INTERFACE

adb0

adbX,hcidumpX

Interface to use

SCENARIO

<string>

Scenario in use

TIME

<integer>

Execution duration (in seconds)

Output parameters

This module doesn’t provide any output parameters.

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

onPacket

packet

when a new packet is received

the module checks if the packet is known and calls the method onKnownPacket if it is known

onKnownPacket

packet

when a new known packet is received

the received packet is displayed

Usage

Basic usage

If you want to monitor an HCI interface on your computer, just run this module with an hcidumpX interface (e.g. if you want to monitor “hci1”, use the interface named “hcidump1”). The following example shows how to monitor hci0 :

$ sudo mirage ble_monitor INTERFACE=hcidump0
[INFO] Module ble_monitor loaded !
[SUCCESS] Hcidump successfully attached to device : hci0
[PACKET] << BLE - Advertisement Packet | type=ADV_IND | addr=10:99:F1:3C:6C:38 | data=1eff060001092002ab79f38dce6943945ca717c659b5583d9cd0f043824818 >>
[PACKET] << BLE - Advertisement Packet | type=ADV_IND | addr=54:F8:EE:FD:CE:1A | data=03039ffe17169ffe0000000000000000000000000000000000000000 >>
[PACKET] << BLE - Advertisement Packet | type=SCAN_RSP | addr=54:F8:EE:FD:CE:1A | data=09ffe0000130ca72fc5b >>
[PACKET] << BLE - Advertisement Packet | type=ADV_IND | addr=FF:FF:60:A5:17:44 | data=020105020a000319c1030302e0ff >>
[PACKET] << BLE - Advertisement Packet | type=SCAN_RSP | addr=FF:FF:60:A5:17:44 | data=110969544147202020202020202020202020 >>
[PACKET] << BLE - Advertisement Packet | type=ADV_IND | addr=4D:65:3B:37:EE:A4 | data=02011a0aff4c0010050318f41632 >>
[PACKET] << BLE - Advertisement Packet | type=SCAN_RSP | addr=4D:65:3B:37:EE:A4 | data= >>
[PACKET] << BLE - Advertisement Packet | type=ADV_IND | addr=C7:FD:F2:07:36:2E | data=0201060303edfe050954696c65 >>
[PACKET] << BLE - Advertisement Packet | type=SCAN_RSP | addr=C7:FD:F2:07:36:2E | data= >>
[PACKET] << BLE - Advertisement Packet | type=ADV_IND | addr=10:CE:A9:E5:97:9E | data=020106020a0008ff0d000901000664 >>
[PACKET] << BLE - Advertisement Packet | type=SCAN_RSP | addr=10:CE:A9:E5:97:9E | data=1309426565576920536d617274204d6f74696f6e >>
[PACKET] << BLE - Advertisement Packet | type=ADV_IND | addr=1F:46:05:0E:35:44 | data=02010611072f2a93a6bdd84152ac0b109900c6feed080957697374696b69 >>
[PACKET] << BLE - Advertisement Packet | type=SCAN_RSP | addr=1F:46:05:0E:35:44 | data=19ffffff44350e05461f67d3f603228c6cdb8d566c277a41d521 >>
[PACKET] << BLE - Advertisement Packet | type=ADV_IND | addr=FF:FF:60:A5:17:44 | data=020105020a000319c1030302e0ff >>
[PACKET] << BLE - Connect Packet | srcAddr=00:00:00:00:00:00 | dstAddr=FF:FF:60:A5:17:44 | type=public | initiatorType=public >>
[INFO] Updating connection handle : 16
[PACKET] << BLE - Connect Response Packet | srcAddr=FF:FF:60:A5:17:44 | dstAddr= | type=public | role=master | success=OK >>
[PACKET] << BLE - Connection Parameter Update Request Packet | slaveLatency=4 | timeoutMult=600 | minInterval=200 | maxInterval=220 >>
[PACKET] << BLE - Connection Parameter Update Response Packet | moveResult=0 >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Read By Type Response | data=070200120300002a0400020500012a0700120800192a >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Read By Type Response | data=070a001c0b00062a0d00120e00e1ff >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0xe | ecode=0xa >>
[PACKET] << BLE - Write Request Packet | handle=0xb | value=02 >>
[PACKET] << BLE - Write Response Packet >>
[PACKET] << BLE - Write Request Packet | handle=0xb | value=00 >>
[PACKET] << BLE - Write Response Packet >>
[PACKET] << BLE - Disconnect Packet >>

If you want to monitor the HCI log of a smartphone using ADB, use the interface adbX :

$ sudo mirage ble_monitor INTERFACE=adb0
[INFO] Module ble_monitor loaded !
[SUCCESS] ADB Device found: 3e95c5e
[INFO] Trying to send adb shell commands ...
[SUCCESS] Yeah, we can send commands.
[INFO] Looking for HCI logs ...
[SUCCESS] Log found: /sdcard/MIUI/debug_log/common/btsnoop_hci.log
[INFO] Calculating size ...
[SUCCESS] Size found: 1423843
[PACKET] << BLE - Connect Packet | srcAddr=00:00:00:00:00:00 | dstAddr=FF:FF:60:A5:17:44 | type=public | initiatorType=random >>
[INFO] Updating connection handle : 3
[PACKET] << BLE - Connect Response Packet | srcAddr=FF:FF:60:A5:17:44 | dstAddr= | type=public | role=master | success=OK >>
[PACKET] << BLE - Read By Group Type Request Packet >>
[PACKET] << BLE - Read By Group Type Response Packet | length=6 | data=010005000018060008000f1809000b000218 >>
[PACKET] << BLE - Read By Group Type Request Packet >>
[PACKET] << BLE - Read By Group Type Response Packet | length=6 | data=0c000e00e0ff >>
[PACKET] << BLE - Read By Group Type Request Packet >>
[PACKET] << BLE - Error Response Packet | req=0x10 | handle=0xf | ecode=0xa >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0x1 | ecode=0xa >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Read By Type Response | data=070200120300002a0400020500012a >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0x5 | ecode=0xa >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0x6 | ecode=0xa >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Read By Type Response | data=070700120800192a >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0x8 | ecode=0xa >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0x9 | ecode=0xa >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Read By Type Response | data=070a001c0b00062a >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0xb | ecode=0xa >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0xc | ecode=0xa >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Read By Type Response | data=070d00120e00e1ff >>
[PACKET] << BLE - Read By Type Request >>
[PACKET] << BLE - Error Response Packet | req=0x8 | handle=0xe | ecode=0xa >>
[PACKET] << BLE - Write Request Packet | handle=0xb | value=02 >>
[PACKET] << BLE - Write Response Packet >>
[PACKET] << BLE - Connection Parameter Update Request Packet | slaveLatency=4 | timeoutMult=600 | minInterval=200 | maxInterval=220 >>
[PACKET] << BLE - Connection Parameter Update Response Packet | moveResult=0 >>
[PACKET] << BLE - Write Request Packet | handle=0xb | value=00 >>
[PACKET] << BLE - Write Response Packet >>
[PACKET] << BLE - Disconnect Packet >>

Customizing the behaviour using scenarios

It’s quite easy to modify the behaviour of this module using a scenario. If you need more details about scenarios, their usage is described here. The following example allows to extract the Long Term Key, EDIV and rand values found in the monitored communications :

First of all, generate a new scenario :

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

Then, you can modify the code to customize the behaviour :

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

class monitor_test(scenario.Scenario):

        def onStart(self):
                return True

        def onEnd(self):
                return True

        def onKey(self,key):
                return True

        def onKnownPacket(self,pkt):
                if isinstance(pkt,ble.BLELongTermKeyRequest):
                        io.success("Long Term Key Request found !")
                        io.info("=> Long Term Key : "+pkt.ltk.hex())
                        io.info("=> rand : "+pkt.rand.hex())
                        io.info("=> EDIV : "+hex(pkt.ediv)+"("+str(pkt.ediv)+")")
                elif isinstance(pkt,ble.BLEEncryptionInformation):
                        io.success("Encryption Information found !")
                        io.info("=> Long Term Key : "+pkt.ltk.hex())
                elif isinstance(pkt,ble.BLEMasterIdentification):
                        io.success("Master Identification found !")
                        io.info("=> rand : "+pkt.rand.hex())
                        io.info("=> EDIV : "+hex(pkt.ediv)+"("+str(pkt.ediv)+")")

                return False

Finally, to execute your scenario, just provide its name in the SCENARIO input parameter :

$ sudo mirage ble_monitor SCENARIO=monitor_test INTERFACE=adb0
[INFO] Module ble_monitor loaded !
[SUCCESS] ADB Device found: 3e95c5e
[INFO] Trying to send adb shell commands ...
[SUCCESS] Yeah, we can send commands.
[INFO] Looking for HCI logs ...
[SUCCESS] Log found: /sdcard/MIUI/debug_log/common/btsnoop_hci.log
[INFO] Calculating size ...
[SUCCESS] Size found: 1463636
[INFO] Scenario loaded !
[INFO] Updating connection handle : 4
[INFO] Updating connection handle : 5
[SUCCESS] Long Term Key Request found !
[INFO] => Long Term Key : 238599db4eeac7f5ef9015cee68fd5cb
[INFO] => rand : 4eea2775b958f4b2
[INFO] => EDIV : 0x9adf(39647)
[INFO] Updating connection handle : 6
[SUCCESS] Long Term Key Request found !
[INFO] => Long Term Key : c62fcee31ca80c5b6f8b72b13793146b
[INFO] => rand : 0000000000000000
[INFO] => EDIV : 0x0(0)
[SUCCESS] Encryption Information found !
[INFO] => Long Term Key : ec91c50e5fd3523a32bc9cd46e6add2d
[SUCCESS] Master Identification found !
[INFO] => rand : af96e17e35489cd7
[INFO] => EDIV : 0xca19(51737)
[SUCCESS] Encryption Information found !
[INFO] => Long Term Key : b7f6dca5c2046200500d06c91688f837
[SUCCESS] Master Identification found !
[INFO] => rand : 87b9800dd07b6c00
[INFO] => EDIV : 0x8660(34400)
[INFO] Updating connection handle : 7
[SUCCESS] Long Term Key Request found !
[INFO] => Long Term Key : ec91c50e5fd3523a32bc9cd46e6add2d
[INFO] => rand : af96e17e35489cd7
[INFO] => EDIV : 0xca19(51737)
^C[INFO] Mirage process terminated !