# Fuzzing101: a fuzzing course built around ten historical CVEs

> A GitHub Security Lab tutorial that walks through ten real targets from Xpdf to Chrome V8, each one teaching a specific fuzzing technique. The repository holds exercises and a VMware image, not code, and the newest changelog entry is from 2022.

**antonio-morales/Fuzzing101** — An step by step fuzzing tutorial. A GitHub Security Lab initiative 

- Repository: https://github.com/antonio-morales/Fuzzing101
- Website: https://securitylab.github.com/
- Stars: 3,916 · Forks: 433
- Language: Unknown
- License: Apache-2.0
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/antonio-morales-fuzzing101

## Ten targets, ten CVE numbers, ten new skills

The selling point of this course is that it is not a tool tutorial with a toy target. The README's structure table pairs every exercise with a real target and the specific CVE the exercise is meant to reproduce. Exercise 1 is Xpdf and CVE-2019-13288 at an estimated 120 minutes. Exercise 2 is libexif and two CVEs, CVE-2009-3895 and CVE-2012-2836, at six hours, with the note that it involves fuzzing libraries rather than a single binary. Exercise 3 is TCPdump and CVE-2017-13028. Exercise 4 is LibTIFF and CVE-2016-9297, and its stated topic is code coverage with LCOV, which is the point where the course stops being about a fuzzer and starts being about knowing whether you looked everywhere.

The later exercises get less forgiving by design. Exercise 5, Libxml2 and CVE-2017-9048, adds dictionaries and basic parallelisation. Exercise 6, GIMP with CVE-2016-4994, is labelled persistent fuzzing and fuzzing interactive applications at seven hours. Exercise 7 attacks VLC media player for CVE-2019-14776 with partial instrumentation and a harness. Exercise 8 targets Adobe Reader with no CVE listed at all, because the lesson is fuzzing closed-source applications through QEMU instrumentation.

Exercise 9 goes after 7-Zip and CVE-2016-2334 with WinAFL on Windows. Exercise 10, marked as the final challenge, is Google Chrome and V8 against CVE-2019-5847 using Fuzzilli, at eight hours.

## What a coverage-guided evolutionary fuzzer is doing

The README defines the technique in one sentence: fuzz testing feeds a program with random or mutated input values and monitors it for exceptions and crashes. It names AFL, libFuzzer and HonggFuzz as three of the most successful fuzzers on real world applications and classifies all three as coverage-guided evolutionary fuzzers, then spends a section unpacking that phrase.

Evolutionary is the easier half to explain. It is a metaheuristic inspired by evolutionary algorithms, which in practice means the initial set of seed inputs gets mutated over time and selection criteria decide what survives. Coverage is the interesting half: rather than picking mutations at random, a coverage-guided fuzzer gathers and compares code coverage data between inputs, usually through instrumentation, and keeps the ones that reach execution paths not seen before. The repository ships a `Diagram.png` with a caption describing a simplification of the coverage gathering process, which is worth opening before anything else in the course.

The practical consequence is that a fuzzer with no coverage feedback is close to random testing, and a fuzzer with a bad corpus spends most of its time re-walking paths it already knows. Everything in the exercise table about instrumentation, dictionaries and LCOV is downstream of that one idea.

## The exercise order is a curriculum, not a difficulty list

Read the topics column as a syllabus. It starts at 120 minutes with `Afl-clang-fast`, `Afl-fuzz` and GDB, which is the minimum viable loop: compile a target with coverage instrumentation, throw a corpus at it, and attach a debugger to the first crash. The estimate then grows to six hours by Exercise 2 because you are now building a harness for a library, which is a different problem from fuzzing a binary that takes a file path.

From there the topics get more specialised in a deliberate order: sanitizers and ASan in Exercise 3, coverage measurement in 4, dictionaries and parallelisation in 5, stateful fuzzing and interactive applications in 6, harnesses and partial instrumentation in 7. Each step assumes the previous one works. Skipping to Exercise 6 without knowing how to build a dictionary means fuzzing a GIMP plugin surface with no idea whether your coverage number is moving.

The course is explicit that AFL++ is the tool in use, a newer fork of Michał Zalewski's AFL, chosen over the original Google AFL the README also links to. That matters for anyone following along today, because the original AFL is unmaintained and the fork's instrumentation and instrumentation-free modes behave differently. The repository topics list carries `afl`, `afl-fuzz`, `fuzzer` and `fuzzilli`, which is a fair summary of the toolchain the exercises assume.

## What the repository actually contains

The tree is short enough to describe in one line: `Diagram.png`, `LICENSE`, `Readme.md`, `Resources/`, and ten directories named `Exercise 1` through `Exercise 10`. There is no source directory, no build system and no library. That is the honest description of what Fuzzing101 is: a set of documents, targets to download and instructions to follow, hosted in a Git repository because that is where a course with ten chapters and a shared Resources folder belongs.

