▄▄·       ·▄▄▄▄  ▄▄▄ .• ▌ ▄ ·. ▄• ▄▌ ▄▄·  ▄ .▄
▐█ ▌▪▪     ██▪ ██ ▀▄.▀··██ ▐███▪█▪██▌▐█ ▌▪██▪▐█
██ ▄▄ ▄█▀▄ ▐█· ▐█▌▐▀▀▪▄▐█ ▌▐▌▐█·█▌▐█▌██ ▄▄██▀▐█
▐███▌▐█▌.▐▌██. ██ ▐█▄▄▌██ ██▌▐█▌▐█▄█▌▐███▌██▌▐▀
·▀▀▀  ▀█▄▀▪▀▀▀▀▀•  ▀▀▀ ▀▀  █▪▀▀▀ ▀▀▀ ·▀▀▀ ▀▀▀ ·
    
android, iOS, web :: hacking + reverse engineering

Sniffing Bluetooth Traffic with the Ubertooth One on MacOS Big Sur

hacking bluetooth ubertooth wireless big sur

Learn 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 via homebrew).

  • A working Ubertooth One connected via USB.

Setup

  1. 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"
  1. Install the dependencies you need to build the Ubertooth libraries and tools:
-> % brew install libusb wget cmake pkg-config
  1. 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
  1. 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
  1. 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:

  1. Use ubertooth-rx or ubertooth-rx -z to identify LAPs for potential target devices.
  2. Use ubertooth-rx -l <LAP> to calculate the UAP byte for a given LAP, if you don't already have it.
  3. 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:

  1. IMPORTANT: Download and install the latest XCode command-line tools from here. Before I figured out this step, the building of some of PyQT5's dependencies failed.
  2. Upgrade your pip3:
python3 -m pip install --upgrade pip 
  1. Install numpy:
brew install numpy
  1. 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.

  1. Create a named pipe:
mkfifo /tmp/pipe
  1. Add your /tmp/pipe named pipe to with Wireshark:
Capture -> Options -> Manager Interfaces -> Pipes -> Add New Pipe
  1. Send tthe output from ubertooth-btle to your named pipe:
ubertooth-btle -f -q /tmp/pipe
  1. 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

References: