mirror of
https://github.com/epi052/feroxbuster.git
synced 2026-06-08 02:31:16 -03:00
silent and quiet are gtg
This commit is contained in:
@@ -60,9 +60,9 @@ _feroxbuster() {
|
||||
'--scan-limit=[Limit total number of concurrent scans (default: 0, i.e. no limit)]' \
|
||||
'--rate-limit=[Limit number of requests per second (per directory) (default: 0, i.e. no limit)]' \
|
||||
'--time-limit=[Limit total run time of all scans (ex: --time-limit 10m)]' \
|
||||
'*-v[Increase verbosity level (use -vv or more for greater effect. \[CAUTION\] 4 -v'\''s is probably too much)]' \
|
||||
'*--verbosity[Increase verbosity level (use -vv or more for greater effect. \[CAUTION\] 4 -v'\''s is probably too much)]' \
|
||||
'--silent[Only print URLs (good for piping a list of urls to other commands)]' \
|
||||
'(--silent)*-v[Increase verbosity level (use -vv or more for greater effect. \[CAUTION\] 4 -v'\''s is probably too much)]' \
|
||||
'(--silent)*--verbosity[Increase verbosity level (use -vv or more for greater effect. \[CAUTION\] 4 -v'\''s is probably too much)]' \
|
||||
'(-q --quiet)--silent[Only print URLs + turn off logging (good for piping a list of urls to other commands)]' \
|
||||
'-q[Hide progress bars and banner (good for tmux windows w/ notifications)]' \
|
||||
'--quiet[Hide progress bars and banner (good for tmux windows w/ notifications)]' \
|
||||
'--json[Emit JSON logs to --output and --debug-log instead of normal text]' \
|
||||
|
||||
@@ -67,7 +67,7 @@ Register-ArgumentCompleter -Native -CommandName 'feroxbuster' -ScriptBlock {
|
||||
[CompletionResult]::new('--time-limit', 'time-limit', [CompletionResultType]::ParameterName, 'Limit total run time of all scans (ex: --time-limit 10m)')
|
||||
[CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'Increase verbosity level (use -vv or more for greater effect. [CAUTION] 4 -v''s is probably too much)')
|
||||
[CompletionResult]::new('--verbosity', 'verbosity', [CompletionResultType]::ParameterName, 'Increase verbosity level (use -vv or more for greater effect. [CAUTION] 4 -v''s is probably too much)')
|
||||
[CompletionResult]::new('--silent', 'silent', [CompletionResultType]::ParameterName, 'Only print URLs (good for piping a list of urls to other commands)')
|
||||
[CompletionResult]::new('--silent', 'silent', [CompletionResultType]::ParameterName, 'Only print URLs + turn off logging (good for piping a list of urls to other commands)')
|
||||
[CompletionResult]::new('-q', 'q', [CompletionResultType]::ParameterName, 'Hide progress bars and banner (good for tmux windows w/ notifications)')
|
||||
[CompletionResult]::new('--quiet', 'quiet', [CompletionResultType]::ParameterName, 'Hide progress bars and banner (good for tmux windows w/ notifications)')
|
||||
[CompletionResult]::new('--json', 'json', [CompletionResultType]::ParameterName, 'Emit JSON logs to --output and --debug-log instead of normal text')
|
||||
|
||||
@@ -24,7 +24,7 @@ complete -c feroxbuster -n "__fish_use_subcommand" -s L -l scan-limit -d 'Limit
|
||||
complete -c feroxbuster -n "__fish_use_subcommand" -l rate-limit -d 'Limit number of requests per second (per directory) (default: 0, i.e. no limit)'
|
||||
complete -c feroxbuster -n "__fish_use_subcommand" -l time-limit -d 'Limit total run time of all scans (ex: --time-limit 10m)'
|
||||
complete -c feroxbuster -n "__fish_use_subcommand" -s v -l verbosity -d 'Increase verbosity level (use -vv or more for greater effect. [CAUTION] 4 -v\'s is probably too much)'
|
||||
complete -c feroxbuster -n "__fish_use_subcommand" -l silent -d 'Only print URLs (good for piping a list of urls to other commands)'
|
||||
complete -c feroxbuster -n "__fish_use_subcommand" -l silent -d 'Only print URLs + turn off logging (good for piping a list of urls to other commands)'
|
||||
complete -c feroxbuster -n "__fish_use_subcommand" -s q -l quiet -d 'Hide progress bars and banner (good for tmux windows w/ notifications)'
|
||||
complete -c feroxbuster -n "__fish_use_subcommand" -l json -d 'Emit JSON logs to --output and --debug-log instead of normal text'
|
||||
complete -c feroxbuster -n "__fish_use_subcommand" -s D -l dont-filter -d 'Don\'t auto-filter wildcard responses'
|
||||
|
||||
@@ -2,6 +2,7 @@ use super::utils::{
|
||||
depth, report_and_exit, save_state, serialized_type, status_codes, threads, timeout,
|
||||
user_agent, wordlist, OutputLevel,
|
||||
};
|
||||
use crate::config::determine_output_level;
|
||||
use crate::{
|
||||
client, parser, scan_manager::resume_scan, utils::fmt_err, FeroxSerialize, DEFAULT_CONFIG_NAME,
|
||||
};
|
||||
@@ -368,7 +369,7 @@ impl Configuration {
|
||||
let mut config = Configuration::default();
|
||||
|
||||
// read in all config files
|
||||
let _ = Self::parse_config_files(&mut config);
|
||||
Self::parse_config_files(&mut config)?;
|
||||
|
||||
// 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
|
||||
@@ -719,16 +720,8 @@ impl Configuration {
|
||||
update_if_not_default!(&mut conf.verbosity, new.verbosity, 0);
|
||||
update_if_not_default!(&mut conf.silent, new.silent, false);
|
||||
update_if_not_default!(&mut conf.quiet, new.quiet, false);
|
||||
if new.quiet && new.silent {
|
||||
// user COULD have both as true in config file, take the more quiet of the two
|
||||
conf.output_level = OutputLevel::Silent;
|
||||
} else if new.quiet {
|
||||
conf.output_level = OutputLevel::Quiet;
|
||||
} else if new.silent {
|
||||
conf.output_level = OutputLevel::Silent;
|
||||
} else {
|
||||
conf.output_level = OutputLevel::Default;
|
||||
}
|
||||
// use updated quiet/silent values to determin output level
|
||||
conf.output_level = determine_output_level(conf.quiet, conf.silent);
|
||||
update_if_not_default!(&mut conf.output, new.output, "");
|
||||
update_if_not_default!(&mut conf.redirects, new.redirects, false);
|
||||
update_if_not_default!(&mut conf.insecure, new.insecure, false);
|
||||
|
||||
@@ -6,4 +6,4 @@ mod utils;
|
||||
mod tests;
|
||||
|
||||
pub use self::container::Configuration;
|
||||
pub use self::utils::OutputLevel;
|
||||
pub use self::utils::{determine_output_level, OutputLevel};
|
||||
|
||||
@@ -68,7 +68,7 @@ pub(super) fn depth() -> usize {
|
||||
}
|
||||
|
||||
/// enum representing the three possible states for informational output (not logging verbosity)
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum OutputLevel {
|
||||
/// normal scan, no --quiet|--silent
|
||||
Default,
|
||||
@@ -87,3 +87,17 @@ impl Default for OutputLevel {
|
||||
Self::Default
|
||||
}
|
||||
}
|
||||
|
||||
/// given the current settings for quiet and silent, determine output_level (DRY helper)
|
||||
pub fn determine_output_level(quiet: bool, silent: bool) -> OutputLevel {
|
||||
if quiet && silent {
|
||||
// user COULD have both as true in config file, take the more quiet of the two
|
||||
OutputLevel::Silent
|
||||
} else if quiet {
|
||||
OutputLevel::Quiet
|
||||
} else if silent {
|
||||
OutputLevel::Silent
|
||||
} else {
|
||||
OutputLevel::Default
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use super::*;
|
||||
use crate::{
|
||||
progress::PROGRESS_PRINTER,
|
||||
scan_manager::FeroxState,
|
||||
scan_manager::PAUSE_SCAN,
|
||||
scan_manager::{FeroxState, PAUSE_SCAN},
|
||||
scanner::RESPONSES,
|
||||
statistics::StatError,
|
||||
utils::{open_file, write_to},
|
||||
SLEEP_DURATION,
|
||||
};
|
||||
@@ -64,7 +64,11 @@ impl TermInputHandler {
|
||||
});
|
||||
|
||||
if result.is_err() {
|
||||
log::error!("Could not set Ctrl+c handler; scan state will not be saved");
|
||||
log::warn!("Could not set Ctrl+c handler; scan state will not be saved");
|
||||
self.handles
|
||||
.stats
|
||||
.send(Command::AddError(StatError::Other))
|
||||
.unwrap_or_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,6 @@ impl FileOutHandler {
|
||||
skip_fail!(write_to(&*response, &mut file, self.config.json));
|
||||
}
|
||||
Command::Exit => {
|
||||
log::error!("file handler got Exit");
|
||||
break;
|
||||
}
|
||||
Command::Sync(sender) => {
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
use super::*;
|
||||
use crate::{
|
||||
client,
|
||||
event_handlers::{Command, Command::UpdateUsizeField, Handles},
|
||||
event_handlers::{
|
||||
Command,
|
||||
Command::{AddError, UpdateUsizeField},
|
||||
Handles,
|
||||
},
|
||||
scan_manager::ScanOrder,
|
||||
statistics::StatField::{LinksExtracted, TotalExpected},
|
||||
statistics::{
|
||||
StatError::Other,
|
||||
StatField::{LinksExtracted, TotalExpected},
|
||||
},
|
||||
url::FeroxUrl,
|
||||
utils::make_request,
|
||||
};
|
||||
@@ -163,7 +170,8 @@ impl<'a> Extractor<'a> {
|
||||
}
|
||||
} else {
|
||||
// unexpected error has occurred
|
||||
log::error!("Could not parse given url: {}", e);
|
||||
log::warn!("Could not parse given url: {}", e);
|
||||
self.handles.stats.send(AddError(Other)).unwrap_or_default();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,11 +233,11 @@ impl HeuristicTests {
|
||||
OutputLevel::Default | OutputLevel::Quiet
|
||||
) {
|
||||
ferox_print(
|
||||
&format!("Could not connect to {}, skipping...", target_url),
|
||||
&format!("Could not connect to {}, skipping... (try turning on warnings with -v)", target_url),
|
||||
&PROGRESS_PRINTER,
|
||||
);
|
||||
}
|
||||
log::error!("{}", e);
|
||||
log::warn!("{}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +327,13 @@ fn main() -> Result<()> {
|
||||
let config = Arc::new(Configuration::new().with_context(|| "Could not create Configuration")?);
|
||||
|
||||
// setup logging based on the number of -v's used
|
||||
logger::initialize(config.clone())?;
|
||||
if matches!(
|
||||
config.output_level,
|
||||
OutputLevel::Default | OutputLevel::Quiet
|
||||
) {
|
||||
// don't log on --silent
|
||||
logger::initialize(config.clone())?;
|
||||
}
|
||||
|
||||
// this function uses rlimit, which is not supported on windows
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
|
||||
@@ -68,6 +68,7 @@ pub fn initialize() -> App<'static, 'static> {
|
||||
.long("verbosity")
|
||||
.takes_value(false)
|
||||
.multiple(true)
|
||||
.conflicts_with("silent")
|
||||
.help("Increase verbosity level (use -vv or more for greater effect. [CAUTION] 4 -v's is probably too much)"),
|
||||
)
|
||||
.arg(
|
||||
@@ -119,7 +120,8 @@ pub fn initialize() -> App<'static, 'static> {
|
||||
Arg::with_name("silent")
|
||||
.long("silent")
|
||||
.takes_value(false)
|
||||
.help("Only print URLs (good for piping a list of urls to other commands)")
|
||||
.conflicts_with("quiet")
|
||||
.help("Only print URLs + turn off logging (good for piping a list of urls to other commands)")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("quiet")
|
||||
|
||||
@@ -45,7 +45,7 @@ pub fn add_bar(prefix: &str, length: u64, bar_type: BarType) -> ProgressBar {
|
||||
style.template("[{bar:.yellow/blue}] - {elapsed:<4} {pos:>7}/{len:7} {eta:7} {msg}")
|
||||
}
|
||||
BarType::Quiet => style.template("Scanning: {prefix}"),
|
||||
};
|
||||
}; // todo update README with silent/quiet stuff
|
||||
|
||||
let progress_bar = PROGRESS_BAR.add(ProgressBar::new(length));
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ impl FeroxResponse {
|
||||
self.url = url;
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Could not parse {} into a Url: {}", url, e);
|
||||
log::warn!("Could not parse {} into a Url: {}", url, e);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -200,7 +200,7 @@ impl FeroxResponse {
|
||||
// await the response's body
|
||||
Ok(text) => text,
|
||||
Err(e) => {
|
||||
log::error!("Could not parse body from response: {}", e);
|
||||
log::warn!("Could not parse body from response: {}", e);
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ impl FeroxScans {
|
||||
scans.push(scan);
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("FeroxScans' container's mutex is poisoned: {}", e);
|
||||
log::warn!("FeroxScans' container's mutex is poisoned: {}", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -248,8 +248,10 @@ impl FeroxScans {
|
||||
pub fn print_known_responses(&self) {
|
||||
if let Ok(mut responses) = RESPONSES.responses.write() {
|
||||
for response in responses.iter_mut() {
|
||||
let _level = response.output_level;
|
||||
if !matches!(self.output_level, _level) {
|
||||
if self.output_level != response.output_level {
|
||||
// set the output_level prior to printing the response to ensure that the
|
||||
// response's setting aligns with the overall configuration (since we're
|
||||
// calling this from a resumed state)
|
||||
response.output_level = self.output_level;
|
||||
}
|
||||
PROGRESS_PRINTER.println(response.as_str());
|
||||
|
||||
@@ -436,7 +436,7 @@ fn feroxscan_display() {
|
||||
scan_order: ScanOrder::Latest,
|
||||
scan_type: Default::default(),
|
||||
num_requests: 0,
|
||||
quiet: false,
|
||||
output_level: OutputLevel::Default,
|
||||
status: Default::default(),
|
||||
task: tokio::sync::Mutex::new(None),
|
||||
progress_bar: std::sync::Mutex::new(None),
|
||||
@@ -476,7 +476,7 @@ async fn ferox_scan_abort() {
|
||||
scan_order: ScanOrder::Latest,
|
||||
scan_type: Default::default(),
|
||||
num_requests: 0,
|
||||
quiet: false,
|
||||
output_level: OutputLevel::Default,
|
||||
status: std::sync::Mutex::new(ScanStatus::Running),
|
||||
task: tokio::sync::Mutex::new(Some(tokio::spawn(async move {
|
||||
sleep(Duration::from_millis(SLEEP_DURATION * 2));
|
||||
|
||||
@@ -46,7 +46,7 @@ pub async fn start_max_time_thread(handles: Arc<Handles>) {
|
||||
let _ = TermInputHandler::sigint_handler(handles.clone());
|
||||
}
|
||||
|
||||
log::error!(
|
||||
log::warn!(
|
||||
"Could not parse the value provided ({}), can't enforce time limit",
|
||||
handles.config.time_limit
|
||||
);
|
||||
@@ -87,6 +87,10 @@ pub fn resume_scan(filename: &str) -> Configuration {
|
||||
}
|
||||
}
|
||||
|
||||
log::error!("{:#?}", config);
|
||||
|
||||
log::error!("{:#?}", config);
|
||||
|
||||
log::trace!("exit: resume_scan -> {:?}", config);
|
||||
config
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use tokio::sync::{oneshot, Semaphore};
|
||||
|
||||
use crate::{
|
||||
event_handlers::{
|
||||
Command::{self, UpdateF64Field, UpdateUsizeField},
|
||||
Command::{self, AddError, UpdateF64Field, UpdateUsizeField},
|
||||
Handles,
|
||||
},
|
||||
extractor::{
|
||||
@@ -21,7 +21,10 @@ use crate::{
|
||||
heuristics,
|
||||
response::FeroxResponse,
|
||||
scan_manager::{FeroxResponses, ScanOrder, ScanStatus, PAUSE_SCAN},
|
||||
statistics::StatField::{DirScanTimes, ExpectedPerScan},
|
||||
statistics::{
|
||||
StatError::Other,
|
||||
StatField::{DirScanTimes, ExpectedPerScan},
|
||||
},
|
||||
url::FeroxUrl,
|
||||
utils::{fmt_err, make_request},
|
||||
};
|
||||
@@ -74,13 +77,9 @@ impl Requester {
|
||||
}
|
||||
|
||||
/// limit the number of requests per second
|
||||
pub async fn limit(&self) {
|
||||
self.rate_limiter
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.acquire_one()
|
||||
.await
|
||||
.unwrap(); // todo unwrap
|
||||
pub async fn limit(&self) -> Result<()> {
|
||||
self.rate_limiter.as_ref().unwrap().acquire_one().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Wrapper for [make_request](fn.make_request.html)
|
||||
@@ -94,7 +93,11 @@ impl Requester {
|
||||
|
||||
for url in urls {
|
||||
if self.rate_limiter.is_some() {
|
||||
self.limit().await;
|
||||
// found a rate limiter, limit that junk!
|
||||
if let Err(e) = self.limit().await {
|
||||
log::warn!("Could not rate limit scan: {}", e);
|
||||
self.handles.stats.send(AddError(Other)).unwrap_or_default();
|
||||
}
|
||||
}
|
||||
|
||||
let response = make_request(
|
||||
@@ -260,9 +263,6 @@ impl FeroxScanner {
|
||||
// to false
|
||||
scanned_urls_clone.pause(true).await;
|
||||
}
|
||||
// if requester_clone.rate_limiter.is_some() {
|
||||
// requester_clone.limit().await;
|
||||
// }
|
||||
requester_clone.request(&word).await
|
||||
}),
|
||||
pb,
|
||||
@@ -274,7 +274,8 @@ impl FeroxScanner {
|
||||
bar.inc(increment_len);
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("error awaiting a response: {}", e);
|
||||
log::warn!("error awaiting a response: {}", e);
|
||||
self.handles.stats.send(AddError(Other)).unwrap_or_default();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
12
src/utils.rs
12
src/utils.rs
@@ -97,12 +97,9 @@ pub async fn make_request(
|
||||
|
||||
match client.get(url.to_owned()).send().await {
|
||||
Err(e) => {
|
||||
let mut log_level = log::Level::Error;
|
||||
|
||||
log::trace!("exit: make_request -> {}", e);
|
||||
|
||||
if e.is_timeout() {
|
||||
// only warn for timeouts, while actual errors are still left as errors
|
||||
log_level = log::Level::Warn;
|
||||
send_command!(tx_stats, AddError(Timeout));
|
||||
} else if e.is_redirect() {
|
||||
if let Some(last_redirect) = e.url() {
|
||||
@@ -135,12 +132,7 @@ pub async fn make_request(
|
||||
send_command!(tx_stats, AddError(Other));
|
||||
}
|
||||
|
||||
if matches!(log_level, log::Level::Error) {
|
||||
log::error!("Error while making request: {}", e);
|
||||
} else {
|
||||
log::warn!("Error while making request: {}", e);
|
||||
}
|
||||
|
||||
log::warn!("Error while making request: {}", e);
|
||||
bail!("{}", e)
|
||||
}
|
||||
Ok(resp) => {
|
||||
|
||||
@@ -295,7 +295,7 @@ fn heuristics_wildcard_test_with_two_static_wildcards() {
|
||||
|
||||
#[test]
|
||||
/// test finds a static wildcard and reports nothing to stdout
|
||||
fn heuristics_wildcard_test_with_two_static_wildcards_with_quiet_enabled(
|
||||
fn heuristics_wildcard_test_with_two_static_wildcards_with_silent_enabled(
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let srv = MockServer::start();
|
||||
let (tmp_dir, file) = setup_tmp_directory(&["LICENSE".to_string()], "wordlist")?;
|
||||
@@ -321,7 +321,7 @@ fn heuristics_wildcard_test_with_two_static_wildcards_with_quiet_enabled(
|
||||
.arg("--wordlist")
|
||||
.arg(file.as_os_str())
|
||||
.arg("--add-slash")
|
||||
.arg("-q")
|
||||
.arg("--silent")
|
||||
.unwrap();
|
||||
|
||||
teardown_tmp_directory(tmp_dir);
|
||||
|
||||
Reference in New Issue
Block a user