Back to Insights

BeagleBone, nu-map and preparing for USB fuzzing

29/07/2021 Article

BG

USB fuzzing is pretty low-level and can require a fair bit of brain-bending to get your head around what is needed and what the results are. Here we discuss how USB fuzzing can be done. We show the setup and installation of the BeagleBone Black hardware device and the open-source software nu-map, a decendant of NCC Group’s umap.

TL;DR; if you have a working BeagleBoard Black and you just want the instructions, go to step five “Build a patched Kernel” below. The rest is stuff you might already know.

There are lots of reasons why doing hardware fuzzing of USB is a bad idea, but occasionally, it is the only way of achieving the objectives. As a result, there are lots of discussions about alternatives, and very few articles written about how to actually do it in hardware that are accessible by mere mortals. This post aims to show exactly what is required with the hardware and software that is available today.

To recap why you shouldn’t do this, there are a few big reasons:

  • Difficult to see what data is actually sent and received to and from the target. This makes it hard to actually analyse the results of the fuzzing
  • It is slow
  • Difficult to integrate the hardware with fuzz test-case generators

There is a bigger discussion about the relative merits of software-based USB fuzzing by F-Secure and it talks about the potential alternatives. If you find a circumstance where nothing else will do (or you just want to play), the below should help you get started.

The steps needed:

  • Buy the hardware
  • Flash the BeagleBone to the latest version of Debian
  • Update it
  • Mount an SD card
  • Build a patched Kernel
  • Build the GadgetFS kernel moduleQQQ
  • Install nu-map
  • Start Gadget-FS
  • Start nu-map
  • Start the Kitty fuzzer

Should be a breeze…

Purchasing

First step is hard. You have to press the “Pay” button on a web site and wait. Oh how the waiting hurts. You can buy these from a variety of places depending on where you are in the world.

Flashing the firmware

This should be straight forward, but, I found that the mechanism for flashing the firmware didn’t work as directed, I am sure it does if you have more patience that I do, but… Instead if you edit a boot file you can comment out a function that always tried to flash the on-board eMMC contents with whatever is on the SD card. Potentially dangerous if you leave it in place, but means you don’t need ti guess if it is flashing correctly or not. I suggest you undo this once flashing is complete (some builds do this automatically).

Change the file /boot/uEnv.txt

So that the following line is uncommented:

cmdline=init=/opt/scripts/tools/eMMC/init-eMMC-flasher-v3.sh

Download the latest Debian image from the BeagleBoard people and write that to your SD card. Pop that shiny SD card into your BeagleBone Black and turn it on. It should flash a bit, then all four LEDs will stay on together for a few seconds and then it will start the flashing process. During this you might not get any LED lights or indication that much is going on, or you might get the LEDs flashing in sequence. Eventually all the LEDs will turn off and you know you are good to take the SD card out and reboot.

Software update

Step three is the usual Debian update commands plus one:

sudo apt update && sudo apt upgrade -y
cd /opt/scripts
git pull

Build a patched Kernel

Build this on your local machine, not on the BeagleBone. It can’t pull the Git Repo for the Kernel as it is too large. This is a very long stage, so get ready to run the set of commands and go and get a cup of tea or something…

The nu-map project documentation specifically references Kernel 4.7. At first I didn’t question this as I didn’t want to stray from instructions but that led to a nightmare of Kernel building and dependency resolution, specifically when it comes to building the GedgetFS Kernel module later on.

The trick here is to search for all Apt-installable Linux headers packages (in the same major version as otherwise it will take weeks to complete the search) and work out which one you can build from Robert Nelson’s repo. In my example, I found that Kernel v4.19 had a bone architecture available and the repo had no missing dependencies (check by trying to build each option until you find one that works).

On the BeagleBone search like so:

sudo apt search linux-headers-4
...
SNIP
...
linux-headers-4.19.182-bone63/unknown 1buster armhf

Then on your local machine build the Kernel:

git clone https://github.com/RobertCNelson/bb-kernel.git
cd bb-kernel
git checkout am33x-v4.19 # change this to your Kernel choice from above
sudo apt install -y fakeroot gettext bison flex libmpc-dev
./build_deb.sh
scp deploy/linux-image-*.deb debian@[IP]:.

You might notice that I chose to use the “build_deb.sh” script instead of the “build_kernel.sh” script. This is because I am being lazy and want apt to install it for me when it is done. Also, I *believe* this is an easy way to stop auto updates from upgrading the Kernel in the future if you do an apt upgrade.

Once it has finished creating the Kernel and you have transferred the Deb packages to the BeagleBone, install it and the relevant headers with:

sudo apt install -y ./linux-image-*.deb
sudo apt install -y linux-headers-[VERSION]
sudo reboot

Just in case it isn’t clear, don’t install the Linux headers package made with the custom kernel build script as it gets compiled for the local workstation’s architecture, not for the BeagleBone’s architecture and is therefore useless.

Install nu-map

Let’s install nu-map itself.

git clone https://github.com/usb-tools/nu-map
cd nu-map
sudo python3 setup.py install

Build the GadgetFS kernel module

There are some typos in the original documentation. They can take a while to spot. There is also a patch needed for the inode.c file as later Kernels don’t appear to have CURRENT_TIME support. The fix is to swap CURRENT_TIME for current_time(inode). The following should actually work.

cd ~/nu-map/gadget
cp inode.c.4.6_and_up inode.c
nano inode.c # edit the reference to "CURRENT_TIME" to be "current_time(inode)"
sudo make modules
sudo cp gadgetfs.ko /root

Start Gadget-FS

This should just be a case of running the script provided in the nu-map repo:

sudo ~/nu-map/gadget/start_gadgetfs.sh

What comes next?

Well this is where the USB fuzzing really gets going and is a topic in its own right. Here you will likely need nu-map and KittyFuzzer. But that depends largely on what you are trying to achieve. Good luck!

Register interest or Get in touch