Merge pull request #220 from bpsizemore/219-sslerrors

Added SSL specific error to "could not connect message" fixes #219
This commit is contained in:
epi
2021-02-17 07:42:18 -06:00
committed by GitHub
7 changed files with 66 additions and 79 deletions

34
Cargo.lock generated
View File

@@ -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",
]

View File

@@ -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"

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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]

View File

@@ -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)

View File

@@ -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]