mirror of
https://github.com/epi052/feroxbuster.git
synced 2026-06-07 01:51:12 -03:00
Merge pull request #220 from bpsizemore/219-sslerrors
Added SSL specific error to "could not connect message" fixes #219
This commit is contained in:
34
Cargo.lock
generated
34
Cargo.lock
generated
@@ -633,7 +633,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "feroxbuster"
|
||||
version = "2.0.1"
|
||||
version = "2.0.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_cmd",
|
||||
@@ -687,7 +687,7 @@ checksum = "531a685ab99b8f60a271b44d5dd1a76e55124a8c9fa0407b7a8e9cd172d5b588"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project 1.0.5",
|
||||
"pin-project",
|
||||
"spinning_top",
|
||||
]
|
||||
|
||||
@@ -990,7 +990,7 @@ dependencies = [
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project 1.0.5",
|
||||
"pin-project",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
@@ -1459,33 +1459,13 @@ version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b9b4df73455c861d7cbf8be42f01d3b373ed7f02e378d55fa84eafc6f638b1"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffbc8e94b38ea3d2d8ba92aea2983b503cd75d0888d75b86bb37970b5698e15"
|
||||
dependencies = [
|
||||
"pin-project-internal 0.4.27",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96fa8ebb90271c4477f144354485b8068bd8f6b78b428b01ba892ca26caf0b63"
|
||||
dependencies = [
|
||||
"pin-project-internal 1.0.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65ad2ae56b6abe3a1ee25f15ee605bacadb9a764edaba9c2bf4103800d4a1895"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2232,11 +2212,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-futures"
|
||||
version = "0.2.4"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab7bb6f14721aa00656086e9335d363c5c8747bae02ebe32ea2c7dece5689b4c"
|
||||
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
|
||||
dependencies = [
|
||||
"pin-project 0.4.27",
|
||||
"pin-project",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "feroxbuster"
|
||||
version = "2.0.1"
|
||||
version = "2.0.2"
|
||||
authors = ["Ben 'epi' Risher <epibar052@gmail.com>"]
|
||||
license = "MIT"
|
||||
edition = "2018"
|
||||
|
||||
@@ -374,7 +374,7 @@ impl Configuration {
|
||||
|
||||
// read in the user provided options, this produces a separate instance of Configuration
|
||||
// in order to allow for potentially merging into a --resume-from Configuration
|
||||
let cli_config = Self::parse_cli_args(&args)?;
|
||||
let cli_config = Self::parse_cli_args(&args);
|
||||
|
||||
// --resume-from used, need to first read the Configuration from disk, and then
|
||||
// merge the cli_config into the resumed config
|
||||
@@ -461,7 +461,7 @@ impl Configuration {
|
||||
|
||||
/// Given a set of ArgMatches read from the CLI, update and return the default Configuration
|
||||
/// settings
|
||||
fn parse_cli_args(args: &ArgMatches) -> Result<Self> {
|
||||
fn parse_cli_args(args: &ArgMatches) -> Self {
|
||||
let mut config = Configuration::default();
|
||||
|
||||
update_config_if_present!(&mut config.threads, args, "threads", usize);
|
||||
@@ -636,7 +636,7 @@ impl Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(config)
|
||||
config
|
||||
}
|
||||
|
||||
/// this function determines if we've gotten a Client configuration change from
|
||||
|
||||
@@ -232,10 +232,17 @@ impl HeuristicTests {
|
||||
self.handles.config.output_level,
|
||||
OutputLevel::Default | OutputLevel::Quiet
|
||||
) {
|
||||
ferox_print(
|
||||
&format!("Could not connect to {}, skipping...", target_url),
|
||||
&PROGRESS_PRINTER,
|
||||
);
|
||||
if e.to_string().contains(":SSL") {
|
||||
ferox_print(
|
||||
&format!("Could not connect to {} due to SSL errors (run with -k to ignore), skipping...", target_url),
|
||||
&PROGRESS_PRINTER,
|
||||
);
|
||||
} else {
|
||||
ferox_print(
|
||||
&format!("Could not connect to {}, skipping...", target_url),
|
||||
&PROGRESS_PRINTER,
|
||||
);
|
||||
}
|
||||
}
|
||||
log::warn!("{}", e);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ fn banner_prints_replay_proxy() -> Result<(), Box<dyn std::error::Error>> {
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + multiple headers
|
||||
fn banner_prints_headers() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_headers() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -111,7 +111,6 @@ fn banner_prints_headers() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("mostuff: mothings"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -161,7 +160,7 @@ fn banner_prints_filter_sizes() {
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + queries
|
||||
fn banner_prints_queries() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_queries() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -186,13 +185,12 @@ fn banner_prints_queries() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("stuff=things"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + status codes
|
||||
fn banner_prints_status_codes() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_status_codes() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -213,13 +211,12 @@ fn banner_prints_status_codes() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("[201, 301, 401]"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + replay codes
|
||||
fn banner_prints_replay_codes() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_replay_codes() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -244,13 +241,12 @@ fn banner_prints_replay_codes() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("[200, 302]"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + output file
|
||||
fn banner_prints_output_file() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_output_file() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -275,13 +271,12 @@ fn banner_prints_output_file() -> Result<(), Box<dyn std::error::Error>> {
|
||||
))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + insecure
|
||||
fn banner_prints_insecure() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_insecure() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -302,13 +297,12 @@ fn banner_prints_insecure() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("true"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + follow redirects
|
||||
fn banner_prints_redirects() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_redirects() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -329,13 +323,12 @@ fn banner_prints_redirects() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("true"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + extensions
|
||||
fn banner_prints_extensions() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_extensions() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -359,13 +352,12 @@ fn banner_prints_extensions() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("[js, pdf]"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + dont_filter
|
||||
fn banner_prints_dont_filter() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_dont_filter() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -386,13 +378,12 @@ fn banner_prints_dont_filter() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("false"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + verbosity=1
|
||||
fn banner_prints_verbosity_one() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_verbosity_one() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -413,13 +404,12 @@ fn banner_prints_verbosity_one() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("│ 1"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + verbosity=2
|
||||
fn banner_prints_verbosity_two() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_verbosity_two() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -440,13 +430,12 @@ fn banner_prints_verbosity_two() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("│ 2"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + verbosity=3
|
||||
fn banner_prints_verbosity_three() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_verbosity_three() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -467,13 +456,12 @@ fn banner_prints_verbosity_three() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("│ 3"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + verbosity=4
|
||||
fn banner_prints_verbosity_four() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_verbosity_four() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -494,13 +482,12 @@ fn banner_prints_verbosity_four() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("│ 4"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + add slash
|
||||
fn banner_prints_add_slash() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_add_slash() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -521,13 +508,12 @@ fn banner_prints_add_slash() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("true"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + INFINITE recursion
|
||||
fn banner_prints_infinite_depth() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_infinite_depth() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -549,13 +535,12 @@ fn banner_prints_infinite_depth() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("INFINITE"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + recursion depth
|
||||
fn banner_prints_recursion_depth() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_recursion_depth() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -577,13 +562,12 @@ fn banner_prints_recursion_depth() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("343214"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + no recursion
|
||||
fn banner_prints_no_recursion() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_no_recursion() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -604,13 +588,12 @@ fn banner_prints_no_recursion() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("true"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see nothing
|
||||
fn banner_doesnt_print() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_doesnt_print() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -621,13 +604,12 @@ fn banner_doesnt_print() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.stderr(predicate::str::contains(
|
||||
"Could not connect to any target provided",
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + extract-links
|
||||
fn banner_prints_extract_links() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_extract_links() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -648,13 +630,12 @@ fn banner_prints_extract_links() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("true"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + scan-limit
|
||||
fn banner_prints_scan_limit() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_scan_limit() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -676,13 +657,12 @@ fn banner_prints_scan_limit() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("│ 4"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test allows non-existent wordlist to trigger the banner printing to stderr
|
||||
/// expect to see all mandatory prints + filter-status
|
||||
fn banner_prints_filter_status() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn banner_prints_filter_status() {
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
@@ -704,7 +684,6 @@ fn banner_prints_filter_status() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.and(predicate::str::contains("│ [200]"))
|
||||
.and(predicate::str::contains("─┴─")),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -90,6 +90,28 @@ fn test_one_good_and_one_bad_target_scan_succeeds() -> Result<(), Box<dyn std::e
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test passes one target with SSL issues via -u to the scanner, expected result is that the
|
||||
/// scanner dies and prints an SSL specific error message
|
||||
fn test_single_target_cannot_connect_due_to_ssl_errors() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let (tmp_dir, file) = setup_tmp_directory(&["LICENSE".to_string()], "wordlist")?;
|
||||
|
||||
Command::cargo_bin("feroxbuster")
|
||||
.unwrap()
|
||||
.arg("--url")
|
||||
.arg("https://expired.badssl.com")
|
||||
.arg("--wordlist")
|
||||
.arg(file.as_os_str())
|
||||
.assert()
|
||||
.success()
|
||||
.stdout(
|
||||
predicate::str::contains("Could not connect to https://expired.badssl.com due to SSL errors (run with -k to ignore), skipping...", )
|
||||
);
|
||||
|
||||
teardown_tmp_directory(tmp_dir);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// test pipes two good targets to the scanner, expected result is that both targets
|
||||
/// are scanned successfully and no error is reported (result of issue #169)
|
||||
|
||||
@@ -7,7 +7,7 @@ use utils::{setup_tmp_directory, teardown_tmp_directory};
|
||||
|
||||
#[test]
|
||||
/// send the function a file to which we dont have permission in order to execute error branch
|
||||
fn main_use_root_owned_file_as_wordlist() -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn main_use_root_owned_file_as_wordlist() {
|
||||
let srv = MockServer::start();
|
||||
|
||||
let mock = srv.mock(|when, then| {
|
||||
@@ -30,7 +30,6 @@ fn main_use_root_owned_file_as_wordlist() -> Result<(), Box<dyn std::error::Erro
|
||||
|
||||
// connectivity test hits it once
|
||||
assert_eq!(mock.hits(), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user