mirror of
https://github.com/epi052/feroxbuster.git
synced 2026-04-19 06:31:13 -03:00
resume scan starts from offset in wordlist
This commit is contained in:
@@ -218,7 +218,7 @@ impl ScanHandler {
|
||||
// current number of requests expected per scan
|
||||
// ExpectedPerScan and TotalExpected are a += action, so we need the wordlist length to
|
||||
// update them while the other updates use expected_num_requests_per_dir
|
||||
let num_words = self.get_wordlist()?.len();
|
||||
let num_words = self.get_wordlist(0)?.len();
|
||||
let current_expectation = self.handles.expected_num_requests_per_dir() as u64;
|
||||
|
||||
// used in the calculation of bar width down below, see explanation there
|
||||
@@ -290,10 +290,19 @@ impl ScanHandler {
|
||||
}
|
||||
|
||||
/// Helper to easily get the (locked) underlying wordlist
|
||||
pub fn get_wordlist(&self) -> Result<Arc<Vec<String>>> {
|
||||
pub fn get_wordlist(&self, offset: usize) -> Result<Arc<Vec<String>>> {
|
||||
if let Ok(guard) = self.wordlist.lock().as_ref() {
|
||||
if let Some(list) = guard.as_ref() {
|
||||
return Ok(list.clone());
|
||||
return if offset > 0 {
|
||||
// the offset could be off a bit, so we'll adjust it backwards by 10%
|
||||
// of the overall wordlist size to ensure we don't miss any words
|
||||
// (hopefully)
|
||||
let adjusted_offset = offset - ((offset as f64 * 0.10) as usize);
|
||||
|
||||
Ok(Arc::new(list[adjusted_offset..].to_vec()))
|
||||
} else {
|
||||
Ok(list.clone())
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +337,7 @@ impl ScanHandler {
|
||||
continue;
|
||||
}
|
||||
|
||||
let list = self.get_wordlist()?;
|
||||
let list = self.get_wordlist(scan.requests() as usize)?;
|
||||
|
||||
log::info!("scan handler received {} - beginning scan", target);
|
||||
|
||||
|
||||
@@ -354,6 +354,7 @@ impl Serialize for FeroxScan {
|
||||
state.serialize_field("scan_type", &self.scan_type)?;
|
||||
state.serialize_field("status", &self.status)?;
|
||||
state.serialize_field("num_requests", &self.num_requests)?;
|
||||
state.serialize_field("requests_made_so_far", &self.requests())?;
|
||||
|
||||
state.end()
|
||||
}
|
||||
@@ -367,6 +368,7 @@ impl<'de> Deserialize<'de> for FeroxScan {
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let mut scan = Self::default();
|
||||
let mut progress_bar_position = 0;
|
||||
|
||||
let map: HashMap<String, Value> = HashMap::deserialize(deserializer)?;
|
||||
|
||||
@@ -412,10 +414,17 @@ impl<'de> Deserialize<'de> for FeroxScan {
|
||||
scan.num_requests = num_requests;
|
||||
}
|
||||
}
|
||||
"requests_made_so_far" => {
|
||||
if let Some(requests_made_so_far) = value.as_u64() {
|
||||
progress_bar_position = requests_made_so_far;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
scan.progress_bar().set_position(progress_bar_position);
|
||||
|
||||
Ok(scan)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ fn ferox_scan_get_progress_bar_when_none_is_set() {
|
||||
/// given a JSON entry representing a FeroxScan, test that it deserializes into the proper type
|
||||
/// with the right attributes
|
||||
fn ferox_scan_deserialize() {
|
||||
let fs_json = r#"{"id":"057016a14769414aac9a7a62707598cb","url":"https://spiritanimal.com","scan_type":"Directory","status":"Complete"}"#;
|
||||
let fs_json = r#"{"id":"057016a14769414aac9a7a62707598cb","url":"https://spiritanimal.com","scan_type":"Directory","status":"Complete","requests_made_so_far":500}"#;
|
||||
let fs_json_two = r#"{"id":"057016a14769414aac9a7a62707598cb","url":"https://spiritanimal.com","scan_type":"Not Correct","status":"Cancelled"}"#;
|
||||
let fs_json_three = r#"{"id":"057016a14769414aac9a7a62707598cb","url":"https://spiritanimal.com","scan_type":"Not Correct","status":"","num_requests":42}"#;
|
||||
|
||||
@@ -246,9 +246,23 @@ fn ferox_scan_deserialize() {
|
||||
ScanType::File => {}
|
||||
}
|
||||
|
||||
match *fs.progress_bar.lock().unwrap() {
|
||||
None => {}
|
||||
Some(_) => {
|
||||
match fs.progress_bar.lock() {
|
||||
Ok(guard) => {
|
||||
match guard.as_ref() {
|
||||
Some(pb) => {
|
||||
// position based on the requests made so far
|
||||
//
|
||||
// note: when this goes through the actual deserialize function, the
|
||||
// progress bar will be set to the total requests made so far, -10%
|
||||
// (i.e. 450 in this case)
|
||||
assert_eq!(pb.position(), 500);
|
||||
}
|
||||
None => {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
@@ -277,7 +291,7 @@ fn ferox_scan_serialize() {
|
||||
None,
|
||||
);
|
||||
let fs_json = format!(
|
||||
r#"{{"id":"{}","url":"https://spiritanimal.com","normalized_url":"https://spiritanimal.com/","scan_type":"Directory","status":"NotStarted","num_requests":0}}"#,
|
||||
r#"{{"id":"{}","url":"https://spiritanimal.com","normalized_url":"https://spiritanimal.com/","scan_type":"Directory","status":"NotStarted","num_requests":0,"requests_made_so_far":0}}"#,
|
||||
fs.id
|
||||
);
|
||||
assert_eq!(fs_json, serde_json::to_string(&*fs).unwrap());
|
||||
@@ -296,7 +310,7 @@ fn ferox_scans_serialize() {
|
||||
);
|
||||
let ferox_scans = FeroxScans::default();
|
||||
let ferox_scans_json = format!(
|
||||
r#"[{{"id":"{}","url":"https://spiritanimal.com","normalized_url":"https://spiritanimal.com/","scan_type":"Directory","status":"NotStarted","num_requests":0}}]"#,
|
||||
r#"[{{"id":"{}","url":"https://spiritanimal.com","normalized_url":"https://spiritanimal.com/","scan_type":"Directory","status":"NotStarted","num_requests":0,"requests_made_so_far":0}}]"#,
|
||||
ferox_scan.id
|
||||
);
|
||||
ferox_scans.scans.write().unwrap().push(ferox_scan);
|
||||
|
||||
@@ -20,12 +20,12 @@ fn resume_scan_works() {
|
||||
// localhost:PORT/ <- complete
|
||||
// localhost:PORT/js <- will get scanned with /css and /stuff
|
||||
let complete_scan = format!(
|
||||
r#"{{"id":"057016a14769414aac9a7a62707598cb","url":"{}","normalized_url":"{}","scan_type":"Directory","status":"Complete"}}"#,
|
||||
r#"{{"id":"057016a14769414aac9a7a62707598cb","url":"{}","normalized_url":"{}","scan_type":"Directory","status":"Complete","num_requests":4174,"requests_made_so_far":0}}"#,
|
||||
srv.url("/"),
|
||||
srv.url("/"),
|
||||
);
|
||||
let incomplete_scan = format!(
|
||||
r#"{{"id":"400b2323a16f43468a04ffcbbeba34c6","url":"{}","normalized_url":"{}/","scan_type":"Directory","status":"NotStarted"}}"#,
|
||||
r#"{{"id":"400b2323a16f43468a04ffcbbeba34c6","url":"{}","normalized_url":"{}/","scan_type":"Directory","status":"NotStarted","num_requests":4174,"requests_made_so_far":0}}"#,
|
||||
srv.url("/js"),
|
||||
srv.url("/js")
|
||||
);
|
||||
@@ -64,10 +64,13 @@ fn resume_scan_works() {
|
||||
});
|
||||
|
||||
let state_file_contents = format!("{{{scans},{config},{responses}}}");
|
||||
|
||||
let (tmp_dir2, state_file) = setup_tmp_directory(&[state_file_contents], "state-file").unwrap();
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("-vvv")
|
||||
.arg("--burp")
|
||||
.arg("--resume-from")
|
||||
.arg(state_file.as_os_str())
|
||||
.assert()
|
||||
|
||||
Reference in New Issue
Block a user