Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/awslabs/snapchange

Lightweight fuzzing of a memory snapshot using KVM
https://github.com/awslabs/snapchange

Last synced: about 1 month ago
JSON representation

Lightweight fuzzing of a memory snapshot using KVM

Awesome Lists containing this project

README

        

# Snapchange

Lightweight fuzzing of a memory snapshot using KVM

Snapchange provides the ability to load a raw memory dump and register state into a
KVM virtual machine (VM) for execution. At a point in execution, this VM can be reset to its initial
state by resetting the dirty pages found by KVM or pages manually dirtied by a
fuzzer.

## Quick Links:

* [Cookbook](./docs/COOKBOOK.md) provides examples [fuzz](./docs/COOKBOOK.md#fuzz-commands), [trace](./docs/COOKBOOK.md#trace-commands), [coverage](./docs/COOKBOOK.md#coverage-commands), [minimize](./docs/COOKBOOK.md#minimize-commands), and [project](./docs/COOKBOOK.md#project-commands) command line utilities
* [Taking a snapshot with QEMU](./qemu_snapshot/README.md)
* [Architecture](./docs/ARCHITECTURE.md)
* [Fuzzer Lifecycle](./docs/FUZZ_FUNCTION_LIFECYCLE.md)

## Tutorials

* [Tutorial 1 - Basic Usage](./examples/01_getpid/README.md)
* [Tutorial 2 - `LibTIFF` with ASAN](./examples/02_libtiff/README.md)
* [Tutorial 3 - `FFmpeg` with custom mutator](./examples/03_ffmpeg_custom_mutator/README.md)
* [Tutorial 4 - Syscall fuzzer](./examples/04_syscall_fuzzer/README.md)
* [Tutorial 5 - Redqueen](./examples/05_redqueen/README.md)

# Aspirations

* Replay a physical memory and register state snapshot using KVM
* Parallel execution across multiple cores
* Provide a set of introspection features to the guest VM
* Real-time coverage state via breakpoint coverage
* Real-time performance metrics of fuzzer components
* Provide fuzzing utilities such as single-step debug tracing, testcase minimization, and testcase coverage
* Input abstraction to allow custom mutation and generation strategies

# Example:

#### Create a target fuzzer from the fuzzer template

```console
$ cp -r -L fuzzer_template your_new_fuzzer
```

#### Modify `your_new_fuzzer/create_snapshot.sh` to take a snapshot of your target

#### Update `src/fuzzer.rs` to inject mutated data into the guest VM

```rust
#[derive(Default)]
pub struct TemplateFuzzer;

impl Fuzzer for TemplateFuzzer {
// The type of Input being fuzzed. Used to know how to generate and mutate useful inputs.
type Input = Vec;
// The starting address of the snapshot
const START_ADDRESS: u64 = 0x402363;
// The maximum length of mutated input to generate
const MAX_INPUT_LENGTH: usize = 100;

fn set_input(&mut self, input: &Self::Input, fuzzvm: &mut FuzzVm) -> Result<()> {
// Write the mutated input into the data buffer in the guest VM
fuzzvm.write_bytes_dirty(VirtAddr(0x402004), CR3, &input)?;
Ok(())
}

fn reset_breakpoints(&self) -> Option<&[BreakpointLookup]> {
Some(&[
// Reset when the VM hits example1!main+0x123
BreakpointLookup::SymbolOffset("example1!main", 0x123)
])
}
}
```

#### Start fuzzing with 16 cores

```console
$ cargo run -r -- fuzz -c 16
```

# Implementation

Quick usage of terms for this README:

* Hypervisor: The target agnostic code executing the snapshot in KVM
* Fuzzer: The target specific code used to modify and monitor the guest for a target
specific fuzz case

The hypervisor begins by mapping the physical memory file for each core requested. In
this way, each core has its own, unique copy of memory. The hypervisor then creates the
KVM guest and gives the guest this backing memory. This guest's register state is then
initialized with the given register state and execution of the guest is launched. The
hypervisor waits until the guest exits. Each exit is handled by the hyperisor and some
are passed to the fuzzer for target specific mutation, modification, or introspection. If
the handler of the exit signifies that the guest should be reset, the hyperisor exits the
run loop and resets the guest back to the original snapshot state and restarts the run
loop again.

Coverage of the guest is generated by using coverage breakpoints. A separate file with a
list of addresses to breakpoint can be given to the hypervisor. If any of these addresses
are hit, the address will be added to the coverage database and the instruction for that
address will be restored. In this way, the breakpoint will not be triggered again.

# Project directory

Snapchange leverages target specific project directories for configuration. This directory
is where input and output files and directories are placed. The following file
extensions/directories are used as inputs:

* `.physmem` - The file containing the raw, physical memory file
* Register file (one of the following)
- `.regs` - JSON register file containing the [register state](./docs/REGISTER.md)
- `.qemuregs` - Output from `info registers` from `qemu`

The full list of files and their uses in the project directory can be found [here](./docs/PROJECT_DIRECTORY.md)

# Debugging Trace

A full example of the debugging single-step trace can be found [here](./docs/DEBUG_TRACE.md).

```
ITERATION 604 0x00007ffff7ecb0d5 0x11115000 | libc-2.31.so!__GI___getpid+0x5 (0x7ffff7ecb0d5)
syscall
[0f, 05]
ITERATION 605 0xffffffff83a00000 0x11115000 | entry_SYSCALL_64+0x0 (0xffffffff83a00000)
swapgs
[0f, 01, f8]
ITERATION 606 0xffffffff83a00003 0x11115000 | entry_SYSCALL_64+0x3 (0xffffffff83a00003)
mov qword ptr gs:[0xa014], rsp
[None:0x0+0xa014=0xa014]]
RSP:0x7fffffffeb78 -> example1!main+0x19 (0x55555555514e)-> 0xff8458b48f44589
[65, 48, 89, 24, 25, 14, a0, 00, 00]
ITERATION 607 0xffffffff83a0000c 0x11115000 | entry_SYSCALL_64+0xc (0xffffffff83a0000c)
nop
[66, 90]
ITERATION 608 0xffffffff83a0000e 0x11115000 | entry_SYSCALL_64+0xe (0xffffffff83a0000e)
mov rsp, cr3
RSP:0x7fffffffeb78 -> example1!main+0x19 (0x55555555514e) -> 0xff8458b48f44589
CR3:0x11115000
[0f, 20, dc]
```

# Snapshots

Information about obtaining a snapshot via `VirtualBox` or `QEMU` are below:

* [VirtualBox](./docs/VIRTUALBOX_SNAPSHOT.md)
* [QEMU](./qemu_snapshot/README.md)

The examples include a `make_example.sh` (like [example 1](./examples/01_getpid/make_example.sh)) script which goes a full snapshot from scratch. These
examples can be used as a template for other targets for reproducible snapshots.

# Documentation and clippy

```
make all
cargo doc --open
```

# Where to begin reading?

The [HACKING](./HACKING.md) provides a few higher level locations in the code base to start
understanding the system.

## Security

See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.

## License

This project is licensed under the Apache-2.0 License.