Capturing BLE in Wireshark

You can capture BLE in Wireshark with standard Wireshark builds. This guide assumes Linux.

  1. Run the command: mkfifo /tmp/pipe

  2. Open Wireshark

  3. Click Capture -> Options

  4. Click “Manage Interfaces” button on the right side of the window

  5. Click the “New” button

  6. In the “Pipe” text box, type “/tmp/pipe”

  7. Click Save, then click Close

  8. Click “Start”

In a terminal, run ubertooth-btle:

ubertooth-btle -f -c /tmp/pipe

In the Wireshark window you should see packets scrolling by.

Note: If you get User encapsulation not handled: DLT=147, check your Preferences->Protocols->DLT_USER the steps you want are:

  1. Click Edit -> Preferences

  2. Click Protocols -> DLT_USER

  3. Click Edit (Encapsulations Table)

  4. Click New

  5. Under DLT, select “User 0 (DLT=147)” (adjust this selection as appropriate if the error message showed a different DLT number than 147)

  6. Under Payload Protocol, enter: btle

  7. Click OK

  8. Click OK

Capturing BLE in scapy

  1. Do not use mkfifo for the filename, it will cause scapy to slow dramatically.

  2. In a terminal, run ubertooth-btle:

    ubertooth-btle -f -q /tmp/pipe
  3. Open python and run:

    from scapy.all import *
    p = sniff(offline='/tmp/pipe')

p is now a list of the packets captured!

Sniffing connection data

With recent Ubertooth firmware, only advertisements are captured by default. Once you have identified the device address of the target device you would like to sniff, run:

ubertooth-btle -t aa:bb:cc:dd:ee:ff

The Ubertooth will follow connections involving this target until -t none is passed or the device is reset.

You may need to attempt connecting several times until Ubertooth is able to follow the connection successfully.

Capturing from a remote host

You can use sshdump to remotely capture packets from a Ubertooth attached to another host or virtual machine. In the Wireshark UI, this may show up as an interface named “SSH remote capture: sshdump” which needs to be configured first with the following “remote capture command”:

killall ubertooth-btle; unlink /tmp/btlepipe; mkfifo /tmp/btlepipe; ubertooth-btle -f -c /tmp/btlepipe &>/dev/null & cat /tmp/btlepipe

The “remote interface” option is ignored and can be set to any value.

Useful display filters

Only connection requests and non-zero data packets:

btle.data_header.length > 0 || btle.advertising_header.pdu_type == 0x05

Only attribute read responses, write requests, and notifications:

btatt.opcode in { 0x0b 0x12 0x1b }