feroxresponse accepts output_level instead of quiet

This commit is contained in:
epi
2021-02-02 20:31:53 -06:00
parent 766fe567a5
commit 45d5d73cd6
8 changed files with 52 additions and 35 deletions

View File

@@ -376,6 +376,7 @@ A pre-made configuration file with examples of all available settings can be fou
# scan_limit = 6
# rate_limit = 250
# quiet = true
# silent = true
# json = true
# output = "/targets/ellingson_mineral_company/gibson.txt"
# debug_log = "/var/log/find-the-derp.log"
@@ -538,7 +539,7 @@ same goes for urls, headers, status codes, queries, and size filters.
### Read urls from STDIN; pipe only resulting urls out to another tool
```
cat targets | ./feroxbuster --stdin --quiet -s 200 301 302 --redirects -x js | fff -s 200 -o js-files
cat targets | ./feroxbuster --stdin --silent -s 200 301 302 --redirects -x js | fff -s 200 -o js-files
```
### Proxy traffic through Burp

View File

@@ -19,6 +19,7 @@
# scan_limit = 6
# rate_limit = 250
# quiet = true
# silent = true
# json = true
# output = "/targets/ellingson_mineral_company/gibson.txt"
# debug_log = "/var/log/find-the-derp.log"

View File

@@ -547,22 +547,22 @@ impl Configuration {
if args.is_present("silent") {
// the reason this is protected by an if statement:
// consider a user specifying quiet = true in ferox-config.toml
// consider a user specifying silent = true in ferox-config.toml
// if the line below is outside of the if, we'd overwrite true with
// false if no -q is used on the command line
// false if no --silent is used on the command line
config.silent = true;
config.output_level = OutputLevel::Silent;
}
if args.is_present("dont_filter") {
config.dont_filter = true;
}
if args.is_present("quiet") {
config.quiet = true;
config.output_level = OutputLevel::Quiet;
}
if args.is_present("dont_filter") {
config.dont_filter = true;
}
if args.occurrences_of("verbosity") > 0 {
// occurrences_of returns 0 if none are found; this is protected in
// an if block for the same reason as the quiet option

View File

@@ -4,11 +4,12 @@ use anyhow::{bail, Result};
use console::style;
use uuid::Uuid;
use crate::response::FeroxResponse;
use crate::{
config::OutputLevel,
event_handlers::{Command, Handles},
filters::WildcardFilter,
progress::PROGRESS_PRINTER,
response::FeroxResponse,
skip_fail,
url::FeroxUrl,
utils::{ferox_print, fmt_err, make_request, status_colorizer},
@@ -116,14 +117,20 @@ impl HeuristicTests {
wildcard.dynamic = wc_length - url_len;
if !self.handles.config.silent {
if matches!(
handles.config.output_level,
OutputLevel::Default | OutputLevel::Quiet
) {
let msg = format_template!("{} {:>9} {:>9} {:>9} Wildcard response is dynamic; {} ({} + url length) responses; toggle this behavior by using {}\n", wildcard.dynamic);
ferox_print(&msg, &PROGRESS_PRINTER);
}
} else if wc_length == wc2_length {
wildcard.size = wc_length;
if !self.handles.config.silent {
if matches!(
handles.config.output_level,
OutputLevel::Default | OutputLevel::Quiet
) {
let msg = format_template!("{} {:>9} {:>9} {:>9} Wildcard response is static; {} {} responses; toggle this behavior by using {}\n", wildcard.size);
ferox_print(&msg, &PROGRESS_PRINTER);
}
@@ -179,7 +186,10 @@ impl HeuristicTests {
bail!("filtered response")
}
if !self.handles.config.silent {
if matches!(
handles.config.output_level,
OutputLevel::Default | OutputLevel::Quiet
) {
let boxed = Box::new(ferox_response.clone());
self.handles.output.send(Command::Report(boxed))?;
}
@@ -218,7 +228,10 @@ impl HeuristicTests {
good_urls.push(target_url.to_owned());
}
Err(e) => {
if !self.handles.config.silent {
if matches!(
handles.config.output_level,
OutputLevel::Default | OutputLevel::Quiet
) {
ferox_print(
&format!("Could not connect to {}, skipping...", target_url),
&PROGRESS_PRINTER,

View File

@@ -12,7 +12,7 @@ use tokio_util::codec::{FramedRead, LinesCodec};
use feroxbuster::{
banner::{Banner, UPDATE_URL},
config::Configuration,
config::{Configuration, OutputLevel},
event_handlers::{
Command::{CreateBar, Exit, JoinTasks, LoadStats, ScanInitialUrls, UpdateWordlist},
FiltersHandler, Handles, ScanHandler, StatsHandler, Tasks, TermInputHandler,
@@ -89,8 +89,8 @@ async fn scan(targets: Vec<String>, handles: Arc<Handles>) -> Result<()> {
// - scanner initialized (this sent expected requests per directory to the stats thread, which
// having been set, makes it so the progress bar doesn't flash as full before anything has
// even happened
if !handles.config.silent {
// only create the bar if -q hasn't been used
if matches!(handles.config.output_level, OutputLevel::Default) {
// only create the bar if no --silent|--quiet
handles.stats.send(CreateBar)?;
// blocks until the bar is created / avoids race condition in first two bars
@@ -228,8 +228,8 @@ async fn wrapped_main(config: Arc<Configuration>) -> Result<()> {
}
};
if !config.silent {
// only print banner if -q isn't used
if matches!(config.output_level, OutputLevel::Default) {
// only print banner if output level is default (no banner on --quiet|--silent)
let std_stderr = stderr(); // std::io::stderr
let mut banner = Banner::new(&targets, &config);

View File

@@ -16,6 +16,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::Value;
use crate::{
config::OutputLevel,
event_handlers::{Command, Handles},
traits::FeroxSerialize,
url::FeroxUrl,
@@ -50,8 +51,8 @@ pub struct FeroxResponse {
/// Wildcard response status
wildcard: bool,
/// whether the user passed -q on the command line
pub(crate) quiet: bool,
/// whether the user passed --quiet|--silent on the command line
pub(crate) output_level: OutputLevel,
}
/// implement Default trait for FeroxResponse
@@ -67,7 +68,7 @@ impl Default for FeroxResponse {
word_count: 0,
headers: Default::default(),
wildcard: false,
quiet: false,
output_level: Default::default(),
}
}
}
@@ -185,7 +186,7 @@ impl FeroxResponse {
}
/// Create a new `FeroxResponse` from the given `Response`
pub async fn from(response: Response, read_body: bool, quiet: bool) -> Self {
pub async fn from(response: Response, read_body: bool, output_level: OutputLevel) -> Self {
let url = response.url().clone();
let status = response.status();
let headers = response.headers().clone();
@@ -218,7 +219,7 @@ impl FeroxResponse {
headers,
line_count,
word_count,
quiet,
output_level,
wildcard: false,
}
}
@@ -327,8 +328,8 @@ impl FeroxSerialize for FeroxResponse {
let status = self.status().as_str();
let wild_status = status_colorizer("WLD");
if self.wildcard && !self.quiet {
// -q was not used and response is a wildcard, special messages abound when
if self.wildcard && matches!(self.output_level, OutputLevel::Default | OutputLevel::Quiet) {
// --silent was not used and response is a wildcard, special messages abound when
// this is the case...
// create the base message
@@ -372,7 +373,7 @@ impl FeroxSerialize for FeroxResponse {
&words,
&chars,
self.url().as_str(),
self.quiet,
self.output_level,
)
}
}
@@ -459,7 +460,7 @@ impl<'de> Deserialize<'de> for FeroxResponse {
content_length: 0,
headers: HeaderMap::new(),
wildcard: false,
quiet: false,
output_level: Default::default(),
line_count: 0,
word_count: 0,
};
@@ -546,7 +547,7 @@ mod tests {
word_count: 0,
headers: Default::default(),
wildcard: false,
quiet: false,
output_level: Default::default(),
};
let result = response.reached_max_depth(0, 0, handles);
assert!(!result);
@@ -567,7 +568,7 @@ mod tests {
word_count: 0,
headers: Default::default(),
wildcard: false,
quiet: false,
output_level: Default::default(),
};
let result = response.reached_max_depth(0, 2, handles);
@@ -588,7 +589,7 @@ mod tests {
word_count: 0,
headers: Default::default(),
wildcard: false,
quiet: false,
output_level: Default::default(),
};
let result = response.reached_max_depth(0, 2, handles);
@@ -609,7 +610,7 @@ mod tests {
word_count: 0,
headers: Default::default(),
wildcard: false,
quiet: false,
output_level: Default::default(),
};
let result = response.reached_max_depth(2, 2, handles);
@@ -630,7 +631,7 @@ mod tests {
word_count: 0,
headers: Default::default(),
wildcard: false,
quiet: false,
output_level: Default::default(),
};
let result = response.reached_max_depth(0, 2, handles);

View File

@@ -11,6 +11,7 @@ use std::{
use tokio::sync::mpsc::UnboundedSender;
use crate::{
config::OutputLevel,
event_handlers::Command::{self, AddError, AddStatus},
progress::PROGRESS_PRINTER,
send_command,
@@ -160,10 +161,10 @@ pub fn create_report_string(
word_count: &str,
content_length: &str,
url: &str,
quiet: bool,
output_level: OutputLevel,
) -> String {
if quiet {
// -q used, just need the url
if matches!(output_level, OutputLevel::Silent) {
// --silent used, just need the url
format!("{}\n", url)
} else {
// normal printing with status and sizes

View File

@@ -30,7 +30,7 @@ fn resume_scan_works() {
let scans = format!(r#""scans":[{},{}]"#, complete_scan, incomplete_scan);
let config = format!(
r#""config": {{"type":"configuration","wordlist":"{}","config":"","proxy":"","replay_proxy":"","target_url":"{}","status_codes":[200,204,301,302,307,308,401,403,405],"replay_codes":[200,204,301,302,307,308,401,403,405],"filter_status":[],"threads":50,"timeout":7,"verbosity":0,"quiet":false,"json":false,"output":"","debug_log":"","user_agent":"feroxbuster/1.9.0","redirects":false,"insecure":false,"extensions":[],"headers":{{}},"queries":[],"no_recursion":false,"extract_links":false,"add_slash":false,"stdin":false,"depth":2,"scan_limit":1,"filter_size":[],"filter_line_count":[],"filter_word_count":[],"filter_regex":[],"dont_filter":false}}"#,
r#""config": {{"type":"configuration","wordlist":"{}","config":"","proxy":"","replay_proxy":"","target_url":"{}","status_codes":[200,204,301,302,307,308,401,403,405],"replay_codes":[200,204,301,302,307,308,401,403,405],"filter_status":[],"threads":50,"timeout":7,"verbosity":0,"silent":false,"quiet":false,"json":false,"output":"","debug_log":"","user_agent":"feroxbuster/1.9.0","redirects":false,"insecure":false,"extensions":[],"headers":{{}},"queries":[],"no_recursion":false,"extract_links":false,"add_slash":false,"stdin":false,"depth":2,"scan_limit":1,"filter_size":[],"filter_line_count":[],"filter_word_count":[],"filter_regex":[],"dont_filter":false}}"#,
file.to_string_lossy(),
srv.url("/")
);