Thursday, January 2, 2014

Using Pure Python to Interact With an Ubertooth and Parse Bluetooth Baseband Data

In mid 2013 I gave a talk at a conference called Lockdown in Wisconsin.  During the talk I released a pure python library for parsing rudimentary bluetooth baseband data and interacting with an Ubertooth USB device.

The core Ubertooth C libraries and tools are much more robust (and faster), but the pure python implementation provided the following:

  • Quick deployment with no need for compiling.
  • Rapid prototyping of new and custom Ubertooth tools in python.
  • Quick and easy way to hook up an Ubertooth to mobile phones and other ARM devices.
  • Ubertooth data integration into my favorite python analytic libraries
  • An excuse for me to better understand the baseband layer and pyusb
Quick Notes:
  • you will need the pure python pyusb library installed to use pyubertooth 
Setup:
  • download the pyubertooth source code via git
  • the cli pyubertooth.py is in the pyubertooth/pyubertooth directory
git clone https://github.com/hackgnar/pyubertooth.git
cd pyubertooth/pyubertooth
For usage help:
python ubertooth.py --help
To log ubertooth data to a file (usable with ubertooth-rx -i filename):
python ubertooth.py --outfile=dump_filename.dump
To log ubertooth data directly to a file from bluetooth channel 60:
python ubertooth.py --outfile=dump_filename.dump --channel 60
To log 30 seconds worth of ubertooth data directly to a file :
python ubertooth.py --outfile=dump_filename.dump -t 30
To log 300 ubertooth usb data packets directly to a file :
python ubertooth.py --outfile=dump_filename.dump -n 300
To read raw ubertooth usb data from a dump file to std out:
python ubertooth.py --infile=dump_filename.dump
To display bluetooth packet information from a dump file (LAP, UAP, channel, etc):
python ubertooth.py --infile=dump_filename.dump --btbb
To display bluetooth packet information from a live stream (LAP, UAP, channel, etc):
python ubertooth.py --btbb

Sample python library usage:

To open a connection to an ubertooth device:
import ubertooth
ut = Ubertooth()
To access 5 data blocks from an ubertooth device as a python iterator:
import ubertooth
ut = Ubertooth()
for data in ut.rx_stream(count=5):
    print data
ut.close()
To access data blocks from an ubertooth device as a python iterator for 30 seconds:
import ubertooth
ut = Ubertooth()
for data in ut.rx_stream(secs=30):
    print data
ut.close()
To access data from an ubertooth device until ctrl-C is pressed:
import ubertooth
ut = Ubertooth()
try:
    for data in ut.rx_stream():
        print data
except KeyboardInterrupt:
    pass
ut.close()
An example of directly streaming ubertooth data to a file for 60 seconds:
import ubertooth
ut = Ubertooth()
f = open("dump_filename.dump", 'wb')
for data in ut.rx_stream(secs=60):
    f.write(data)
f.close()
ut.close()
Changing the channel on an ubertooth device:
import ubertooth
ut = Ubertooth()
ut.set_channel(66)


The libraries for this project only provide a fraction of Ubertooth's capabilities, and the baseband parser only provide LAP address and address parsing on baseband data.  As time goes on, I will try to expand the functionality and speed of the library.  I have also considered creating a python ctypes variant of the library to take advantage of the core Ubertooth C libaries.  A ctypes variant would be much faster while still providing a python API for interacting with the Ubertooth and its data.

The pure python libraries can be found in this github repo, but be warned, the code is ugly and needs some serious refactoring.

1 comment:

  1. Do you know if the data array given by self.rx_stream() comprises the RSSI value? (Here the Ubertooth-one USB hardware is set with `device.ctrl_transfer(0x40, 12, 2402+channel, 0)`; whereas in the ubertooth-specan-ui they compute the RSSI but the device is set `device.ctrl_transfer(0x40, 27, low_frequency, high_frequency)`.)

    ReplyDelete