Skip to content
Security
Skill

/aflpp

Sets up and runs AFL++ for multi-core fuzzing of C/C++ projects built with afl-clang-fast or afl-gcc-fast. Covers instrumentation modes, parallel main and secondary campaigns, persistent mode, corpus minimization, and crash triage. Use when scaling fuzzing across cores, fuzzing

From plugin
trailofbits-skills
7.1k81 skills30 agents8 commands2 MCP
Install
$ npx -y skills add trailofbits/skills --skill aflpp --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/aflpp

Context preview

The summary Claude sees to decide when to auto-load this skill.

Sets up and runs AFL++ for multi-core fuzzing of C/C++ projects built with afl-clang-fast or afl-gcc-fast. Covers instrumentation modes, parallel main and secondary campaigns, persistent mode, corpus minimization, and crash triage. Use when scaling fuzzing across cores, fuzzing

SKILL.md

aflpp.SKILL.md
name: aflpp
type: fuzzer
description: "Sets up and runs AFL++ for multi-core fuzzing of C/C++ projects built with afl-clang-fast or afl-gcc-fast. Covers instrumentation modes, parallel main and secondary campaigns, persistent mode, corpus minimization, and crash triage. Use when scaling fuzzing across cores, fuzzing a mature C/C++ codebase, reading the afl-fuzz status screen, or moving on after libFuzzer has plateaued."

AFL++

AFL++ is a fork of the original AFL fuzzer that offers better fuzzing performance and more advanced features while maintaining stability. A major benefit over libFuzzer is that AFL++ has stable support for running fuzzing campaigns on multiple cores, making it ideal for large-scale fuzzing efforts.

When to Use

| Fuzzer | Best For | Complexity | |--------|----------|------------| | AFL++ | Multi-core fuzzing, diverse mutations, mature projects | Medium | | libFuzzer | Quick setup, single-threaded, simple harnesses | Low | | LibAFL | Custom fuzzers, research, advanced use cases | High |

**Choose AFL++ when:**

  • You need multi-core fuzzing to maximize throughput
  • Your project can be compiled with Clang or GCC
  • You want diverse mutation strategies and mature tooling
  • libFuzzer has plateaued and you need more coverage
  • You're fuzzing production codebases that benefit from parallel execution

Quick Start

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    // Call your code with fuzzer-provided data
    check_buf((char*)data, size);
    return 0;
}

Compile and run:

# Setup AFL++ wrapper script first (see Installation)
./afl++ docker afl-clang-fast++ -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz
mkdir seeds && echo "aaaa" > seeds/minimal_seed
./afl++ docker afl-fuzz -i seeds -o out -- ./fuzz

Installation

AFL++ has many dependencies including LLVM, Python, and Rust. We recommend using a current Debian or Ubuntu distribution for fuzzing with AFL++.

| Method | When to Use | Supported Compilers | |--------|-------------|---------------------| | Ubuntu/Debian repos | Recent Ubuntu, basic features only | Ubuntu 23.10: Clang 14 & GCC 13<br>Debian 12: Clang 14 & GCC 12 | | Docker (from Docker Hub) | Specific AFL++ version, Apple Silicon support | As of 4.35c: Clang 19 & GCC 11 | | Docker (from source) | Test unreleased features, apply patches | Configurable in Dockerfile | | From source | Avoid Docker, need specific patches | Adjustable via `LLVM_CONFIG` env var |

Ubuntu/Debian

Prior to installing afl++, check the clang version dependency of the packge with `apt-cache show afl++`, and install the matching `lld` version (e.g., `lld-17`).

apt install afl++ lld-17

Docker (from Docker Hub)

docker pull aflplusplus/aflplusplus:stable

Docker (from source)

git clone --depth 1 --branch stable https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
docker build -t aflplusplus .

From source

Refer to the [Dockerfile](https://github.com/AFLplusplus/AFLplusplus/blob/stable/Dockerfile) for Ubuntu version requirements and dependencies. Set `LLVM_CONFIG` to specify Clang version (e.g., `llvm-config-18`).

Wrapper Script Setup

Create a wrapper script to run AFL++ on host or Docker:

cat <<'EOF' > ./afl++
#!/bin/sh
AFL_VERSION="${AFL_VERSION:-"stable"}"
case "$1" in
   host)
        shift
        bash -c "$*"
        ;;
    docker)
        shift
        /usr/bin/env docker run -i \
            --privileged \
            -v ./:/src \
            --rm \
            --name "afl_fuzzing_$$" \
            "aflplusplus/aflplusplus:$AFL_VERSION" \
            bash -c "cd /src && bash -c \"$*\""
        ;;
    *)
        echo "Usage: $0 {host|docker}"
        exit 1
        ;;
esac
EOF
chmod +x ./afl++

The examples below use `docker` mode, apart from the system configuration commands that have to reach the host kernel. Swap in `host` to run any of them against an AFL++ installed on the machine itself. The wrapper joins everything after the mode argument into a single shell string, so quoting does not survive: an argument containing a space (`-x "my dict.dict"`) arrives word-split. Rename such files without spaces, or edit the wrapper for that run.

The missing `-t` is deliberate. `docker run -ti` aborts with `the input device is not a TTY` whenever stdin is not a terminal, which covers CI jobs and anything an agent or script drives. `afl-fuzz` notices there is no terminal and prints plain status lines in place of the full-screen UI. A program that insists on a terminal, such as `watch`, has to run on the host side of the wrapper instead. `$$` expands to the wrapper's PID, so parallel instances get distinct container names rather than colliding on a single `afl_fuzzing`. `docker ps` truncates the COMMAND column, so every row looks alike; use `docker ps --no-trunc` to tell the instances apart before stopping one.

**Security Warning:** The `afl-system-config` and `afl-persistent-config` scripts require root privileges and disable OS security features. Do not fuzz on production systems or your development environment. Use a dedicated VM instead.

System Configuration

Run after each reboot for up to 15% more executions per second:

./afl++ host afl-system-config

`afl-system-config` tunes the kernel it runs against, so run it on the machine that hosts the campaign. `./afl++ docker afl-system-config` reaches the same settings through the wrapper's `--privileged` container, which is the only route when AFL++ is installed via Docker alone.

For maximum performance, disable kernel security mitigations (requires grub bootloader, not supported in Docker):

./afl++ host afl-persistent-config
update-grub
reboot
./afl++ host afl-system-config

Verify with `cat /proc/cmdline` - output should include `mitigations=off`.

Writing a Harness

Harness Structure

AFL++ supports libFuzzer-style harnesses:

#inc
Read more
Ships withtrailofbits-skills

A Claude Code plugin marketplace from Trail of Bits providing skills to enhance AI-assisted security analysis, testing, and development workflows. Codex can load this marketplace through its Claude marketplace compatibility.

Get the whole plugin

Other skills on trailofbits-skills.