added shell completion scripts and build.rs; closes #146

This commit is contained in:
epi
2020-12-04 07:08:49 -06:00
parent fbb964a893
commit 6c779bd4c1
7 changed files with 411 additions and 2 deletions

View File

@@ -10,10 +10,14 @@ description = "A fast, simple, recursive content discovery tool."
categories = ["command-line-utilities"]
keywords = ["pentest", "enumeration", "url-bruteforce", "content-discovery", "web"]
exclude = [".github/*", "img/*", "check-coverage.sh"]
build = "build.rs"
[badges]
maintenance = { status = "actively-developed" }
[build-dependencies]
clap = "2"
[dependencies]
futures = { version = "0.3"}
tokio = { version = "0.2", features = ["full"] }

17
build.rs Normal file
View File

@@ -0,0 +1,17 @@
extern crate clap;
use clap::Shell;
include!("src/parser.rs");
fn main() {
let outdir = "shell_completions";
let mut app = initialize();
let shells: [Shell; 4] = [Shell::Bash, Shell::Fish, Shell::Zsh, Shell::PowerShell];
for shell in &shells {
app.gen_completions("feroxbuster", *shell, outdir);
}
}

View File

@@ -0,0 +1,92 @@
#compdef feroxbuster
_feroxbuster() {
typeset -A opt_args
local ret=1
local context curcontext="$curcontext" state line
_arguments -s -S -C \
'-w+[Path to the wordlist]' \
'--wordlist+[Path to the wordlist]' \
'*-u+[The target URL(s) (required, unless --stdin used)]' \
'*--url+[The target URL(s) (required, unless --stdin used)]' \
'-t+[Number of concurrent threads (default: 50)]' \
'--threads+[Number of concurrent threads (default: 50)]' \
'-d+[Maximum recursion depth, a depth of 0 is infinite recursion (default: 4)]' \
'--depth+[Maximum recursion depth, a depth of 0 is infinite recursion (default: 4)]' \
'-T+[Number of seconds before a request times out (default: 7)]' \
'--timeout+[Number of seconds before a request times out (default: 7)]' \
'-p+[Proxy to use for requests (ex: http(s)://host:port, socks5://host:port)]' \
'--proxy+[Proxy to use for requests (ex: http(s)://host:port, socks5://host:port)]' \
'-P+[Send only unfiltered requests through a Replay Proxy, instead of all requests]' \
'--replay-proxy+[Send only unfiltered requests through a Replay Proxy, instead of all requests]' \
'*-R+[Status Codes to send through a Replay Proxy when found (default: --status-codes value)]' \
'*--replay-codes+[Status Codes to send through a Replay Proxy when found (default: --status-codes value)]' \
'*-s+[Status Codes to include (allow list) (default: 200 204 301 302 307 308 401 403 405)]' \
'*--status-codes+[Status Codes to include (allow list) (default: 200 204 301 302 307 308 401 403 405)]' \
'-o+[Output file to write results to (use w/ --json for JSON entries)]' \
'--output+[Output file to write results to (use w/ --json for JSON entries)]' \
'(-w --wordlist -u --url -t --threads -d --depth -T --timeout -v --verbosity -p --proxy -P --replay-proxy -R --replay-codes -s --status-codes -q --quiet --json -D --dont-filter -o --output --debug-log -a --user-agent -r --redirects -k --insecure -x --extensions -H --headers -Q --query -n --no-recursion -f --add-slash --stdin -S --filter-size -X --filter-regex -W --filter-words -N --filter-lines -C --filter-status -e --extract-links -L --scan-limit)--resume-from+[State file from which to resume a partially complete scan (ex. --resume-from ferox-1606586780.state)]' \
'--debug-log+[Output file to write log entries (use w/ --json for JSON entries)]' \
'-a+[Sets the User-Agent (default: feroxbuster/VERSION)]' \
'--user-agent+[Sets the User-Agent (default: feroxbuster/VERSION)]' \
'*-x+[File extension(s) to search for (ex: -x php -x pdf js)]' \
'*--extensions+[File extension(s) to search for (ex: -x php -x pdf js)]' \
'*-H+[Specify HTTP headers (ex: -H Header:val '\''stuff: things'\'')]' \
'*--headers+[Specify HTTP headers (ex: -H Header:val '\''stuff: things'\'')]' \
'*-Q+[Specify URL query parameters (ex: -Q token=stuff -Q secret=key)]' \
'*--query+[Specify URL query parameters (ex: -Q token=stuff -Q secret=key)]' \
'*-S+[Filter out messages of a particular size (ex: -S 5120 -S 4927,1970)]' \
'*--filter-size+[Filter out messages of a particular size (ex: -S 5120 -S 4927,1970)]' \
'*-X+[Filter out messages via regular expression matching on the response'\''s body (ex: -X '\''^ignore me$'\'')]' \
'*--filter-regex+[Filter out messages via regular expression matching on the response'\''s body (ex: -X '\''^ignore me$'\'')]' \
'*-W+[Filter out messages of a particular word count (ex: -W 312 -W 91,82)]' \
'*--filter-words+[Filter out messages of a particular word count (ex: -W 312 -W 91,82)]' \
'*-N+[Filter out messages of a particular line count (ex: -N 20 -N 31,30)]' \
'*--filter-lines+[Filter out messages of a particular line count (ex: -N 20 -N 31,30)]' \
'*-C+[Filter out status codes (deny list) (ex: -C 200 -C 401)]' \
'*--filter-status+[Filter out status codes (deny list) (ex: -C 200 -C 401)]' \
'-L+[Limit total number of concurrent scans (default: 0, i.e. no limit)]' \
'--scan-limit+[Limit total number of concurrent scans (default: 0, i.e. no limit)]' \
'*-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)]' \
'-q[Only print URLs; Don'\''t print status codes, response size, running config, etc...]' \
'--quiet[Only print URLs; Don'\''t print status codes, response size, running config, etc...]' \
'--json[Emit JSON logs to --output and --debug-log instead of normal text]' \
'-D[Don'\''t auto-filter wildcard responses]' \
'--dont-filter[Don'\''t auto-filter wildcard responses]' \
'-r[Follow redirects]' \
'--redirects[Follow redirects]' \
'-k[Disables TLS certificate validation]' \
'--insecure[Disables TLS certificate validation]' \
'-n[Do not scan recursively]' \
'--no-recursion[Do not scan recursively]' \
'(-x --extensions)-f[Append / to each request]' \
'(-x --extensions)--add-slash[Append / to each request]' \
'(-u --url)--stdin[Read url(s) from STDIN]' \
'-e[Extract links from response body (html, javascript, etc...); make new requests based on findings (default: false)]' \
'--extract-links[Extract links from response body (html, javascript, etc...); make new requests based on findings (default: false)]' \
'-h[Prints help information]' \
'--help[Prints help information]' \
'-V[Prints version information]' \
'--version[Prints version information]' \
&& ret=0
}
(( $+functions[_feroxbuster_commands] )) ||
_feroxbuster_commands() {
local commands; commands=(
)
_describe -t commands 'feroxbuster commands' commands "$@"
}
(( $+functions[_feroxbuster_commands] )) ||
_feroxbuster_commands() {
local commands; commands=(
)
_describe -t commands 'feroxbuster commands' commands "$@"
}
_feroxbuster "$@"

