Sniffing Bluetooth Traffic with the Ubertooth One on MacOS Big Sur
hacking bluetooth ubertooth wireless big surLearn to capture and analyse bluetooth communications on MacOS Big Sur using the
ubertooth one
device from Great Scott Gadgets, which you can find here.
Sniffing Bluetooth Traffic with the Ubertooth One on MacOS Big Sur
Ubertooth One is an open source 2.4 GHz wireless development platform suitable for Bluetooth experimentation.
This article is a work in progress, and serves to document my notes experimenting with Bluetooth capture on MacOS Big Sur using the Ubertooth One.
Pre-requisites:
I'm assuming the following things are set up:
-
homebrew
, and Python 3 installed (preferably viahomebrew
). -
A working
Ubertooth One
connected via USB.
Setup
- Plug in the device, and use
ioreg
to confirm that it's online:
-> % ioreg -p IOUSB -l -w 0 | grep Ubertooth
| +-o Ubertooth One@14210000 <class AppleUSBDevice, id 0x100137a3f, registered, matched, active, busy 0 (2 ms), retain 13>
| "USB Product Name" = "Ubertooth One"
| "kUSBProductString" = "Ubertooth One"
- Install the dependencies you need to build the Ubertooth libraries and tools:
-> % brew install libusb wget cmake pkg-config
- Install the Bluetooth baseband library:
mkdir -p ~/tools/ubertooth; cd $_
wget https://github.com/greatscottgadgets/libbtbb/archive/2020-12-R1.tar.gz -O libbtbb-2020-12-R1.tar.gz
tar zxvf libbtbb-2020-12-R1.tar.gz
cd libbtbb-2020-12-R1
mkdir build; cd $_
cmake ..
make
sudo make install
- Install the Ubertooth tools:
cd ~/tools/ubertooth
wget https://github.com/greatscottgadgets/ubertooth/releases/download/2020-12-R1/ubertooth-2020-12-R1.tar.xz
tar zxvf ubertooth-2020-12-R1.tar.xz
cd ubertooth-2020-12-R1/host
mkdir build; cd $_
cmake ..
make
sudo make install
- Update the firmware
cd ~/tools/ubertooth/ubertooth-2020-12-R1/ubertooth-one-firmware-bin
ubertooth-dfu -d bluetooth_rxtx.dfu -r
If everything works out, you should see something similar to the following in the terminal:
Switching to DFU mode...
Checking firmware signature
........................................
........................................
........................................
........
In my case, I received a control message unsupported error message. However, checking the version number with ubertooth-util
confirmed that the firmware update was actually successful.
-> % ubertooth-util -v
Firmware version: 2020-12-R1 (API:1.07)
Trying a First Capture
If everything is working correctly, you should be able to run ubertooth-rx
and see output that looks like this.
-> % ubertooth-rx
systime=1611516018 ch= 2 LAP=bcf902 err=1 clkn=661 clk_offset=5364 s=-66 n=-55 snr=-11
systime=1611516018 ch=21 LAP=ee7086 err=0 clkn=1676 clk_offset=1797 s=-42 n=-55 snr=13
systime=1611516019 ch=12 LAP=2ba543 err=2 clkn=3879 clk_offset=3341 s=-60 n=-55 snr=-5
systime=1611516019 ch=76 LAP=2ba543 err=1 clkn=4131 clk_offset=3347 s=-72 n=-55 snr=-17
systime=1611516019 ch=29 LAP=ee7086 err=2 clkn=4236 clk_offset=1887 s=-43 n=-55 snr=12
There's a lot to gather from this information, and so here's a description of what some of the more useful fields mean:
- systime - The current UNIX timestamp
- ch - Channel (at time of capture) used by the device referenced by the LAP
- LAP - Lower Address Part
- s - Signal
- n - Noise
- snr - Signal to noise ratio
Something that I found pretty useful was to run and watch the output of ubertooth-rx
while moving an active device closer and farther away from my Ubertooth One so that I could use the signal strength to figure out which LAP I wanted to target. More on that in the next section.
Sniffing
If you've managed to follow along, you should have some impressive looking text and numbers on your screen. But what can you actually do with it? In order to start sniffing Bluetooth conversations between target devices, you need something called the BD_ADDR
, or Bluetooth device address, which is similar to an Ethernet MAC address.
The Bluetooth protocol uses Frequency Hopping Spread Spectrum (FHSS) to hop between different channels of the 2.4Ghz ISM radio band to avoid interference. The information used to time this hopping behavior is pseudo-random, and derived from the value of the “master” device's BD_ADDR. Long story short, in order to sniff traffic from a device, you need to be able to account for it's hops, which requires knowing it's BD_ADDR.
Bluetooth frames don't contain the full BD_ADDR, they contain the lower 24 bits (3 bytes), known as the Lower Address Part (LAP). The BD_ADDR is actually a combination of the LAP, plus 1 byte making up a portion called the Upper Address Part (UAP), and finally an initial 2 bytes at the beginning of the BD_ADDR, called the Non-significant Address Part (NAP). The combinatino of the UAP and LAP is called the Significant Address Part (SAP).
The Ubertooth One (or any other Bluetooth receiver) can passively sniff the LAPs, because these are transmitted in every frame. Some additional magic is performed by the Ubertooth One in order to calculate the UAP and LAP portions.
After playing around with it for a bit, I found I was pretty successfully able to get the UAP of two devices (a phone and a headset) by running ubertooth-rx
in survey mode (using the -z
flag) for a few minutes, and letting the devices communicate nearby.
systime=1611521922 ch=45 LAP=9e8b33 err=1 clkn=959916 clk_offset=233 s=-63 n=-55 snr=-8
systime=1611521922 ch=45 LAP=9e8b33 err=0 clkn=959920 clk_offset=235 s=-63 n=-55 snr=-8
systime=1611521922 ch=77 LAP=9e8b33 err=1 clkn=960009 clk_offset=3351 s=0 n=-55 snr=55
systime=1611521922 ch=77 LAP=9e8b33 err=0 clkn=960013 clk_offset=3357 s=0 n=-55 snr=55
Survey Results
??:??:E2:C9:64:A7
??:??:4D:F1:EC:98
??:??:??:EE:70:86
??:??:50:6D:E9:76
??:??:??:BC:F9:02
??:??:50:6C:4A:42
??:??:D9:22:E7:38
??:??:??:91:7C:05
Additionally, you'll see some lines in the output that look like this:
UAP = 0x1a found after 4 total packets.
Note: If you're playing around with UAP discovery for the first time, it's helpful to do it with Bluetooth devices for which you already know the MAC so that you can easily confirm what you're seeing.
So to summarize, the general process from recon to sniffing goes like this:
- Use
ubertooth-rx
orubertooth-rx -z
to identify LAPs for potential target devices. - Use
ubertooth-rx -l <LAP>
to calculate the UAP byte for a given LAP, if you don't already have it. - Use
ubertooth-rx -u <UAP> -l <LAP> -q output.pcap
to perform a packet capture using a provided LAP and UAP.
So now that? Well, now you have a pcap file containing Bluetooth traffic that you can hopefully glean some useful information out of, even if it's just the fact that the communications are encrypted ;)
If you know the full BD_ADDR
, you can also feed it to ubertooth-btle
in order to capture Bluetooth LE communications:
ubertooth-btle -f c4:d0:3e:31:56:a6 -c ~/Desktop/deviceX.pcap
Spectrum Analyzer
I ran into some issues getting some of the Ubertooth tools working correctly, namely ubertooth-specan-ui
. What I gathered from the error messages is that this tool utilizes PyQT5
, which was the messiest part to troubleshoot, but you should be able to get it working by follwing these steps:
- IMPORTANT: Download and install the latest
XCode
command-line tools from here. Before I figured out this step, the building of some ofPyQT5
's dependencies failed. - Upgrade your
pip3
:
python3 -m pip install --upgrade pip
- Install
numpy
:
brew install numpy
- Finally, install
PyQT5
:
pip3 install numpy pyqt5
At that point, I was able to get it working by browsing to the specan_ui
and running the tool from there:
cd ~/tools/ubertooth/ubertooth-2020-12-R1/hosts/python/specan_ui
python ./ubertooth-specan-ui
Note: You'll need to substitute the above for the location where you put the ubertooth directories.
I didn't find this visualization to be actually useful for anything, but it looks pretty cool.
Wireshark
One cool thing you can do with this device is directly capture Bluetooth LE traffic using Wireshark. You can accomplish this by creating a named pipe
using mkfifo
, piping the output of ubertooth-btle
to it, and then using that active pipe as a Wireshark interface to capture traffic in realtime.
- Create a named pipe:
mkfifo /tmp/pipe
- Add your
/tmp/pipe
named pipe to with Wireshark:
Capture -> Options -> Manager Interfaces -> Pipes -> Add New Pipe
- Send tthe output from
ubertooth-btle
to your named pipe:
ubertooth-btle -f -q /tmp/pipe
- Start capturing by selecting your pipe in Wireshark.
Note: Per the documentation, with recent Ubertooth firrmware, only advertisement packets will be captured by default. You can specify the address of a target device you want to sniff (once you've identified it) by running
ubertooth-btle -t aa:bb:cc:dd:ee:ff
.
That's all for now! Go forth and use this knowledge to eavesdrop on the many Bluetooth-enabled devices you might have filling the airwaves around your home.
Miscellaneous Commands / Cheat Sheet:
- Troubleshooting: reset the device:
ubertooth-util -r