Fuzzing is an automated testing technique in which programs or interfaces are confronted with unusual, invalid, or random inputs in order to uncover vulnerabilities such as buffer overflows, program crashes, or other unintended behavior.
Fuzzing can be applied to applications, network services, APIs, and file formats.
The goal of fuzzing is to provoke error states, crashes, memory errors, or security vulnerabilities that are often not found by classic tests because they are only triggered by conditions such as boundary values, invalid combinations, or certain bit manipulations. We will discuss various fuzzing techniques in this blog post.
In dumb fuzzing, also known as blind fuzzing, test data is generated purely at random, without regard to the expected input structure or protocol rules of the target program. A simple shell script is sufficient to generate random strings with /dev/urandom, for example, and pass them to a command line program:
for i in {1..1000}; do
echo "$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | head -c 100)" |
./targetprogram
done
This script executes the target program 1,000 times with 100 random alphanumeric characters each time. Although this method is very simple and does not require any knowledge of the data format or program logic, it is inefficient for more complex programs: most inputs are simply discarded or do not lead to new program states. However, no specialized tools are required for this. Basic shell commands such as cat, tr, and head are sufficient.
In smart fuzzing, the fuzzer knows the format or protocol of the input and generates structured test data based on valid specifications. Smart fuzzing typically involves testing file formats (such as PDF, JPEG, or DOCX) or protocols (such as HTTP, FTP, or TCP).
For example, you could generate a structured HTTP request in which header fields are too long or duplicated:
GET /index.html HTTP/1.1
Host: example.com
Content-Length: 9999999999
X-Custom: AAAAAAAAAAAAA...[10000x A]
Tools such as Peach Fuzzer or Boofuzz can be used to automatically generate targeted inputs. These tools use templates that specify how the protocol is structured. One advantage is that they are very effective with complex protocols. A disadvantage is the additional effort involved, as you need to know exactly how the inputs must be structured.
Mutation-based fuzzing uses existing, valid input files and modifies them in a targeted manner. This means that the data is not purely random but consists of modified valid examples—such as a real PDF file or an HTTP request—that are then mutated. This increases the chance of reaching deeper program branches.
A practical example is fuzzing a program that processes PNG images. To do this, you can use the Radamsa fuzzer, for example. Take a real PNG file and modify individual bytes or character strings using the following code:
radamsa image.png > mutated.png
./output mutated.png
The mutated file is then loaded. If the program crashes or behaves unusually when processing the manipulated file, that could indicate a vulnerability. Mutation-based fuzzing is particularly effective when you know which inputs the program typically accepts. It therefore uses existing structures as a basis.
Coverage-guided fuzzing not only generates input but also monitors program execution to determine which parts of the program are actually reached. The fuzzer then adjusts its inputs so that as many different program branches as possible are traversed. One example is the American Fuzzy Lop (AFL) fuzzer. Before the target program can be fuzzed, it is compiled as follows:
CC=afl-gcc ./configure
make
Then the fuzzing is started:
afl-fuzz -i inputs/ -o outputs/ -- ./targetprogram @@
AFL then analyzes which inputs lead to new code paths and focuses its mutations precisely on those. This makes it significantly more efficient than pure dumb fuzzing.
In protocol fuzzing, network protocols are systematically fuzzed using tools such as boofuzz or Peach. A client or server is confronted with manipulated network packets in order to provoke malfunctions. An example of this is fuzzing a simple FTP server with boofuzz, which can be used directly in Python:
from boofuzz import *
session = Session(target=Target(connection=SocketConnection("127.0.0.1",
21, proto="tcp")))
s_initialize("user")
s_string("USER")
s_delim(" ")
s_string("anonymous", fuzzable=True)
s_static("\r\n")
session.connect(s_get("user"))
session.fuzz()
This script sends a series of USER commands with modified usernames. Its goal is to cause the server to crash or behave unexpectedly. Protocol fuzzing is particularly effective when analyzing proprietary services or older network protocols with weak error handling.
Web fuzzing focuses on web servers, web applications, or REST APIs. For example, URL paths, form parameters, or cookies are automatically varied to discover hidden endpoints or insecure parameters. One program for systematically trying out directory names is Fuzz Faster U Fool (FFUF).
Every technique here trades setup effort against depth of coverage, from dumb fuzzing that costs nothing but rarely reaches past the first parser check, to coverage-guided tools like AFL that take feedback from the program itself and steer mutations toward untested branches. Most teams end up combining approaches, and the real work starts after the first crash, when you reproduce it, minimize the input, and decide whether it points to an exploitable condition.
Editor’s note: This post has been adapted from a section of the book Ethical Hacking: The Practical Guide for Pentesting and Red Teaming by Florian Dalwigk. Florian is an expert in cybercrime, cyberespionage, and IT security. After studying computer science, he worked for a security agency and has been a volunteer lecturer since 2024, teaching modules on "Ethical Hacking," "IT Forensics," "Cyberespionage," "Cybercrime and Crypto Forensics," and "Post-Quantum Cryptography," among others. As an author of specialist books, he conveys his knowledge in a clear and practical way. He is interested in the interface between technological innovation and security, particularly in the context of state-controlled cyber operations and cryptographic resilience in the post-quantum era.
This post was originally published 9/2026.