The GitHub metadata reflects that too. The repository has no detected primary language, because it does not contain a program in any language. There are no GitHub releases, so there is no version history beyond commits, and the README carries its own changelog with two entries: 02/14/2022 fixing some wget typos in Exercise 5, and 11/25/2021 updating Exercise 3 with fixes.

The homepage is GitHub Security Lab, which is where the initiative sits, and the README credits ten people who helped with the exercises, including Xavier RENE-CORAIL and Alan Vivona. The intended audience is stated plainly twice: anyone wanting the fuzzing basics, and anyone who wants to learn how to find vulnerabilities in real software projects.

## Ubuntu 20.04 and the virtual machine constraint

The requirements section is where this course stops being universally usable. It asks for a running Linux system with an internet connection, at least basic Linux skills, and it points at a suitable VMware image in the exercises. Then it says the exercises have been tested on Ubuntu 20.04.2 LTS, with a download link for that specific point release.

Ubuntu 20.04 reached end of standard support in 2025, so the pinned image is a fixed point in time rather than a suggestion. That is not necessarily bad for a fuzzing course, because half the value is reproducing a known crash and a frozen environment makes that easier. It does mean the flags in those documents were written against the toolchain of that era, and that any exercise where you install AFL++ or a sanitizer from source will behave differently today.

There is also no solutions branch in the tree, which is either a feature or a gap depending on your intent. The related searches people type for this project include Fuzzing 101 solutions, and what shows up is the exercises themselves. Solve them yourself and you learn the debugging loop that is the actual point; read the answers first and you get the commands without the reasoning, which is most of the value in an exercise that teaches you to attach GDB to a fresh crash.

## Who this course is for and what it will not give you

The course is aimed at people who can already use a Linux shell and want to find bugs in real software. It is not aimed at application security engineers looking for a triage workflow, and it does not cover continuous fuzzing infrastructure. Nothing in the README mentions libFuzzer harnesses for production code, corpus minimization at scale, or integrating a fuzzer into a CI pipeline. libFuzzer is named as one of the three great fuzzers, but no exercise uses it, because the exercises deliberately go in AFL order.

It also stops short of the modern toolchain. There is no mention of libAFL, the coverage-guided fuzzing library written in Rust that the project's own related search list leads with, and no mention of OSS-Fuzz beyond the fact that the searchers type that phrase. If your goal is to contribute to a project that already fuzzes on OSS-Fuzz, the gap between this course and that workflow is larger than the README implies.

What you do get is the one thing tutorials usually skip: the boring part where you build a corpus, watch the coverage number, discover your harness never reaches the vulnerable function, and fix it. Exercise 2's six hours and Exercise 7's harness work are where that lesson lives, and no amount of reading about coverage-guided fuzzing substitutes for it. The last push was on 2026-06-16, so the repository is still being touched even though its changelog has not moved since 2022.

## Conclusion

Fuzzing101 is worth several evenings for anyone who has read about coverage-guided fuzzing and never actually built a corpus, because the targets are chosen so each one forces a new skill rather than repeating the last. Its limits are equally clear. The repository contains exercises, write-ups and a `Resources/` directory rather than a toolchain, there are no releases to speak of, and the changelog stops at 02/14/2022, so the tool versions in those exercises are frozen in Ubuntu 20.04.2 LTS even though the last push was on 2026-06-16. Read the exercise documents for the technique and check the current AFL++ documentation for the flags, and pick the exercise whose target you already have an interest in rather than working through the table in order.

## FAQ

### What is fuzzing and how does it work?

Fuzzing feeds a program with random or mutated input and watches for crashes or exceptions. A coverage-guided fuzzer, which is the category AFL, libFuzzer and HonggFuzz belong to, also instruments the target, compares execution paths between inputs and keeps the mutations that reach new code.

### What skills are needed for fuzzing?

Fuzzing101 asks for a running Linux system with an internet connection and at least basic Linux skills, and it points at a VMware image inside the exercises. It also assumes you can read C well enough to understand what a crash in the target means, since most exercises end in a debugger.

### What is fuzz testing used for?

In this course it is used to find memory safety and parsing bugs in real software, and each of the ten exercises is tied to a specific published CVE, from CVE-2019-13288 in Xpdf through to CVE-2019-5847 in Chrome V8. The stated audience is anyone who wants to learn how vulnerabilities are found in real projects.

## Sources

- [antonio-morales/Fuzzing101 on GitHub](https://github.com/antonio-morales/Fuzzing101)
- [Issues](https://github.com/antonio-morales/Fuzzing101/issues)
- [License: Apache-2.0](https://github.com/antonio-morales/Fuzzing101/blob/main/LICENSE)
- [Project website](https://securitylab.github.com/)
- [README](https://github.com/antonio-morales/Fuzzing101/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/antonio-morales-fuzzing101
