Garden of KnowledgeApplied Sciences › Computer Science › Software › Security › Reverse Engineering
November 6, 2025

Fuzzing

Le fuzzing (ou fuzz testing) est une technique de test automatisé qui consiste à envoyer des données invalides, aléatoires ou inattendues à un système afin de découvrir des bugs, crashes, et vulnérabilités de sécurité.

Principes fondamentaux§

Pourquoi fuzzer§

Les développeurs pensent en termes de chemins valides ; les attaquants exploitent les chemins inattendus. Le fuzzing automatise l’exploration de l’espace d’entrée pour trouver :

Types de fuzzers§

TypeDescriptionExemples
BlackboxAucune connaissance du code sourcewfuzz, ffuf, Boofuzz
GreyboxUtilise la couverture de code comme feedbackAFL++, libFuzzer, Honggfuzz
WhiteboxAnalyse symbolique ou concolic du codeKLEE, SAGE, SymCC
Mutation-basedModifie des entrées valides existantesAFL++, Radamsa
Generation-basedGénère des entrées depuis une grammairePeach, Boofuzz, grammarinator

Métriques clés§

Fuzzing web (découverte d’endpoints)§

ffuf — Fast web fuzzer§

# Découverte de répertoires
ffuf -u http://target.com/FUZZ -w /usr/share/wordlists/dirb/common.txt

# Avec extension
ffuf -u http://target.com/FUZZ -w wordlist.txt -e .php,.html,.txt,.bak

# Fuzzing de paramètres GET
ffuf -u "http://target.com/page?FUZZ=value" -w params.txt

# Fuzzing de la valeur d'un paramètre
ffuf -u "http://target.com/page?id=FUZZ" -w /usr/share/wordlists/wfuzz/Injections/SQL.txt

# POST avec body JSON
ffuf -u http://target.com/api/login \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"username":"FUZZ","password":"test"}' \
     -w usernames.txt

# Filtrer par code HTTP (exclure 404)
ffuf -u http://target.com/FUZZ -w wordlist.txt -fc 404

# Filtrer par taille de réponse
ffuf -u http://target.com/FUZZ -w wordlist.txt -fs 1234

# Fuzzing de sous-domaines
ffuf -u http://FUZZ.target.com -w subdomains.txt -H "Host: FUZZ.target.com"

# Récursif
ffuf -u http://target.com/FUZZ -w wordlist.txt -recursion -recursion-depth 2

# Output JSON pour traitement
ffuf -u http://target.com/FUZZ -w wordlist.txt -o results.json -of json

wfuzz§

# Découverte basique
wfuzz -c -z file,wordlist.txt http://target.com/FUZZ

# Masquer codes 404
wfuzz -c -z file,wordlist.txt --hc 404 http://target.com/FUZZ

# Fuzzing de cookies
wfuzz -c -z file,payloads.txt -b "session=FUZZ" http://target.com/profile

# Authentification basique
wfuzz -c -z file,passwords.txt --basic admin:FUZZ http://target.com/admin

Wordlists utiles§

SourceCheminUsage
SecLists/usr/share/seclists/Référence complète
dirb/usr/share/wordlists/dirb/common.txtRépertoires courants
dirbuster/usr/share/wordlists/dirbuster/Découverte approfondie
rockyou/usr/share/wordlists/rockyou.txtPasswords
wfuzz/usr/share/wordlists/wfuzz/Payloads injection

Fuzzing réseau et protocoles§

Boofuzz — Framework Python pour protocoles réseau§

from boofuzz import *

def main():
    session = Session(
        target=Target(
            connection=TCPSocketConnection("192.168.1.100", 21)  # FTP
        )
    )

    s_initialize("FTP USER")
    s_static("USER ")
    s_string("administrator")  # champ fuzzé
    s_static("\r\n")

    session.connect(s_get("FTP USER"))
    session.fuzz()

if __name__ == "__main__":
    main()

Radamsa — Mutateur générique§

# Générer 100 mutations d'un input valide
echo "test_input" | radamsa -n 100 > fuzz_inputs.txt

# Muter un fichier (ex: PDF)
radamsa input.pdf -o fuzzed_##.pdf -n 1000

# Fuzzer une cible réseau directement
echo "GET / HTTP/1.0\r\n\r\n" | radamsa -n 100 | nc target.com 80

Coverage-guided fuzzing (greybox)§

AFL++ — American Fuzzy Lop§

Le fuzzer greybox de référence. Instrumente le binaire pour tracker la couverture de code, et priorise les inputs qui découvrent de nouvelles branches.

# Compiler avec instrumentation AFL
CC=afl-clang-fast ./configure
make

# Ou avec afl-gcc
afl-gcc -o target_afl source.c

# Créer le corpus initial
mkdir corpus_in corpus_out
echo "test" > corpus_in/seed1

# Lancer AFL++
afl-fuzz -i corpus_in -o corpus_out -- ./target_afl @@
# @@ : AFL remplace par le path du fichier généré

