Home

Awesome

(c) Airbus 2021, sduverger

GUSTAVE - Embedded OS kernel fuzzer

What is it ?

GUSTAVE is a fuzzing platform for embedded OS kernels. It is based on QEMU and AFL (and all of its forkserver siblings). It allows to fuzz OS kernels like simple applications.

Thanks to QEMU, it is multi-platform. One can see GUSTAVE as a AFL forkserver implementation inside QEMU, with fine grain target inspection.

What are the supported kernels ?

GUSTAVE has mainly been designed to target embedded OS kernels. It might not be the best tool to fuzz large and complex kernels as found in Windows, Linux or MACOS.

However if you have a target under the hood which can be prepared with one or two applications to boot without any user interaction, it might be interesting to give GUSTAVE a try.

How does it work ?

The afl-fuzz tool, from the AFL project, is used to automatically fuzz your target. However, AFL can't directly fuzz an OS kernel and expects its target to directly parse the generated test cases.

To make it short, afl-fuzz will run QEMU with GUSTAVE integration as its target. In turn, GUSTAVE will handle :

As AFL/QEMU-user mode found in AFL++ project, GUSTAVE implements QEMU TCG IR level binary instrumentation for code coverage.

However, you can choose to disable it and rebuild your target kernel code with only specific parts being subject to code coverage analysis. You will have to inject AFL shims at build time to update the trace bitmaps though. That was our initial approach (see Publications).

Less prevalent in existing solutions, GUSTAVE does not care about monitoring kernel panics. We consider them managed errors, and want to discover illegal behaviors that did not trigger any alarm.

For that purpose GUSTAVE relies on a O(1) byte oriented memory filtering bitmap to detect illegal accesses from the kernel. There might be large debate about defining what could be considered illegal from the kernel point of view. But in restricted embedded, highly deterministic environments you might find yourself comfortable defining legitimate memory areas for your firmware and tracking out-of-bound accesses.

How does it compare to existing solutions ?

There exists comparable approaches, such as:

GUSTAVE design choices imply the following differences:

However, you still need to tell GUSTAVE:

Current status ?

Host hardware

For now only x86 host is supported, as many working environments are based upon this architecture we don't consider it a prohibiting limitation.

The restriction comes from the way we initially implemented memory filtering backend at tcg-target level for the QEMU load/store fast-path. The recent TCGPlugin memory callbacks architecture might be an alternative approach to support any host.

Guest Hardware

We have implemented and tested Intel x86 and PowerPC support. The GUSTAVE implementation is architecture independent. If you can run your target with QEMU, you can fuzz it with GUSTAVE with little effort.

We provide example Intel 440FX and PowerPC PREP boards with GUSTAVE integration. The implementation of your own board is really easy, and consist in wrapping the MACHINE_INIT function for a given architecture.

We also added support for x86 and PowerPC GUSTAVE instrumentation shims to afl-gcc, in case you don't want to proceed with TCG binary instrumentation.

Example target

We provide POK micro-kernel specific developments:

How to use it ?

You will need to:

Read the manual for the POK target.

Publications

Material from different talks on GUSTAVE can be found at https://airbus-seclab.github.io/.