Master Fuzz Testing with AFL and Honggfuzz: Step‑by‑Step Guide

This guide walks you through the fundamentals of fuzz testing, demonstrating how to install, configure, and use popular tools like AFL and Honggfuzz on Ubuntu to detect buffer overflows, illegal memory accesses, and other security vulnerabilities in C programs, complete with code examples and result analysis.

OPPO Amber Lab
OPPO Amber Lab
OPPO Amber Lab
Master Fuzz Testing with AFL and Honggfuzz: Step‑by‑Step Guide

What Is Fuzzing?

Fuzzing is an automated software testing technique that feeds programs with malformed, unexpected, or random data to trigger crashes, memory leaks, or other security issues. Mature tools such as AFL, AFL++, honggfuzz, LibFuzzer, and syzkaller have lowered the entry barrier, making fuzzing one of the most powerful methods for discovering software vulnerabilities.

Vulnerable Sample Program

The article first presents a deliberately vulnerable C program ( test1.c) that contains three distinct bugs:

#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
    FILE *fp;
    char line[1024];
    char buf[20] = {0};
    int nums[10];
    printf("starts
");
    if (argc < 2) { printf("argc < 2
"); return -1; }
    fp = fopen(argv[1], "r");
    if (NULL == fp) { printf("open file failed
"); return -1; }
    fgets(line, 1024, fp);
    fclose(fp);
    switch (line[8]) {
        case 'A': printf("case A
"); strcpy(buf, line); break;
        case 'B': printf("case B
"); *(int*)0xffffffffabcdef10 = 80; break;
        case 'C': printf("case C
"); nums[10] = 100; break;
        default:  printf("default
"); break;
    }
    printf("ends
");
    return 0;
}

Line 23 can overflow buf, line 27 writes to an unmapped address, and line 31 writes past the end of nums.

AFL Example

Installation : on Ubuntu 20.04 install make and gcc, download the source, extract, compile and install.

sudo apt install make gcc
wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
tar zxvf afl-latest.tgz
cd afl-2.52b
make
sudo make install

Successful compilation is confirmed by the appearance of the afl-fuzz command.

Instrumented Build of the target program:

afl-gcc test1.c -o test1_aflfuzz1

Seed Corpus : create a samples_test directory with a few arbitrary files, then minimise it with afl-cmin:

afl-cmin -i samples_test -o samples_cmin ./test1_aflfuzz1 @@

Adjust the kernel core‑dump pattern to avoid delayed crash reporting:

sudo su
echo core > /proc/sys/kernel/core_pattern

Run the fuzzer :

afl-fuzz -i samples_cmin/ -o aflfuzz_output ./test1_aflfuzz1 @@

The AFL UI shows two unique crashes (the buffer overflow and the illegal write). The interface also displays overall results, unique crashes, total crashes, hangs, process timing, map coverage, stage progress, and CPU usage.

Crash files are stored in aflfuzz_output/crashes. Inspecting them reveals that the first two crashes correspond to cases A and B, while case C (array out‑of‑bounds) does not immediately crash.

AddressSanitizer (ASan) Integration

Compile the target with ASan instrumentation:

afl-gcc test1.c -o test1_aflfuzz1_asan -fsanitize=address

Running AFL on this binary discovers all three bugs quickly, and the ASan output pinpoints the exact source line and memory address of each fault.

ASan can also be enabled directly with GCC:

gcc test1.c -o test1_asan -fsanitize=address
./test1_asan ./aflfuzz_output/crashes/id:000000,sig:06,...

Honggfuzz Example

Installation on Ubuntu 20.04:

sudo apt install libbfd-dev libunwind-dev clang git
git clone https://github.com/google/honggfuzz
cd honggfuzz
make
sudo make install

Verify installation by running honggfuzz and observing the help output.

Static Mode Fuzzing of test1.c (instrumented with ASan):

hfuzz-clang test1.c -o test1_hfuzz1 -fsanitize=address
honggfuzz -i samples_cmin/ -x -- ./test1_hfuzz1 ___FILE___

The UI shows three crashes, and the generated SIG* files can be replayed to see the exact fault location.

Persistent Mode with Honggfuzz

A second sample program ( test2.c) demonstrates the persistent fuzzing API:

#include <stdio.h>
#include <string.h>
#include <libhfuzz/libhfuzz.h>

int test_function1(const uint8_t* buffer, size_t len) {
    char buf[20] = {0};
    int nums[10];
    printf("starts
");
    if (len <= 8) { printf("len <= 8, return
"); return -1; }
    switch (buffer[8]) {
        case 'A': printf("case A
"); strcpy(buf, buffer); break;
        case 'B': printf("case B
"); *(int*)0xffffffffabcdef10 = 80; break;
        case 'C': printf("case C
"); nums[len] = 100; break;
        default:  printf("default
"); break;
    }
    printf("ends
");
    return 0;
}

int LLVMFuzzerTestOneInput(const uint8_t* buffer, size_t len) {
    test_function1(buffer, len);
    return 0;
}

Compile and run in persistent mode:

hfuzz-clang test2.c -o test2_hfuzz1
honggfuzz -i samples_cmin/ -P -- ./test2_hfuzz1

The fuzzer quickly reports dozens of crashes; inspecting a crash file shows the out‑of‑bounds write at nums[len] = 100;, confirming that persistent mode can exercise the target repeatedly with low overhead.

Conclusion

AFL and Honggfuzz provide straightforward, powerful workflows for fuzzing C programs, covering instrumented compilation, seed‑corpus creation, minimisation, and result analysis. Integrated sanitizers such as AddressSanitizer further improve bug localisation, making modern fuzzing accessible to developers and security engineers.

software securityC programmingfuzz testingAFLaddress sanitizerhonggfuzz
OPPO Amber Lab
Written by

OPPO Amber Lab

Centered on user data security and privacy, we conduct research and open our tech capabilities to developers, building an information‑security fortress for partners and users and safeguarding OPPO device security.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.