Aller au contenu

LibAFL - Framework de Fuzzing Modulaire

LibAFL - Framework de Fuzzing Modulaire

LibAFL est un framework de fuzzing, pas un testeur. Écrit en Rust par l’équipe AFL++, il fournit des blocs de construction composables — observateurs, retours, mutateurs, planificateurs, étapes, exécuteurs — que vous assemblez en un testeur adapté à votre cible. La motivation est que les testeurs monolithiques fonctionnent bien sur les cibles conventionnelles et mal sur les cibles inhabituelles (protocoles personnalisés, firmware émulé, noyaux, grammaires), où vous finissez par combattre l’outil. Avec LibAFL, vous construisez exactement le testeur dont la cible a besoin, et obtenez l’évolutivité multi-cœur gratuitement.

Construire un testeur est plus de travail que d’en exécuter un. Préférez LibAFL quand les outils prêts à l’emploi ne correspondent réellement pas.

Setup

ÉtapeCommande
Nouveau projetcargo new my_fuzzer && cd my_fuzzer
Ajouter LibAFLcargo add libafl libafl_bolts
Instrumentation ciblecargo add libafl_targets (ou libafl_qemu, libafl_frida)
Construirecargo build --release

Concepts Clés

ComposantRôle
InputCe qui est testé (octets, arborescence de grammaire, appels système)
ObserverEnregistre les données pendant une exécution (carte de couverture, timing)
FeedbackDécide si une exécution était « intéressante »
ObjectiveDécide si une exécution est une solution (un plantage)
CorpusStockage pour les entrées intéressantes
MutatorTransforme les entrées
SchedulerChoisit l’entrée suivante à exécuter
StageUne phase appliquée par entrée (muter, trimmer, calibrer)
ExecutorExécute la cible avec une entrée

Un Testeur Minimal (forme)

// Structure conceptuelle — voir les exemples LibAFL pour le code complet
let mut feedback = MaxMapFeedback::new(&edges_observer);
let mut objective = CrashFeedback::new();

let mut state = StdState::new(
    StdRand::with_seed(current_nanos()),
    InMemoryCorpus::new(),
    OnDiskCorpus::new("./crashes")?,
    &mut feedback,
    &mut objective,
)?;

let scheduler = QueueScheduler::new();
let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);

let mut executor = InProcessExecutor::new(
    &mut harness, tuple_list!(edges_observer), &mut fuzzer, &mut state, &mut mgr,
)?;

let mutator = StdScheduledMutator::new(havoc_mutations());
let mut stages = tuple_list!(StdMutationalStage::new(mutator));

fuzzer.fuzz_loop(&mut stages, &mut executor, &mut state, &mut mgr)?;

Exécuteurs (Comment la Cible S’exécute)

ExécuteurUtilisation
InProcessExecutorPlus rapide ; harnais dans le même processus
ForkserverExecutorStyle AFL forkserver pour les binaires externes
CommandExecutorExécuter une commande externe par entrée
libafl_qemuCibles émulées / fuzzing sans source binaire
libafl_fridaInstrumentation dynamique (sans source binaire)
libafl_nyxFuzzing de VM basé sur snapshot

Retours

RetourIntéressant quand
MaxMapFeedbackNouvelles arêtes de couverture touchées
TimeFeedbackLe temps d’exécution change
CrashFeedbackLa cible s’est plantée (objectif)
TimeoutFeedbackLa cible s’est suspendue (objectif)
NewHashFeedbackNouvelle trace de plantage unique
Combinateursfeedback_or!, feedback_and! pour composer

Mutateurs

MutateurFait
havoc_mutations()Mutations aléatoires standard de style AFL
tokens_mutations()Insertion de dictionnaire/jeton
Mutateurs de grammaireGénération tenant compte de la structure
PersonnaliséImplémenter le trait Mutator pour votre type d’entrée

Les types d’entrée personnalisés plus les mutateurs personnalisés sont la raison principale de choisir LibAFL — tester un protocole ou un AST intelligemment plutôt que de basculer des octets.

Évolutivité Multi-Core

MécanismeNote
LlmpRestartingEventManagerPassage de messages à faible surcharge entre les cœurs
LauncherGénérer un testeur par cœur avec corpus partagé
Synchronisation du corpusLes entrées intéressantes se propagent entre les instances
RedémarrageSurvit aux plantages du processus testeur

LibAFL vs Testeurs Prêts à l’Emploi

AspectLibAFLAFL++honggfuzz
ModèleConstruire votre proprePrêt à exécuterPrêt à exécuter
EffortÉlevéBasBas
FlexibilitéTotalConfigurableConfigurable
Meilleur pourCibles inhabituelles, rechercheBinaires standardDémarrage rapide, retour matériel

Commencez avec AFL++ ou honggfuzz ; passez à LibAFL quand la structure d’entrée de la cible ou le modèle d’exécution les défait.

Ressources