Pular para o conteúdo

LibAFL - Cheatsheet de Framework de Fuzzing Modular

LibAFL - Cheatsheet de Framework de Fuzzing Modular

LibAFL é um framework de fuzzing, não um fuzzer. Escrito em Rust pela equipe AFL++, fornece blocos de construção compostos — observers, feedbacks, mutators, schedulers, stages, executors — que você monta em um fuzzer adaptado ao seu alvo. A motivação é que fuzzers monolíticos funcionam bem em alvos convencionais e mal em incomuns (protocolos customizados, firmware emulado, kernels, gramáticas), onde você termina lutando contra a ferramenta. Com LibAFL você construa exatamente o fuzzer que o alvo precisa, e obtém escalamento multi-core gratuitamente.

Construir um fuzzer é mais trabalho que executar um. Alcance LibAFL quando ferramentas prontas genuinamente não se encaixam.

Setup

PassoComando
Novo projetocargo new my_fuzzer && cd my_fuzzer
Adiciona LibAFLcargo add libafl libafl_bolts
Instrumentação de alvocargo add libafl_targets (ou libafl_qemu, libafl_frida)
Buildcargo build --release

Conceitos Centrais

ComponentePapel
InputO que é fuzzed (bytes, árvore de gramática, syscalls)
ObserverRegistra dados durante uma execução (mapa de cobertura, timing)
FeedbackDecide se uma execução foi “interessante”
ObjectiveDecide se uma execução é uma solução (um crash)
CorpusArmazenamento para inputs interessantes
MutatorTransforma inputs
SchedulerEscolhe o próximo input para executar
StageUma fase aplicada por input (mutar, trim, calibrar)
ExecutorExecuta o alvo com um input

Um Fuzzer Mínimo (forma)

// Estrutura conceitual — veja exemplos LibAFL para código completo
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)?;

Executors (Como o Alvo Executa)

ExecutorUse
InProcessExecutorMais rápido; harness no mesmo processo
ForkserverExecutorEstilo AFL forkserver para binários externos
CommandExecutorExecuta um comando externo por input
libafl_qemuAlvos emulados / fuzzing binário-only
libafl_fridaInstrumentação dinâmica (binário-only)
libafl_nyxFuzzing de VM baseado em snapshot

Feedbacks

FeedbackInteressante quando
MaxMapFeedbackNovas bordas de cobertura alcançadas
TimeFeedbackTempo de execução muda
CrashFeedbackAlvo travou (objetivo)
TimeoutFeedbackAlvo pendurou (objetivo)
NewHashFeedbackStack de crash único novo
Combinadoresfeedback_or!, feedback_and! para compor

Mutators

MutatorFaz
havoc_mutations()Mutações aleatórias padrão de estilo AFL
tokens_mutations()Inserção de dicionário/token
Mutadores de gramáticaGeração ciente de estrutura
CustomImplementa o trait Mutator para seu tipo de entrada

Tipos de entrada customizados mais mutadores customizados são a razão principal para escolher LibAFL — fuzz um protocolo ou AST inteligentemente em vez de virar bits.

Escalamento Multi-Core

MecanismoNota
LlmpRestartingEventManagerPassagem de mensagem de baixa sobrecarga entre cores
LauncherSpawna um fuzzer por core com corpus compartilhado
Sincronização de corpusInputs interessantes propagam entre instâncias
RestartingSobrevive crashes do processo fuzzer

LibAFL vs Fuzzers Prontos

AspectoLibAFLAFL++honggfuzz
ModeloConstrua o seuPronto para executarPronto para executar
EsforçoAltoBaixoBaixo
FlexibilidadeTotalConfigurávelConfigurável
Melhor paraAlvos incomuns, pesquisaBinários padrãoInício rápido, feedback de hardware

Comece com AFL++ ou honggfuzz; mude para LibAFL quando a estrutura de entrada do alvo ou modelo de execução os derrota.

Recursos