Listen to this Post

Introduction:
Fuzzing is an essential technique in software security that involves feeding unexpected or random inputs to a program to uncover hidden bugs, vulnerabilities, and crashes. American Fuzzy Lop Plus Plus (AFL++) is the successor to AFL, a very popular mutational, coverage-guided greybox fuzzer. It stands as one of the most powerful and user-friendly tools for vulnerability discovery, requiring essentially no configuration while seamlessly handling complex, real-world use cases. This article provides a comprehensive, step-by-step guide to fuzzing a sample vulnerable C program (‘vulnerable.c’) using AFL++, covering installation, instrumentation, execution, and result analysis across Linux and Windows environments.
Learning Objectives:
- Understand the core concepts of coverage-guided fuzzing and how AFL++ operates.
- Master the installation and configuration of AFL++ on Linux (Ubuntu/Kali) and its Windows counterpart (WinAFL).
- Gain hands-on experience in instrumenting, fuzzing, and analyzing crashes in a C program.
You Should Know:
1. Setting Up the AFL++ Fuzzing Environment
To begin fuzzing, you must first install AFL++ on your system. The easiest way to get started is by using the official Docker image, which comes with everything pre-compiled. This method is highly recommended to avoid dependency issues.
- Using Docker (Recommended for Linux):
docker pull aflplusplus/aflplusplus:latest docker run -ti -v /location/of/your/target:/src aflplusplus/aflplusplus
This command pulls the latest AFL++ image and mounts your target directory into the container.
-
Building from Source (Ubuntu/Debian/Kali):
For a native installation, you need to install the necessary dependencies and compile AFL++ yourself.sudo apt-get update sudo apt-get install -y build-essential python3-dev automake cmake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools cargo libgtk-3-dev sudo apt-get install -y lld-14 llvm-14 llvm-14-dev clang-14 || sudo apt-get install -y lld llvm llvm-dev clang git clone https://github.com/AFLplusplus/AFLplusplus cd AFLplusplus make distrib sudo make install
It is highly recommended to have the newest LLVM version possible installed; anything below version 9 is not recommended.
-
Fuzzing on Windows:
While AFL++ is primarily a Linux tool, Windows users can leverage WinAFL, a Windows equivalent that uses DynamoRIO for instrumentation. The setup involves building WinAFL from source with Visual Studio and using it similarly to fuzz Windows binaries.
2. The Target: Writing ‘vulnerable.c’
Our target program is a simple C application vulnerable to a classic buffer overflow. It uses `strcpy` to copy a user-provided string into a fixed-size buffer (char buffer
) without checking the input length.
Create a file named `vulnerable.c` with the following code:
[bash]
include <stdio.h>
include <string.h>
int main(int argc, char argv[]) {
// Define a buffer of size 20
char buffer[bash];
// Check if command line arguments are passed
if (argc < 2) {
printf("Usage: %s <string>\n", argv[bash]);
return 1;
}
// Vulnerable to buffer overflow
strcpy(buffer, argv[bash]);
// Display string
printf("You entered: %s\n", buffer);
return 0;
}
Supplying input longer than 20 characters will overwrite adjacent memory, causing a segmentation fault.
3. Instrumenting the Program with afl-cc
AFL++ uses instrumentation to monitor how the code behaves under different inputs. To instrument the program, we must compile it with AFL++’s provided `afl-cc` compiler.
afl-cc -o vulnerable vulnerable.c
This will generate an executable named `vulnerable` in the current directory.
For more advanced instrumentation, AFL++ offers different modes. It is highly recommended to use the LTO mode (Link Time Optimization) if you have LLVM 11+ installed, as it provides superior performance and coverage. You can use `afl-clang-lto` or `afl-clang-lto++` for this purpose.
4. Preparing the Input Corpus
AFL++ requires an initial set of inputs (a seed corpus) to start fuzzing. This provides a baseline for the fuzzer to mutate.
Create an input directory and populate it with a valid test case:
mkdir input echo "AAAAAAAAAAAAAAAA" > input/testcase
AFL++ will use this seed to generate thousands of mutated inputs. If fuzzing a format with complex syntax like SQL or HTTP, it is beneficial to create a dictionary file as described in the `dictionaries/README.md` to improve efficiency.
5. Executing the Fuzz Test
With the instrumented binary and input corpus ready, you can now start the fuzzing process using the `afl-fuzz` command.
If the program reads input from a file (or via arguments as in our case), you use the `@@` placeholder. AFL++ will replace `@@` with the name of a generated input file.
afl-fuzz -i input -o findings -- ./vulnerable @@
– -i input: Specifies the input directory containing seed files.
– -o findings: Specifies the output directory where AFL++ will store crash reports and logs.
– ./vulnerable @@: Instructs AFL++ to pass the fuzzed input file as a command-line argument to the target program.
If the program reads from standard input (stdin), the command would be:
afl-fuzz -i input -o findings -- ./vulnerable
Monitoring Progress:
AFL++’s terminal interface provides real-time statistics about the fuzzing process, such as execution speed, unique crashes, and code coverage. Pay close attention to anything shown in red in the fuzzer UI, as it often indicates critical issues or crashes.
6. Analyzing Results and Crashes
When AFL++ discovers a crash, it saves the crashing input in the `findings` directory (usually under crashes/). These files are the key to understanding and reproducing the vulnerability.
To analyze a crash, you can run the target program with the crashing input:
./vulnerable $(cat findings/crashes/id:000000,sig:11,src:000000,op:flip1,pos:0)
Or, if using a debugger like GDB:
gdb --args ./vulnerable $(cat findings/crashes/id:000000,sig:11,src:000000,op:flip1,pos:0)
This allows you to pinpoint the exact memory corruption and understand the exploitability of the bug. The `afl-fuzz` tool uses a genetic algorithm to intelligently mutate input data, aiming to discover new code paths and uncover potential vulnerabilities by feeding the program increasingly complex inputs based on the coverage information gathered.
7. Advanced Usage: Fuzzing Binary-Only and ARM Targets
AFL++ is not limited to source code. For binary-only targets, you can use QEMU mode (afl-qemu-trace) or FRIDA mode.
- Fuzzing an ARM ELF:
First, cross-compile your target for ARM:
arm-linux-gnueabi-gcc -o vulnerable_arm vulnerable.c -static
Then, use the AFL++ Docker image and build the QEMU support for ARM:
docker run -it --rm -v $HOME:$HOME aflplusplus/aflplusplus cd /AFLplusplus/qemu_mode CPU_TARGET=arm ./build_qemu_support.sh
Finally, fuzz the ARM binary using QEMU mode:
afl-fuzz -Q -i input -o findings -- ./vulnerable_arm @@
What Undercode Say:
- Key Takeaway 1: Coverage-guided fuzzing with AFL++ is a game-changer for vulnerability research. By automatically mutating inputs and tracking code coverage, it drastically reduces the time and effort required to find critical security flaws compared to manual code review.
- Key Takeaway 2: The true power of AFL++ lies in its versatility. Whether you are fuzzing a simple C program, a complex library, a binary-only ARM firmware, or a Windows application via WinAFL, the core principles remain the same. Mastering this tool equips security professionals with a universal skill for uncovering hidden bugs across diverse platforms.
Analysis:
The demonstration with `vulnerable.c` illustrates the fundamental workflow of fuzzing: instrument, seed, fuzz, and analyze. The buffer overflow vulnerability, while simple, is representative of the thousands of memory corruption bugs that plague modern software. AFL++’s ability to find these bugs autonomously makes it an indispensable asset in any security toolkit. Furthermore, the support for binary-only targets through QEMU and FRIDA modes extends its utility to legacy systems, IoT devices, and proprietary software where source code is unavailable. As fuzzing techniques evolve, integrating AFL++ with Continuous Integration (CI) pipelines and leveraging Large Language Models (LLMs) to generate fuzzing harnesses are the next frontiers, promising even more automated and intelligent vulnerability discovery.
Prediction:
- +1 The integration of AFL++ with AI and LLMs for automated harness generation will democratize fuzzing, allowing even junior developers and security analysts to perform advanced vulnerability research with minimal effort.
- +1 As software complexity grows, coverage-guided fuzzing will become a mandatory step in the Secure Development Lifecycle (SDL) for critical infrastructure and enterprise software, driven by regulatory requirements and the increasing cost of data breaches.
- -1 The rise of fuzzing as a standard practice will force attackers to develop more sophisticated evasion techniques, such as anti-fuzzing mechanisms and logic bombs that remain dormant during fuzzing, leading to an arms race between defenders and adversaries.
- -1 Fuzzing resource-intensive targets (e.g., kernel modules, hypervisors) will remain challenging and may lead to hardware damage or system instability, requiring dedicated, isolated fuzzing farms and advanced monitoring to prevent catastrophic failures.
▶️ Related Video (82% Match):
🎯Let’s Practice For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
IT/Security Reporter URL:
Reported By: Sans1986 Try – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


