0

Has anyone built a bluetooth/BLE sniffer that runs headless and logs MAC addresses of all discoverable BT/BLE devices? What resources did you use?

I've found a tutorial on Adafruit, https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-sniffer/v2-wireshark-usage , but it seems like this only passes BLE data to wireshark, and I don't think wireshark would allow for headless operation.

Thanks for consideration.

1
  • 1
    There is a terminal version of wireshark, tshark, try that.
    – MatsK
    Oct 6, 2019 at 15:10

1 Answer 1

1

Scanning for devices is a core feature of Bluetooth Low-Energy.

For Linux, the official protocol stack for Bluetooth is BlueZ, and many tools and services will derive their functionality from it. I mention this because, while there are plenty of software-specific tools available (like noble for Node.js, or bluepy for Python), they are essentially adapters for BlueZ. It's also worth noting that Raspbian typically has a version of BlueZ installed by default.

With this in mind, it is possible for you to achieve what you're asking using BlueZ itself, or any of its software-specific derivatives (such as those mentioned above). I have used noble in the past (although I would recommend this fork, as the module has not been updated in a while), as well as using BlueZ's own native tools (i.e. btmon and hcitool).

  • Note, hcitool is officially deprecated, and was superseded by tools like btmgmt, however the API that these new tools use currently do not support scanning for duplicates (despite having the option to enable/disable duplicates). If you're not interested in scanning for duplicates (which I was), then you may find these newer tools more useful.

Using noble, you could create a javascript file like this:

var noble = require('noble'); // or '@abandonware/noble' if you're using the fork

noble.on('stateChange'), function(state) {
    if (state === 'poweredOn') {
        noble.startScanning();
    }
    else {
        noble.stopScanning();
    }
});

noble.on('discover', function(device) {
    var mac = device.address; // retrieves the MAC address
    ... do something with the MAC address ...
});

Using btmon, you could create a bash script like this:

#!/bin/bash

while IFS= read -r LINE; do
    ADDRESS="Address: (([0-9A-F]{2}:){5}[0-9A-F]{2})" # regular expression for the MAC address
    if [[ $LINE =~ $ADDRESS ]]; then
        MAC=${BASH_REMATCH[1]} # retrieves the MAC address
        ... do something with the MAC address ...
    fi
done < <(btmon 2>&1) # streams stdout and stderr from btmon to stdin

With the latter, you would also need to initiate a BLE scan for btmon as a separate process; using hcitool, btmgmt, or similar.

With either method, you would then need to decide on where you want your list of MAC addresses to go (e.g. to a file, to another PC), as well as a way to make it run automatically (e.g. systemd).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.