← Creations

AutoFTE

A local crash-triage system that reduces a fuzzing corpus to evidence-backed findings a person can review.

2026activeSecurity Engineering / Developer ToolsPython · AFL++ · GDB · Sanitizers · SARIF · Ollama

Problem

Fuzzing is good at producing crashes. It is less helpful when a campaign leaves hundreds of files and the real question is which ones represent distinct bugs. I started AutoFTE in May 2025 because I wanted the work after a fuzzing run to be repeatable. Replaying inputs, reading sanitizer output, checking binary protections, and writing a useful report should not require a fresh manual investigation for every file.

Privacy also shaped the project. Crash inputs, binaries, and source context can be sensitive, so the analysis needed to stay on the local machine. An optional language model could help explain a finding, but it could not be allowed to replace the evidence.

Approach

The first version was a collection of AFL helper scripts, seed files, and crash-analysis commands. That was enough to prove the workflow, but the repository history shows the limit of that design. A generated proof-of-concept script was removed, the code was reorganized, and the older scripts were eventually replaced by a Python package and a single autofte command.

The key decision was to make deterministic analysis responsible for the facts. AutoFTE parses sanitizer reports, normalizes stack frames, groups related crashes, inspects ELF protections, and scores severity from the observed fault and mitigations. The local Ollama step receives that record plus source and disassembly context. Its output must match a schema and pass validators before it appears in a report. If no model is available, the rest of the pipeline still works.

Architecture

The pipeline moves from raw artifacts toward smaller, more reviewable units:

crash files
  -> sanitizer or GDB records
  -> normalized stack hashes
  -> deduplicated crash groups
  -> mitigation and crash-state analysis
  -> Markdown, HTML, JSON, SARIF, and CASR reports

This separation mattered as the project expanded. GDB crash-state analysis could add direct evidence such as instruction-pointer control without changing how reports were produced. Crash minimization could preserve a group identity while reducing its representative input. Incremental mode could process only new content hashes in a growing campaign. The same normalized findings now feed a dashboard, a plain-language exploitability brief, CI severity gates, and machine-readable exports.

Validation

Several early bugs made the case for fixture-based validation. The protection scanner initially read the wrong GNU_STACK line, its FORTIFY_SOURCE match lacked a word boundary, and dynamic symbols from nm -D were parsed incorrectly. Each fix became a regression test. Sanitizer fixtures now cover multiple GCC and Clang versions across ASan, UBSan, LSan, MSan, and TSan output.

Deduplication was also measured against the GPTrace/Igor corpus: 325,044 labeled ASan reports from 50 bugs across 14 C and C++ targets. AutoFTE recorded 97.7 percent macro purity and 90.5 percent macro inverse purity. Its 89.9 percent pooled purity is close to the 89.4 percent ceiling calculated for the stack-hash evidence available in that dataset. That ceiling was important because it separated an implementation problem from a limit in the signal itself.

Results

AutoFTE became a Linux CLI and Python package that can take a fuzzing directory through triage, prioritization, and reporting without sending the target or its crashes to a cloud service. The bundled demo covers four vulnerability classes, and the project can also run as a GitHub Action, a container, or a standalone binary.

The larger result is a change in what the tool optimizes for. The early project automated crash handling. The current project preserves a chain from each conclusion back to sanitizer text, stack frames, mitigations, registers, the faulting instruction, and a minimized reproducer. The report is useful because that chain remains available for a person to challenge.