TL;DR: Introducing usb-racer, a tool for pentesting Time-of-check/Time-of-use (TOCTOU) issues with USB storage devices.
usb-racer
One issue that we are always on the lookout for when performing an embedded assessment are TOCTOU situations. Typically, these involve conditions where the authenticity of data is verified and then modified by an attacker before being consumed by the device. For example, we recently completed an engagement where the device booted from a USB drive in order to perform firmware updates and included a script similar to the following to mount the root file system from the initrd:
#!/bin/sh
ROOT_IMG="..."
openssl dgst -sha256 -verify ${SIGNING_KEY} -signature "${ROOT_IMG}.sig" ${ROOT_IMG}
if [ $? -ne 0 ]
then
logger -p Error "Invalid signature on root filesystem."
exit -1
fi
mount ${ROOT_IMG} /new_root
#...
This is a classic TOCTOU flaw, where the root file system's signature is verified then the image is mounted. If we swap the data between the check and the mount, we will be able to defeat the verified boot system. To exploit this issue, we built usb-racer.
Usage
usb-racer comes with some built in tools to handle basic cases; more complex scenarios may require a custom script.
Basic Mass Storage Device
A no frills basic mass storage device is included and can be launched simply:
> usbracer-storage --block-size 512 /path/to/disk.img
It is not very fast, so the standard mass storage gadget is a better choice if you just need to emulate a mass storage device. The tool has some options that are useful such as:
-
--write
โ Controls the write behavior,ALLOW
,DENY
returns an error on writes,DROP
silently drops writes. -
--cow
โ A simple copy on write that saves writes to another file. Makes it easier to see what changes and revert back to the original file. -
--log
&--log-data
โ Creates a binary recording read, writes, and optionally the data for each operation. Can be read with theusbracer-log-dump
command.
TOCTOU Tool
The usbracer
tool implements the TOCTOU attack:
usage: usbracer [-h] (--toggle-image TOGGLE_IMAGE | --offset-override OFFSET_OVERRIDE OFFSET_OVERRIDE) [--block-size BLOCK_SIZE]
[--toggle-delay TOGGLE_DELAY] [--toggle-read-block TOGGLE_READ_BLOCK] [--debug-level DEBUG_LEVEL]
disk
positional arguments:
disk Path to disk image
options:
-h, --help show this help message and exit
--block-size BLOCK_SIZE
--toggle-delay TOGGLE_DELAY
Automatically toggles the disks after a delay (in seconds)
--toggle-read-block TOGGLE_READ_BLOCK
Toggle disks after a read on a specific block
--debug-level DEBUG_LEVEL
Second Image:
--toggle-image TOGGLE_IMAGE
A full image to toggle between
--offset-override OFFSET_OVERRIDE OFFSET_OVERRIDE
The next two arguments are used as an offset and a path, can be specified multiple times
There are a couple ways to specify the second/replacement image:
-
--toggle-image
โ Takes a path to a file the same size asdisk
and serves as the second image. When the toggle action happens all reads and writes get redirected to the second file. This is simple, easy to modify several files and directory structures, but can result in disk corruption. The OS typically has already cached a bunch of data, including metadata about the directory structure, which may cause issues. -
--offset-override
โ This takes two arguments an offset to replace the data with the contents of a file (e.g.--offset-override 425 ~/malicious.bin
). When compared to swapping the whole image, this method uses less disk space and risk of corruption is much smaller as reads and writes outside of the targeted blocks are unaffected. Takes a little more work to setup as you need to know the blocks in the file you are targeting, and if the file is fragmented you may need to patch up multiple offsets. Also, it is not easy to change the directory structure. The--offset-override
argument can be specified multiple times to target multiple files or a fragmented file.
When to trigger the attack can also be controlled. The tool offers three ways:
-
Keyboard Toggle
โ Hitting enter will toggle (enable/disable) the TOCTOU attack. This option is always on, even if one of the other options is picked. -
--toggle-delay
โ This option will automatically toggle after the specified seconds. -
--toggle-read-block
โ This option watches read operations and will toggle after reading the specified block. In terms of a TOCTOU, we would watch the last block in the targeted file. After the "check" operation reads it, we swap the underlying data for the usage operation.
More complex scenarios can be implemented by creating your own script.
Disk Caching
There is an important wrinkle in swapping underlying storage blocks: OS level disk caching. OSs will heavily cache disk IO, so after the first read (to verify the integrity of the data), there may not be a second read when the system consumes the data. So, some strategizing and conditioning may be necessary to craft a working exploit. Here are some tips:
- Target Larger Files โ Processing large amounts of data will cause cache entries to be evicted. For example, a disk image of a root filesystem is unlikely to be fully cached during the signature verification step, while a configuration file a few hundred bytes long is easily cached.
- Target Less Frequently Used Files โ If the time between accesses is large then it gives the cache a chance to clear. For example, if a file is verified on boot but then not consumed until much later, the rest of the boot process or normal operations could have evicted the file from the cache.
- Force Resource Consumption โ Is there a web server? Firmware update? Network protocol that can be leveraged to allocate memory? Basically, we want to put a resource load on the device. The more memory we can tie up the less will be available for caching. The more IO we can force the faster the cache will turn over.
About the Author
Michael Milvich is a Fellow at Anvil Secure. Prior to joining Anvil, Michael worked as a Senior Principal Consultant IOActive Inc, and as a Cyber Security Researcher at Idaho National Laboratory (INL). Michael got his start in embedded security hacking SCADA and ICS systems and later broadened to encompass a wide variety of embedded systems across many industries. Michaelโs strong technical background combined with his years of general consulting have been utilized to assist some of the leading technologies and most advanced security groups in improving their security posture.