Skip to content

vul337/TrigFuzz

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TrigFuzz

First page of the TrigFuzz paper

Official code repository for the research paper TrigFuzz: Triggering Conditions Guided Directed Fuzzing (IEEE S&P 2026). TrigFuzz is a directed fuzzing tool that leverages LLMs to extract vulnerability triggering conditions for PoC generation.


Citation

@inproceedings{chen2026trigfuzz,
  author = {Chen, Yiyang and Gui, Nuoqi and Wang, Long and Chen, Longfei and Shi, Xuanqing and Cao, Xi and Zhang, Chao},
  booktitle = {2026 IEEE Symposium on Security and Privacy (SP)},
  title = {{TrigFuzz: Triggering Conditions Guided Directed Fuzzing}},
  year = {2026},
  volume = {},
  ISSN = {2375-1207},
  isbn = {979-8-3315-6065-2},
  pages = {3357-3375},
  abstract = {Directed fuzzing aims to trigger specific vulnerabilities by steering execution towards predefined target code. However, state-of-the-art directed fuzzers predominantly focus on reaching the target code quickly, often lacking effective follow-up strategies to satisfy the vulnerability constraints required to trigger them. We find that this can be a key factor limiting their performance in directed fuzzing tasks such as crash reproduction. The main challenge is that existing directed fuzzers cannot accurately identify the triggering conditions of target vulnerabilities and effectively exploit them to guide fuzzing. To address this challenge, we propose TrigFuzz, a directed fuzzing solution guided by triggering conditions. Our approach leverages pre-trained large language models (LLMs) to automatically generate the triggering conditions of target vulnerabilities. We design a formalized representation for generated triggering conditions, along with a novel dynamic triggering validation technique to verify their correctness. The verified conditions are further transformed into ``triggering distance'' metrics that serve as fuzzing runtime feedback to guide seed scheduling and mutation strategies, enabling directed fuzzing to effectively generate vulnerability-triggering test cases. Our evaluations demonstrate that TrigFuzz can generate high-quality triggering conditions for 96.67% of target vulnerabilities and outperform state-of-the-art directed fuzzers with over a 1.72x speedup in reproducing target vulnerabilities on the benchmark Magma. Lastly, we detected 7 previously unknown vulnerabilities with 2 CVE IDs assigned in well-tested real-world software using TrigFuzz.},
  keywords = {},
  doi = {10.1109/SP63933.2026.00156},
  url = {https://doi.ieeecomputersociety.org/10.1109/SP63933.2026.00156},
  publisher = {IEEE Computer Society},
  address = {Los Alamitos, CA, USA},
  month = {May},
}

Release Options

This release contains two usable paths:

option directory purpose
AFLGo based TrigFuzz engines/aflgo-trigfuzz Paper-aligned AFLGo implementation with triggering-distance scheduling as the default. Triggering byte-aware mutation is available as an optional config.
Selective AFL++ based TrigFuzz engines/aflplusplus-selective AFL++ implementation with TrigFuzz feedback and conservative SelectFuzz-style selective instrumentation for better Magma performance in our local evaluation.

The shared Python tooling lives in trigfuzz/. The target-side AFLGo runtime header is distance.h; the AFL++ runtime header is engines/aflplusplus-selective/include/trigfuzz-distance.h.

Environment

The release workflow was tested on Ubuntu 22.04.5 LTS with:

  • Python 3.10;
  • GCC 11;
  • LLVM/Clang 14;
  • GNU make;
  • CMake;
  • the OpenAI Python SDK for TC generation;
  • pytest for the Python test suite.

Install the Python dependencies:

python3 -m pip install openai pytest

Build dependencies vary by engine:

  • AFLGo based TrigFuzz uses the bundled AFLGo/AFL source tree and builds with make clean all.
  • Selective AFL++ based TrigFuzz uses the bundled AFL++ source tree and builds with make source-only.
  • AFL++ gcc-plugin mode needs GCC plugin development headers.
  • AFL++ Nyx mode is optional and requires Rust; the normal source-instrumentation build does not require Nyx.

Runtime environment variables used by the workflow:

variable purpose
OPENAI_API_KEY API key for TC generation.
OPENAI_MODEL Optional model override for TC generation.
OPENAI_API_BASE_URL / OPENAI_BASE_URL Optional OpenAI-compatible API base URL.
TRIGFUZZ_AFL Optional override for the AFLGo based afl-fuzz binary.
TRIGFUZZ_AFL_GCC Optional override for the AFLGo based afl-gcc compiler wrapper.
AFL_TRIG_ENABLE_BYTE_AWARE_MUTATION Opt-in switch for the triggering byte-aware mutation stage.
AFL_TRIG_MUTATION_MODE Optional byte-aware mutation strategy: diff, scan, or hybrid.
AFL_TRIGFUZZ_ENABLE Enables TrigFuzz feedback in the AFL++ based engine.
AFL_TRIGFUZZ_INS_NUM Number of TCU distance slots for the AFL++ based engine.
AFL_TRIGFUZZ_SEQ_NUM Number of TCU sequence groups for the AFL++ based engine.
AFL_TRIGFUZZ_SELECTIVE_FILE Selective instrumentation keep-list path for the AFL++ based engine.

Complete Workflow

1. Prepare a target directory

my-target/
  bug_report.json
  source/
    parser.c
    parser.h
  seeds/
    seed0
  build.sh              # optional, for non-single-file targets
  funcs.json            # optional, function-name -> numbered source map

bug_report.json should identify the vulnerability type and target crash or bug location:

{
  "type": "heap-buffer-overflow",
  "crash_points": ["line 5973 in tif_dirread.c"],
  "summary": "Short bug description and relevant constraints"
}

For small targets, putting the relevant C/C++ files under source/ is enough. For larger targets, funcs.json lets the progressive TC generation agent fetch extra function bodies when the model asks for them.

2. Run TC generation

Install the OpenAI SDK if needed and provide an API key:

python3 -m pip install openai
export OPENAI_API_KEY=...
# optional
export OPENAI_MODEL=gpt-5
export OPENAI_API_BASE_URL=...

Generate candidate triggering-condition units:

cd /root/TrigFuzz
python3 -B -m trigfuzz.tcgen my-target --k 3 --out my-target/tcus.json

For large projects, seed the first prompt with specific files:

python3 -B -m trigfuzz.tcgen my-target \
  --source libtiff/tif_dirread.c \
  --source libtiff/tif_dir.h \
  --k 3

The output is tcus.json. It uses explicit distance_expr fields, which are compiled directly into distance_instrument(...).

3. Review generated TCUs

Before fuzzing, inspect tcus.json for:

  • correct loc line numbers;
  • safe distance_expr arithmetic using helpers like tf_gt, tf_sub_num, and tf_bool;
  • sensible seq order for multi-stage bugs;
  • DNF grouping through conj.

See docs/TCU_FORMAT.md.

4. Build the AFLGo based engine

cd /root/TrigFuzz/engines/aflgo-trigfuzz/afl-2.57b
make clean all

5. Fuzz with generated TCUs

cd /root/TrigFuzz
python3 -B -m trigfuzz.driver my-target \
  --skip-llm \
  --quick-dirty \
  --budget 3600

--skip-llm means the driver uses the reviewed my-target/tcus.json. The driver instruments source/, builds a target binary, and runs the patched AFLGo fuzzer with -z exp -c 10m; --quick-dirty passes -d.

For non-single-file targets, provide my-target/build.sh and pass --use-script. The script receives:

build.sh <instrumented-source-dir> <output-binary>

6. AFL++ selective path

For the selective AFL++ option, TCgen is the same. After reviewing tcus.json, insert the distance_instrument(...) calls using the AFL++ runtime header and compile with engines/aflplusplus-selective/afl-clang-fast under the selective instrumentation settings described in docs/USAGE_AFLPLUSPLUS_SELECTIVE.md.

Quick Start: AFLGo Based TrigFuzz

Build the AFLGo based engine:

cd engines/aflgo-trigfuzz/afl-2.57b
make clean all

Run the motivating example:

cd /root/TrigFuzz
python3 -B -m trigfuzz.driver examples/motivating \
  --skip-llm \
  --quick-dirty \
  --budget 60

The driver uses -z exp -c 10m by default and passes -d when --quick-dirty is set.

Triggering-distance scheduling is the default. To additionally enable the byte-aware mutation stage:

export AFL_TRIG_ENABLE_BYTE_AWARE_MUTATION=1

See docs/USAGE_AFLGO.md.

Quick Start: Selective AFL++ Based TrigFuzz

Build the AFL++ based engine:

cd engines/aflplusplus-selective
make source-only

Compile an instrumented target with the AFL++ compiler wrapper, include trigfuzz-distance.h, and enable selective instrumentation with a keep list:

export AFL_TRIGFUZZ_SELECTIVE=selectfuzz-like
export AFL_TRIGFUZZ_SELECTIVE_FILE=/path/to/selective-keep.txt
./afl-clang-fast -Iinclude -O1 -g -o target target.c

Run the fuzzer with TrigFuzz feedback enabled:

AFL_TRIGFUZZ_ENABLE=1 \
AFL_TRIGFUZZ_INS_NUM=64 \
AFL_TRIGFUZZ_SEQ_NUM=64 \
./afl-fuzz -i seeds -o out -m none -t 5000 -d -- ./target @@

See docs/USAGE_AFLPLUSPLUS_SELECTIVE.md.

Magma Demo Script

For the local Magma setup used during this release work, PDF010 is the default demo target. Use --bug to run a different local Magma target.

cd /root/TrigFuzz
bash scripts/magma/run_magma_demo.sh --budget 3600

Useful variants:

bash scripts/magma/run_magma_demo.sh --engine aflgo --budget 3600
bash scripts/magma/run_magma_demo.sh --engine aflpp-selective --budget 3600
bash scripts/magma/run_magma_demo.sh --bug PDF010 --engine both --budget 86400

The script writes a timestamped run directory under /root/magma-eval/trigfuzz-release-demo/. Before fuzzing, it replays the seed corpus against the target command line and uses a run-local filtered corpus, so the initial AFL dry run is not stopped by seeds that already crash or time out. It records this in seed-filter.meta and seed-filter.log, then creates summary.tsv by replaying saved crashes and checking for MAGMA_BUG.

TCU Metadata

Release metadata should provide distance_expr directly. Do not rely on old cond-only JSON for generated TCUs.

[
  {
    "cond": "nstrips - 1 > limit",
    "distance_expr": "tf_gt(tf_sub_num((double)nstrips, 1.0), (double)limit)",
    "loc": "line 5973 in tif_dirread.c",
    "seq": 0,
    "conj": 0,
    "w": 1.0,
    "kind": "numeric"
  }
]

cond is a readable label. distance_expr is what gets compiled into the target. See docs/TCU_FORMAT.md.

Tests

cd /root/TrigFuzz
python3 -m pytest -q
python3 -B -m py_compile trigfuzz/*.py

For fuzzer build checks:

make -C engines/aflgo-trigfuzz/afl-2.57b all
make -C engines/aflplusplus-selective source-only

About

Official code repository for the research paper *TrigFuzz: Triggering Conditions Guided Directed Fuzzing* (IEEE S&P 2026)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors