BLE Sniffer in Linux using Wireshark

Here is a small guide on how to build Wireshark with a BLE plugin under linux, with a small example on using this plugin with the Nordic Sniffer API.

##Prerequisites

  • nRF Dongle (PCA10031/PCA10000) or similar
  • Working installation of SEGGER J-Link drivers (To flash the chip with the firmware)
  • Python 2.7

###Tested using

  • Ubuntu 14.04.3
  • Wireshark version 1.12.0

##Sniffer API Download the Sniffer API and firmware here: nRF Sniffer

Inside the zip-file you will find another zip-file called SnifferAPI.zip. Unzip the content of this file to your workspace. These are the files you need. The "Sniffer API" folder contains the python API, and the "wireshark_dissector_source" folder contains the plugin source.

##Build Wireshark with BLE plugin

###Dependencies

For Ubuntu:

sudo apt-get install build-essential automake autoconf libgtk2.0-dev libglib2.0-dev libpcap0.8-dev flex bison

Also check out the Wireshark wiki: https://wiki.wireshark.org/Development

###Build

  • Download the Wireshark plugin: nordic_ble_linux-1.12.0.zip

  • Download the Wireshark source: wireshark-1.12.0.tar.bz2

  • Decompress wireshark-1.12.0.tar.bz2 and move into created folder (wireshark-1.12.0)

  • Decompress nordic_ble_linux-1.12.0.zip in plugins folder

  • Move Custom files to plugins folder

    $ mv plugins/nordic_ble/Custom.m4-1.12.0 plugins/Custom.m4 $ mv plugins/nordic_ble/Custom.make-1.12.0 plugins/Custom.make $ mv plugins/nordic_ble/Custom.nmake-1.12.0 plugins/Custom.nmake

  • Add packet-nordic_ble.c from the "wireshark_dissector_source" folder in the Sniffer API to plugins/nordic_ble folder

  • Compile wireshark:

    $ ./autogen.sh $ ./configure $ make

  • Then run wireshark to see if it works:

    $ ./wireshark

##Flash firmware

Flash the chip with the firmware included in the "Firmware" folder in the Sniffer API zip file you downloaded (ble-sniffer_nRF51822_1.0.1_1111_Sniffer.hex), using JLinkExe or preferred tool. No need to flash softdevice first.

##Linux example code

  • Download the example python script here: example_linux.py

  • Put it in the Sniffer API root folder (Called "SnifferAPIBuild" after the unzip)

  • install the "pyserial" python 2.7 package:

    pip install pyserial

In the example script under def setup() you can set the UART port for the nRF USB dongle. In Ubuntu it should enumerate under "/dev/ttyACM0". Check to see if this is the case:

ls -l /dev/ttyACM0

Also set the address of the device you want to sniff (tls_dev_addr)

Run the example script:

sudo python linux_example.py

(You might need to run as sudo to access the UART port)

If the device is found, run Wireshark (from the Wireshark root folder) using:

./wireshark -Y btle -k -i /home/username/snifferAPI_directory/SnifferAPIBuild/logs/nordic_ble.pipe

(This command will also be output from the script when the sniffer successfully finds the device. So you can copy/paste it to get the right path for the nordic_ble.pipe file)

Wireshark should start to show the packets now.

  • Hello Stian, I've merged the code in this blog post in my fork of the Adafruit BLE Sniffer.

    The Adafruit sniffer.py script does a scan and presents the list of devices in range. You can select the device and start the Wireshark capture.

    There is nothing special, just you don't have to guess the value of tls_dev_addr.

    I gave you all credits in the files commited to github and I hope there are no licensing issues.

    Thanks!

  • While building wireshark from scratch. Make sure that, packet capturing development files (headers) are installed, On Fedora 21, this can be done as below:

    $ sudo yum install libpcap-devel
    
  • FormerMember
    FormerMember

    Thanks Stian for your effort! Can confirm that it work for me in Ubuntu 15.04. Great to have this tool work with Linux now.

    I had to go through a bit of effort to make this work. Here are some pointers for others which might help.

    1. Install dependency packages for wireshark. autogen stops when these are not installed. libtool and libtoolize are two packages that I think I installed apart from what is mentioned in this post.
    2. Note that example-linux.py stops scanning when the device address which it is searching is not found and the nordic_ble.pipe is not created. Update1: Also looks like the nordic_ble.pipe file needs to be deleted before a new sniff is started.
    3. Had search a lot to figure out this bug was making wireshark get a segmentation fault.
    4. Update1: Forgot to mention that in the example_linux.py file attached a colon is missing at the end of the if statement in the loop method.

    Happy sniffing to you all! :)