mirror of
https://github.com/epi052/feroxbuster.git
synced 2026-05-30 19:41:12 -03:00
feroxresponse accepts output_level instead of quiet
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
10
src/main.rs
10
src/main.rs
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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("/")
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user