View File

@@ -0,0 +1,38 @@
@('feroxbuster', './feroxbuster') | %{
Register-ArgumentCompleter -Native -CommandName $_ -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$command = '_feroxbuster'
$commandAst.CommandElements |
Select-Object -Skip 1 |
%{
switch ($_.ToString()) {
'feroxbuster' {
$command += '_feroxbuster'
break
}
default {
break
}
}
}
$completions = @()
switch ($command) {
'_feroxbuster' {
$completions = @('-v', '-q', '-D', '-r', '-k', '-n', '-f', '-e', '-h', '-V', '-w', '-u', '-t', '-d', '-T', '-p', '-P', '-R', '-s', '-o', '-a', '-x', '-H', '-Q', '-S', '-X', '-W', '-N', '-C', '-L', '--verbosity', '--quiet', '--json', '--dont-filter', '--redirects', '--insecure', '--no-recursion', '--add-slash', '--stdin', '--extract-links', '--help', '--version', '--wordlist', '--url', '--threads', '--depth', '--timeout', '--proxy', '--replay-proxy', '--replay-codes', '--status-codes', '--output', '--resume-from', '--debug-log', '--user-agent', '--extensions', '--headers', '--query', '--filter-size', '--filter-regex', '--filter-words', '--filter-lines', '--filter-status', '--scan-limit')
}
}
$completions |
?{ $_ -like "$wordToComplete*" } |
Sort-Object |
%{ New-Object System.Management.Automation.CompletionResult $_, $_, 'ParameterValue', $_ }
}
}

View File

@@ -0,0 +1,212 @@
_feroxbuster() {
local i cur prev opts cmds
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
cmd=""
opts=""
for i in ${COMP_WORDS[@]}
do
case "${i}" in
feroxbuster)
cmd="feroxbuster"
;;
feroxbuster)
cmd+="__feroxbuster"
;;
*)
;;
esac
done
case "${cmd}" in
feroxbuster)
opts=" -v -q -D -r -k -n -f -e -h -V -w -u -t -d -T -p -P -R -s -o -a -x -H -Q -S -X -W -N -C -L --verbosity --quiet --json --dont-filter --redirects --insecure --no-recursion --add-slash --stdin --extract-links --help --version --wordlist --url --threads --depth --timeout --proxy --replay-proxy --replay-codes --status-codes --output --resume-from --debug-log --user-agent --extensions --headers --query --filter-size --filter-regex --filter-words --filter-lines --filter-status --scan-limit "
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
case "${prev}" in
--wordlist)
COMPREPLY=("<FILE>")
return 0
;;
-w)
COMPREPLY=("<FILE>")
return 0
;;
--url)
COMPREPLY=("<URL>...")
return 0
;;
-u)
COMPREPLY=("<URL>...")
return 0
;;
--threads)
COMPREPLY=("<THREADS>")
return 0
;;
-t)
COMPREPLY=("<THREADS>")
return 0
;;
--depth)
COMPREPLY=("<RECURSION_DEPTH>")
return 0
;;
-d)
COMPREPLY=("<RECURSION_DEPTH>")
return 0
;;
--timeout)
COMPREPLY=("<SECONDS>")
return 0
;;
-T)
COMPREPLY=("<SECONDS>")
return 0
;;
--proxy)
COMPREPLY=("<PROXY>")
return 0
;;
-p)
COMPREPLY=("<PROXY>")
return 0
;;
--replay-proxy)
COMPREPLY=("<REPLAY_PROXY>")
return 0
;;
-P)
COMPREPLY=("<REPLAY_PROXY>")
return 0
;;
--replay-codes)
COMPREPLY=("<REPLAY_CODE>...")
return 0
;;
-R)
COMPREPLY=("<REPLAY_CODE>...")
return 0
;;
--status-codes)
COMPREPLY=("<STATUS_CODE>...")
return 0
;;
-s)
COMPREPLY=("<STATUS_CODE>...")
return 0
;;
--output)
COMPREPLY=("<FILE>")
return 0
;;
-o)
COMPREPLY=("<FILE>")
return 0
;;
--resume-from)
COMPREPLY=("<STATE_FILE>")
return 0
;;
--debug-log)
COMPREPLY=("<FILE>")
return 0
;;
--user-agent)
COMPREPLY=("<USER_AGENT>")
return 0
;;
-a)
COMPREPLY=("<USER_AGENT>")
return 0
;;
--extensions)
COMPREPLY=("<FILE_EXTENSION>...")
return 0
;;
-x)
COMPREPLY=("<FILE_EXTENSION>...")
return 0
;;
--headers)
COMPREPLY=("<HEADER>...")
return 0
;;
-H)
COMPREPLY=("<HEADER>...")
return 0
;;
--query)
COMPREPLY=("<QUERY>...")
return 0
;;
-Q)
COMPREPLY=("<QUERY>...")
return 0
;;
--filter-size)
COMPREPLY=("<SIZE>...")
return 0
;;
-S)
COMPREPLY=("<SIZE>...")
return 0
;;
--filter-regex)
COMPREPLY=("<REGEX>...")
return 0
;;
-X)
COMPREPLY=("<REGEX>...")
return 0
;;
--filter-words)
COMPREPLY=("<WORDS>...")
return 0
;;
-W)
COMPREPLY=("<WORDS>...")
return 0
;;
--filter-lines)
COMPREPLY=("<LINES>...")
return 0
;;
-N)
COMPREPLY=("<LINES>...")
return 0
;;
--filter-status)
COMPREPLY=("<STATUS_CODE>...")
return 0
;;
-C)
COMPREPLY=("<STATUS_CODE>...")
return 0
;;
--scan-limit)
COMPREPLY=("<SCAN_LIMIT>")
return 0
;;
-L)
COMPREPLY=("<SCAN_LIMIT>")
return 0
;;
*)
COMPREPLY=()
;;
esac
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
;;
esac
}
complete -F _feroxbuster -o bashdefault -o default feroxbuster

