Open source keystroke injector implementation on the Fomu FPGA board

Published:

Topics: Open FPGA, Open source tools

At Antmicro we work with a large variety of FPGA chips, starting from very large FPGAs we’re using for prototyping ASIC systems, to super small, resource constrained devices to be deployed at the very edge.

One of such devices is the tiny and open source Fomu, containing a Lattice iCE40 FPGA chip with a set of peripherals such as pads meant for touch input and SPI Flash for storage, fitting inside a USB port. Thanks to its small size, hackability, availability of DFU bootloader, good documentation, Renode and Verilator simulation support and ability to work as any USB device, Fomu is a perfect platform for developing projects using USB, such as pen test tools.

In this blog note we will present the details of one of our latest projects called Fomu keystroke injector, which reimplements the functionality of the USB Rubber Ducky pen test tool using only the Fomu FPGA board.

Why Fomu

USB Rubber Ducky is a small USB keyboard emulator built with Atmel’s AT32UC3B1256 microcontroller, capable of sending preprogrammed keystroke sequences to the USB host. It uses a microSD card as a storage for payloads and fits inside a typical pendrive case. Because of its basic user interface requiring only a single button and compatibility with any operating system supporting USB keyboards, it seemed like a good project to reimplement using the miniature Fomu hardware, and a real-life use case for the open FPGA tooling that Antmicro has been developing with Google and other customers and partners in the CHIPS Alliance.

Fomu’s FPGA chip, the Lattice iCE40 UP5K, is very well supported by a fully open source toolchain, which allows much more flexibility for HW/SW co-development projects targeting this family of FPGAs. Despite seemingly limited capabilities when compared to other FPGA families, the availability of open source tooling enabled a diverse ecosystem of open source CPUs and I/O peripheral cores. One example is VexRiscv, a robust and configurable RISC-V implementation scaling from very small to multi-core, Linux-capable systems.

The main efforts of the community around Fomu are aimed at popularizing the use of Fomu for different applications, mostly by contributing Fomu support to open source frameworks such as LiteX, used for building complete SoCs on FPGAs, and testing frameworks such as Renode, enabling hybrid simulation with components partially running on Fomu and partially in an emulator.

System overview

To create a keyboard injector with Fomu, it was necessary to not only implement the firmware itself, but also prepare the SoC gateware on which such firmware would run. The LiteX SoC building framework was used for building the gateware from the included IP cores, such as the VexRiscv CPU core and the LiteSPI controller used for communication between the FPGA and the SPI Flash chip. To support USB communication, a USB full-speed controller called ValentyUSB was used. Additional components such as the RGB LED driver interface and touch input I/O were implemented using Migen hardware design language, which is also used as a basis for the LiteX framework.

The firmware was implemented in C language as a bare metal application, using the TinyUSB library, which is a USB stack implementation for embedded devices. Thanks to its easy to use API, it was possible to quickly implement sending of HID events, which was required for the keyboard emulation functionality. TinyUSB was also used for adding support for DFU updates, allowing to update flash memory contents with injector updates or payload scripts.

Diagram depicting Fomu software, gateware and hardware

Building and usage

This project’s source code has been recently released on Antmicro’s GitHub. Assuming you have the RISC-V GCC and the iCE40 FPGA toolchains installed on your system, you can build your own Fomu keystroke injector by cloning the repository and running the bitstream.py script in the hw directory, which will take care of building both the gateware and software. Then the bitstream binary from hw/build/kosagi_fomu_pvt/kosagi_fomu_pvt.dfu can be installed on the Fomu using dfu-util: dfu-util -D kosagi_fomu_pvt.bin. If you have updated the Foboot bootloader to version 2.0.4, then after plugging Fomu into the PC next time the keystroke injector will run automatically. It is ready to use when the onboard RGB LED lights up green.

Fomu keystroke injector screenshot

The Fomu keystroke injector, similarly to the USB Rubber Ducky, uses Duckyscript, which is a simple scripting language used for automating common keyboard operations, such as typing text strings or sending shortcuts. This means that scripts made for USB Rubber Ducky can be used with the Fomu keystroke injector without any modifications.

Let’s start with writing and encoding an example script. Write the following commands in a text file:

STRING Hi!
DELAY 250
STRING I am Fomu Keystroke Injector.
DELAY 250
STRING Nice to meet you!
DELAY 1000
CTRL-ALT DEL

To encode the script to a binary file, you need to use a Duckyscript encoder called duckencoder, which can be downloaded from the USB Rubber Ducky wiki.

Assuming that script.txt contains the previously written Duckyscript commands, by running:

java -jar duckencoder.jar -i script.txt -o script.bin

you will get a file called script.bin, which includes keystroke sequences that can be downloaded to the injector’s storage. The encoded binary can be sent to the keystroke injector using the dfu-util program. To switch the keystroke injector into programming mode, run:

dfu-util -e

The LED on Fomu will turn red for half a second, then green again, which means that the keystroke injector switched to programming mode. You can send the script using dfu-util -a0 -D script.bin.

Once programmed, the injector is ready to use: simply plug in Fomu to the PC you want to run the script on, wait until the LED starts glowing green and then bridge the two leftmost pads on Fomu - the injector will read the previously loaded script and start executing it by sending keystrokes to the computer. In our example one line of text will be written in the currently open window and then the keyboard shortcut will be executed.

Happy hacking!

Open source for FPGA development

At Antmicro, we’re heavily involved in developing FPGA systems, and thanks to our open source methodology and versatile contributions to open toolchains, IP and software we help companies working in areas such as security, testing, defense and space to benefit from the transparency and the wide range of features that an open source approach to FPGAs offers. If you’re looking to develop your next FPGA project using more software-driven workflows, reach out to us at contact@antmicro.com.

See Also: