baby fuzzer

This commit is contained in:
Andrea Fioraldi 2021-04-21 14:51:51 +02:00
parent 0732028190
commit 2f7bb8d532
6 changed files with 125 additions and 5 deletions

View File

@ -16,5 +16,5 @@ exclude = [
"fuzzers/libfuzzer_stb_image", "fuzzers/libfuzzer_stb_image",
"fuzzers/libfuzzer_libmozjpeg", "fuzzers/libfuzzer_libmozjpeg",
"fuzzers/frida_libpng", "fuzzers/frida_libpng",
"fuzzers/qemu_user", "fuzzers/baby_fuzzer",
] ]

1
fuzzers/baby_fuzzer/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
libpng-*

View File

@ -0,0 +1,22 @@
[package]
name = "baby_fuzzer"
version = "0.1.0"
authors = ["Andrea Fioraldi <andreafioraldi@gmail.com>", "Dominik Maier <domenukk@gmail.com>"]
edition = "2018"
[features]
default = ["std"]
std = []
[profile.dev]
panic = "abort"
[profile.release]
panic = "abort"
lto = true
codegen-units = 1
opt-level = 3
debug = true
[dependencies]
libafl = { path = "../../libafl/" }

View File

@ -0,0 +1,3 @@
# Baby fuzzer

View File

@ -0,0 +1,94 @@
use std::path::PathBuf;
use libafl::{
bolts::tuples::tuple_list,
corpus::{InMemoryCorpus, OnDiskCorpus, QueueCorpusScheduler},
events::SimpleEventManager,
executors::{inprocess::InProcessExecutor, ExitKind},
feedbacks::{CrashFeedback, MaxMapFeedback},
fuzzer::{Fuzzer, StdFuzzer},
generators::RandPrintablesGenerator,
mutators::scheduled::{havoc_mutations, StdScheduledMutator},
observers::StdMapObserver,
stages::mutational::StdMutationalStage,
state::State,
stats::SimpleStats,
utils::{current_nanos, StdRand},
};
static mut SIGNALS: [u8; 16] = [0; 16];
pub fn main() {
// The closure that we want to fuzz
let mut harness = |buf: &[u8]| {
unsafe { SIGNALS[0] = 1 };
if buf.len() > 0 && buf[0] == 'a' as u8 {
unsafe { SIGNALS[1] = 1 };
if buf.len() > 1 && buf[1] == 'b' as u8 {
unsafe { SIGNALS[2] = 1 };
if buf.len() > 2 && buf[2] == 'c' as u8 {
panic!("=)");
}
}
}
ExitKind::Ok
};
// The Stats trait define how the fuzzer stats are reported to the user
let stats = SimpleStats::new(|s| println!("{}", s));
// The event manager handle the various events generated during the fuzzing loop
// such as the notification of the addition of a new item to the corpus
let mut mgr = SimpleEventManager::new(stats);
// Create an observation channel using the siganls map
let observer =
StdMapObserver::new("signals", unsafe { &mut SIGNALS }, unsafe { SIGNALS.len() });
// create a State from scratch
let mut state = State::new(
// RNG
StdRand::with_seed(current_nanos()),
// Corpus that will be evolved, we keep it in memory for performance
InMemoryCorpus::new(),
// Feedbacks to rate the interestingness of an input
tuple_list!(MaxMapFeedback::new(&observer)),
// Corpus in which we store solutions (crashes in this example),
// on disk so the user can get them after stopping the fuzzer
OnDiskCorpus::new(PathBuf::from("./crashes")).unwrap(),
// Feedbacks to recognize an input as solution
tuple_list!(CrashFeedback::new()),
);
// Setup a basic mutator with a mutational stage
let mutator = StdScheduledMutator::new(havoc_mutations());
let stage = StdMutationalStage::new(mutator);
// A fuzzer with just one stage
let mut fuzzer = StdFuzzer::new(tuple_list!(stage));
// A queue policy to get testcasess from the corpus
let scheduler = QueueCorpusScheduler::new();
// Create the executor for an in-process function with just one observer
let mut executor = InProcessExecutor::new(
"in-process(signals)",
&mut harness,
tuple_list!(observer),
&mut state,
&mut mgr,
)
.expect("Failed to create the Executor".into());
// Generator of printable bytearrays of max size 32
let mut generator = RandPrintablesGenerator::new(32);
// Generate 8 initial inputs
state
.generate_initial_inputs(&mut executor, &mut generator, &mut mgr, &scheduler, 8)
.expect("Failed to generate the initial corpus".into());
fuzzer
.fuzz_loop(&mut state, &mut executor, &mut mgr, &scheduler)
.expect("Error in the fuzzing loop".into());
}

View File

@ -84,8 +84,8 @@ where
time, time,
executions, executions,
} => { } => {
stats.client_stats_mut()[0].update_corpus_size(*corpus_size as u64); stats.client_stats_mut_for(0).update_corpus_size(*corpus_size as u64);
stats.client_stats_mut()[0].update_executions(*executions as u64, *time); stats.client_stats_mut_for(0).update_executions(*executions as u64, *time);
stats.display(event.name().to_string()); stats.display(event.name().to_string());
Ok(BrokerEventResult::Handled) Ok(BrokerEventResult::Handled)
} }
@ -95,12 +95,12 @@ where
phantom: _, phantom: _,
} => { } => {
// TODO: The stats buffer should be added on client add. // TODO: The stats buffer should be added on client add.
stats.client_stats_mut()[0].update_executions(*executions as u64, *time); stats.client_stats_mut_for(0).update_executions(*executions as u64, *time);
stats.display(event.name().to_string()); stats.display(event.name().to_string());
Ok(BrokerEventResult::Handled) Ok(BrokerEventResult::Handled)
} }
Event::Objective { objective_size } => { Event::Objective { objective_size } => {
stats.client_stats_mut()[0].update_objective_size(*objective_size as u64); stats.client_stats_mut_for(0).update_objective_size(*objective_size as u64);
stats.display(event.name().to_string()); stats.display(event.name().to_string());
Ok(BrokerEventResult::Handled) Ok(BrokerEventResult::Handled)
} }