# Avec timeout personnalisé (ms)
afl-fuzz -i corpus_in -o corpus_out -t 1000 -- ./target_afl @@

# Fuzzing parallèle (maître + 3 secondaires)
afl-fuzz -i corpus_in -o corpus_out -M fuzzer1 -- ./target_afl @@
afl-fuzz -i corpus_in -o corpus_out -S fuzzer2 -- ./target_afl @@
afl-fuzz -i corpus_in -o corpus_out -S fuzzer3 -- ./target_afl @@

# Statistiques en temps réel
afl-whatsup corpus_out/

# Triage des crashes
afl-tmin -i corpus_out/crashes/id:000000 -o minimized -- ./target_afl @@

Interprétation du dashboard AFL++ :

libFuzzer — Fuzzing en-process§

Intégré directement dans le binaire comme bibliothèque. Pas de fork(), très rapide.

// target.c — fonction cible à fuzzer
#include <stdint.h>
#include <stddef.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    if (size < 4) return 0;

    // Code à tester
    if (data[0] == 'F' && data[1] == 'U' &&
        data[2] == 'Z' && data[3] == 'Z') {
        __builtin_trap();  // Simule un bug
    }
    return 0;
}
# Compiler avec libFuzzer
clang -g -fsanitize=fuzzer,address target.c -o target_fuzz

# Lancer
./target_fuzz corpus_dir/ -max_len=1024

# Avec dictionnaire
./target_fuzz corpus_dir/ -dict=keywords.dict

# Reproduire un crash
./target_fuzz crash-abc123

AddressSanitizer (ASan)§

Détecter les accès mémoire invalides pendant le fuzzing :

# Compiler avec ASan + UBSan + fuzzer
clang -fsanitize=address,undefined,fuzzer target.c -o target_fuzz

# Variables d'environnement
ASAN_OPTIONS=abort_on_error=1:symbolize=1 ./target_fuzz corpus/

Fuzzing d’APIs REST§

Schemathesis — Fuzzing basé sur OpenAPI§

# Depuis une spec OpenAPI
schemathesis run http://api.target.com/openapi.json

# Tester les injections spécifiquement
schemathesis run http://api.target.com/openapi.json --checks all

# Depuis un fichier local
schemathesis run schema.yaml --base-url http://localhost:8000

# Format de sortie JUnit
schemathesis run schema.yaml --junit-xml report.xml

RESTler — Fuzzer Microsoft pour REST APIs§

# Compilation (dotnet required)
dotnet build

# Test stateful
python restler.py compile --api_spec openapi.json
python restler.py fuzz --grammar_file Compile/grammar.py --time_budget 24

Fuzzing de fichiers (parsers)§

Les parsers de formats (PDF, XML, ZIP, images) sont des cibles privilégiées :

# Fuzzer un parser PDF avec AFL++
afl-gcc -o pdf_parser_afl pdf_parser.c

mkdir seeds
cp sample.pdf seeds/
afl-fuzz -i seeds -o crashes -t 5000 -- ./pdf_parser_afl @@

# Ou avec libFuzzer + ASan (plus efficace)
clang -fsanitize=address,fuzzer pdf_parser.c -o pdf_fuzz
./pdf_fuzz seeds/ -max_len=10000000

# Honggfuzz pour targets compilées
honggfuzz -i seeds/ -o corpus/ -- ./pdf_parser ___FILE___

Analyse des résultats§

Triage des crashes§

# Minimiser un crash (trouver le plus petit input déclenchant le bug)
afl-tmin -i crash_file -o minimized -- ./target @@

# Analyser avec GDB
gdb -ex "run < crash_file" -ex "bt" -ex "quit" ./target

# Avec ASan, le rapport indique directement le type de bug :
# heap-buffer-overflow, stack-buffer-overflow, use-after-free, etc.

# Déduplication (éviter les doublons)
afl-collect -r corpus_out/crashes ./target @@

Types de bugs découverts§

BugDescriptionDangerosité
Heap buffer overflowÉcriture hors des limites du tasCritique (RCE possible)
Stack buffer overflowÉcriture hors des limites de la pileCritique (RCE/contrôle EIP)
Use-after-freeAccès à mémoire libéréeCritique
Integer overflowDépassement d’entierVariable
Null pointer dereferenceAccès à l’adresse 0DoS
Format string%n en paramètre contrôlableCritique
Race conditionTOCTOU, atomicitéVariable
Infinite loopHang sur input malforméDoS

Outils récapitulatif§

OutilCibleType
ffufWeb endpointsBlackbox mutation
wfuzzWeb parametersBlackbox
AFL++Binaires C/C++Greybox coverage
libFuzzerFonctions C/C++In-process greybox
HonggfuzzBinairesGreybox
BoofuzzProtocoles réseauGeneration-based
RadamsaTout (générique)Mutation-based
SchemathesisAPIs REST/OpenAPIGeneration-based
PeachProtocoles/fichiersGeneration-based
ClusterFuzzInfrastructure cloudCoverage-guided
OSS-FuzzOpen source (Google)Coverage-guided
—The Gardener