View File

@@ -0,0 +1,47 @@
function __fish_using_command
set cmd (commandline -opc)
if [ (count $cmd) -eq (count $argv) ]
for i in (seq (count $argv))
if [ $cmd[$i] != $argv[$i] ]
return 1
end
end
return 0
end
return 1
end
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s w -l wordlist -d 'Path to the wordlist'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s u -l url -d 'The target URL(s) (required, unless --stdin used)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s t -l threads -d 'Number of concurrent threads (default: 50)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s d -l depth -d 'Maximum recursion depth, a depth of 0 is infinite recursion (default: 4)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s T -l timeout -d 'Number of seconds before a request times out (default: 7)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s p -l proxy -d 'Proxy to use for requests (ex: http(s)://host:port, socks5://host:port)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s P -l replay-proxy -d 'Send only unfiltered requests through a Replay Proxy, instead of all requests'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s R -l replay-codes -d 'Status Codes to send through a Replay Proxy when found (default: --status-codes value)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s s -l status-codes -d 'Status Codes to include (allow list) (default: 200 204 301 302 307 308 401 403 405)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s o -l output -d 'Output file to write results to (use w/ --json for JSON entries)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -l resume-from -d 'State file from which to resume a partially complete scan (ex. --resume-from ferox-1606586780.state)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -l debug-log -d 'Output file to write log entries (use w/ --json for JSON entries)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s a -l user-agent -d 'Sets the User-Agent (default: feroxbuster/VERSION)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s x -l extensions -d 'File extension(s) to search for (ex: -x php -x pdf js)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s H -l headers -d 'Specify HTTP headers (ex: -H Header:val \'stuff: things\')'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s Q -l query -d 'Specify URL query parameters (ex: -Q token=stuff -Q secret=key)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s S -l filter-size -d 'Filter out messages of a particular size (ex: -S 5120 -S 4927,1970)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s X -l filter-regex -d 'Filter out messages via regular expression matching on the response\'s body (ex: -X \'^ignore me$\')'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s W -l filter-words -d 'Filter out messages of a particular word count (ex: -W 312 -W 91,82)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s N -l filter-lines -d 'Filter out messages of a particular line count (ex: -N 20 -N 31,30)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s C -l filter-status -d 'Filter out status codes (deny list) (ex: -C 200 -C 401)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s L -l scan-limit -d 'Limit total number of concurrent scans (default: 0, i.e. no limit)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -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_using_command feroxbuster" -s q -l quiet -d 'Only print URLs; Don\'t print status codes, response size, running config, etc...'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -l json -d 'Emit JSON logs to --output and --debug-log instead of normal text'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s D -l dont-filter -d 'Don\'t auto-filter wildcard responses'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s r -l redirects -d 'Follow redirects'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s k -l insecure -d 'Disables TLS certificate validation'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s n -l no-recursion -d 'Do not scan recursively'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s f -l add-slash -d 'Append / to each request'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -l stdin -d 'Read url(s) from STDIN'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s e -l extract-links -d 'Extract links from response body (html, javascript, etc...); make new requests based on findings (default: false)'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s h -l help -d 'Prints help information'
complete -c feroxbuster -n "__fish_using_command feroxbuster" -s V -l version -d 'Prints version information'

View File

@@ -1,10 +1,9 @@
use crate::VERSION;
use clap::{App, Arg, ArgGroup};
/// Create and return an instance of [clap::App](https://docs.rs/clap/latest/clap/struct.App.html), i.e. the Command Line Interface's configuration
pub fn initialize() -> App<'static, 'static> {
App::new("feroxbuster")
.version(VERSION)
.version(env!("CARGO_PKG_VERSION"))
.author("Ben 'epi' Risher (@epi052)")
.about("A fast, simple, recursive content discovery tool written in Rust")
.arg(