use feroxfuzz::client::{BlockingClient, HttpClient};
use feroxfuzz::corpora::{RangeCorpus, Wordlist};
use feroxfuzz::fuzzers::{BlockingFuzzer, BlockingFuzzing};
use feroxfuzz::mutators::ReplaceKeyword;
use feroxfuzz::observers::ResponseObserver;
use feroxfuzz::prelude::*;
use feroxfuzz::processors::RequestProcessor;
use feroxfuzz::requests::ShouldFuzz;
use feroxfuzz::responses::BlockingResponse;
use feroxfuzz::schedulers::OrderedScheduler;
use feroxfuzz::state::SharedState;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let wordlist = Wordlist::new()
.word("a")
.word("b")
.word("c")
.name("chars")
.build();
let range1 = RangeCorpus::new().name("range1").stop(3).build()?;
let range2 = RangeCorpus::new()
.name("range2")
.start(4)
.stop(9)
.step(2)
.build()?;
let corpora = [range1, wordlist, range2];
let mut state = SharedState::with_corpora(corpora);
let req_client = reqwest::blocking::Client::builder().build()?;
let client = BlockingClient::with_client(req_client);
let mutator1 = ReplaceKeyword::new(&"RANGE1", "range1");
let mutator2 = ReplaceKeyword::new(&"CHARS", "chars");
let mutator3 = ReplaceKeyword::new(&"RANGE2", "range2");
let request = Request::from_url(
"http://localhost:8000/",
Some(&[ShouldFuzz::URLParameterValue(
b"injectable=/RANGE1/CHARS/RANGE2",
b"=",
)]),
)?;
let scheduler = OrderedScheduler::new(state.clone())?;
let request_printer = RequestProcessor::new(|request, _action, _state| {
print!("{}?", request.original_url());
for (key, value) in request.params().unwrap().iter() {
print!("{key}={value}");
}
println!();
});
let response_observer: ResponseObserver<BlockingResponse> = ResponseObserver::new();
let observers = build_observers!(response_observer);
let mutators = build_mutators!(mutator1, mutator2, mutator3);
let processors = build_processors!(request_printer);
let mut fuzzer = BlockingFuzzer::new()
.client(client)
.request(request)
.scheduler(scheduler)
.mutators(mutators)
.observers(observers)
.processors(processors)
.build();
fuzzer.fuzz_n_iterations(2, &mut state)?;
Ok(())
}