Implement -v (verbose) flag (#100)

This commit is contained in:
Joona Hoikkala 2019-11-16 16:32:11 +02:00 committed by GitHub
parent ad927ef939
commit 3949e49b3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 17 additions and 19 deletions

View file

@ -139,7 +139,6 @@ Usage of ./ffuf:
-input-num int -input-num int
Number of inputs to test. Used in conjunction with --input-cmd. (default 100) Number of inputs to test. Used in conjunction with --input-cmd. (default 100)
-k TLS identity verification -k TLS identity verification
-l Show target location of redirect responses
-mc string -mc string
Match HTTP status codes from respose, use "all" to match every response code. (default "200,204,301,302,307,401,403") Match HTTP status codes from respose, use "all" to match every response code. (default "200,204,301,302,307,401,403")
-ml string -ml string
@ -172,6 +171,7 @@ Usage of ./ffuf:
HTTP request timeout in seconds. (default 10) HTTP request timeout in seconds. (default 10)
-u string -u string
Target URL Target URL
-v Verbose output, printing full URL and redirect location (if any) with the results.
-w value -w value
Wordlist file path and (optional) custom fuzz keyword, using colon as delimiter. Use file path '-' to read from standard input. Can be supplied multiple times. Format: '/path/to/wordlist:KEYWORD' Wordlist file path and (optional) custom fuzz keyword, using colon as delimiter. Use file path '-' to read from standard input. Can be supplied multiple times. Format: '/path/to/wordlist:KEYWORD'
-x string -x string
@ -197,10 +197,12 @@ The only dependency of ffuf is Go 1.11. No dependencies outside of Go standard l
- Redirect location is always shown in the output files (when using `-o`) - Redirect location is always shown in the output files (when using `-o`)
- Full URL is always shown in the output files (when using `-o`) - Full URL is always shown in the output files (when using `-o`)
- HTML output format got [DataTables](https://datatables.net/) support allowing realtime searches, sorting by column etc. - HTML output format got [DataTables](https://datatables.net/) support allowing realtime searches, sorting by column etc.
- New CLI flag `-v` for verbose output. Including full URL, and redirect location.
- Changed - Changed
- Fixed a bug in the default multi wordlist mode - Fixed a bug in the default multi wordlist mode
- Fixed JSON output regression, where all the input data was always encoded in base64 - Fixed JSON output regression, where all the input data was always encoded in base64
- `--debug-log` no correctly logs connection errors - `--debug-log` no correctly logs connection errors
- Removed `-l` flag in favor of `-v`
- v0.11 - v0.11

View file

@ -93,7 +93,6 @@ func main() {
flag.StringVar(&conf.Method, "X", "GET", "HTTP method to use") flag.StringVar(&conf.Method, "X", "GET", "HTTP method to use")
flag.StringVar(&conf.OutputFile, "o", "", "Write output to file") flag.StringVar(&conf.OutputFile, "o", "", "Write output to file")
flag.StringVar(&opts.outputFormat, "of", "json", "Output file format. Available formats: json, ejson, html, md, csv, ecsv") flag.StringVar(&opts.outputFormat, "of", "json", "Output file format. Available formats: json, ejson, html, md, csv, ecsv")
flag.BoolVar(&conf.ShowRedirectLocation, "l", false, "Show target location of redirect responses")
flag.BoolVar(&conf.Quiet, "s", false, "Do not print additional information (silent mode)") flag.BoolVar(&conf.Quiet, "s", false, "Do not print additional information (silent mode)")
flag.BoolVar(&conf.StopOn403, "sf", false, "Stop when > 95% of responses return 403 Forbidden") flag.BoolVar(&conf.StopOn403, "sf", false, "Stop when > 95% of responses return 403 Forbidden")
flag.BoolVar(&conf.StopOnErrors, "se", false, "Stop on spurious errors") flag.BoolVar(&conf.StopOnErrors, "se", false, "Stop on spurious errors")
@ -103,6 +102,7 @@ func main() {
flag.Var(&opts.AutoCalibrationStrings, "acc", "Custom auto-calibration string. Can be used multiple times. Implies -ac") flag.Var(&opts.AutoCalibrationStrings, "acc", "Custom auto-calibration string. Can be used multiple times. Implies -ac")
flag.IntVar(&conf.Threads, "t", 40, "Number of concurrent threads.") flag.IntVar(&conf.Threads, "t", 40, "Number of concurrent threads.")
flag.IntVar(&conf.Timeout, "timeout", 10, "HTTP request timeout in seconds.") flag.IntVar(&conf.Timeout, "timeout", 10, "HTTP request timeout in seconds.")
flag.BoolVar(&conf.Verbose, "v", false, "Verbose output, printing full URL and redirect location (if any) with the results.")
flag.BoolVar(&opts.showVersion, "V", false, "Show version information.") flag.BoolVar(&opts.showVersion, "V", false, "Show version information.")
flag.StringVar(&opts.debugLog, "debug-log", "", "Write all of the internal logging to the specified file.") flag.StringVar(&opts.debugLog, "debug-log", "", "Write all of the internal logging to the specified file.")
flag.Parse() flag.Parse()

View file

@ -37,7 +37,6 @@ type Config struct {
FollowRedirects bool FollowRedirects bool
AutoCalibration bool AutoCalibration bool
AutoCalibrationStrings []string AutoCalibrationStrings []string
ShowRedirectLocation bool
Timeout int Timeout int
ProgressFrequency int ProgressFrequency int
Delay optRange Delay optRange
@ -47,6 +46,7 @@ type Config struct {
Context context.Context Context context.Context
ProxyURL func(*http.Request) (*url.URL, error) ProxyURL func(*http.Request) (*url.URL, error)
CommandLine string CommandLine string
Verbose bool
} }
type InputProviderConfig struct { type InputProviderConfig struct {
@ -67,7 +67,6 @@ func NewConfig(ctx context.Context) Config {
conf.StopOn403 = false conf.StopOn403 = false
conf.StopOnErrors = false conf.StopOnErrors = false
conf.StopOnAll = false conf.StopOnAll = false
conf.ShowRedirectLocation = false
conf.FollowRedirects = false conf.FollowRedirects = false
conf.InputProviders = make([]InputProviderConfig, 0) conf.InputProviders = make([]InputProviderConfig, 0)
conf.CommandKeywords = make([]string, 0) conf.CommandKeywords = make([]string, 0)
@ -81,5 +80,6 @@ func NewConfig(ctx context.Context) Config {
// Progress update frequency, in milliseconds // Progress update frequency, in milliseconds
conf.ProgressFrequency = 100 conf.ProgressFrequency = 100
conf.DirSearchCompat = false conf.DirSearchCompat = false
conf.Verbose = false
return conf return conf
} }

View file

@ -159,7 +159,7 @@ func (s *Stdoutput) printResult(resp ffuf.Response) {
if s.config.Quiet { if s.config.Quiet {
s.resultQuiet(resp) s.resultQuiet(resp)
} else { } else {
if len(resp.Request.Input) > 1 { if len(resp.Request.Input) > 1 || s.config.Verbose {
// Print a multi-line result (when using multiple input keywords and wordlists) // Print a multi-line result (when using multiple input keywords and wordlists)
s.resultMultiline(resp) s.resultMultiline(resp)
} else { } else {
@ -199,9 +199,16 @@ func (s *Stdoutput) resultQuiet(resp ffuf.Response) {
func (s *Stdoutput) resultMultiline(resp ffuf.Response) { func (s *Stdoutput) resultMultiline(resp ffuf.Response) {
var res_hdr, res_str string var res_hdr, res_str string
res_str = "%s%s * %s: %s\n" res_str = "%s%s * %s: %s\n"
res_hdr = fmt.Sprintf("%s[Status: %d, Size: %d, Words: %d, Lines: %d%s]", TERMINAL_CLEAR_LINE, resp.StatusCode, resp.ContentLength, resp.ContentWords, resp.ContentLines, s.addRedirectLocation(resp)) res_hdr = fmt.Sprintf("%s[Status: %d, Size: %d, Words: %d, Lines: %d]", TERMINAL_CLEAR_LINE, resp.StatusCode, resp.ContentLength, resp.ContentWords, resp.ContentLines)
res_hdr = s.colorize(res_hdr, resp.StatusCode) res_hdr = s.colorize(res_hdr, resp.StatusCode)
reslines := "" reslines := ""
if s.config.Verbose {
reslines = fmt.Sprintf("%s%s| URL | %s\n", reslines, TERMINAL_CLEAR_LINE, resp.Request.Url)
redirectLocation := resp.GetRedirectLocation()
if redirectLocation != "" {
reslines = fmt.Sprintf("%s%s| --> | %s\n", reslines, TERMINAL_CLEAR_LINE, redirectLocation)
}
}
for k, v := range resp.Request.Input { for k, v := range resp.Request.Input {
if inSlice(k, s.config.CommandKeywords) { if inSlice(k, s.config.CommandKeywords) {
// If we're using external command for input, display the position instead of input // If we're using external command for input, display the position instead of input
@ -211,26 +218,15 @@ func (s *Stdoutput) resultMultiline(resp ffuf.Response) {
reslines = fmt.Sprintf(res_str, reslines, TERMINAL_CLEAR_LINE, k, v) reslines = fmt.Sprintf(res_str, reslines, TERMINAL_CLEAR_LINE, k, v)
} }
} }
fmt.Printf("%s\n%s", res_hdr, reslines) fmt.Printf("%s\n%s\n", res_hdr, reslines)
} }
func (s *Stdoutput) resultNormal(resp ffuf.Response) { func (s *Stdoutput) resultNormal(resp ffuf.Response) {
var res_str string var res_str string
res_str = fmt.Sprintf("%s%-23s [Status: %s, Size: %d, Words: %d, Lines: %d%s]", TERMINAL_CLEAR_LINE, s.prepareInputsOneLine(resp), s.colorize(fmt.Sprintf("%d", resp.StatusCode), resp.StatusCode), resp.ContentLength, resp.ContentWords, resp.ContentLines, s.addRedirectLocation(resp)) res_str = fmt.Sprintf("%s%-23s [Status: %s, Size: %d, Words: %d, Lines: %d]", TERMINAL_CLEAR_LINE, s.prepareInputsOneLine(resp), s.colorize(fmt.Sprintf("%d", resp.StatusCode), resp.StatusCode), resp.ContentLength, resp.ContentWords, resp.ContentLines)
fmt.Println(res_str) fmt.Println(res_str)
} }
// addRedirectLocation returns a formatted string containing the Redirect location or returns an empty string
func (s *Stdoutput) addRedirectLocation(resp ffuf.Response) string {
if s.config.ShowRedirectLocation == true {
redirectLocation := resp.GetRedirectLocation()
if redirectLocation != "" {
return fmt.Sprintf(", ->: %s", redirectLocation)
}
}
return ""
}
func (s *Stdoutput) colorize(input string, status int64) string { func (s *Stdoutput) colorize(input string, status int64) string {
if !s.config.Colors { if !s.config.Colors {
return fmt.Sprintf("%s", input) return fmt.Sprintf("%s", input)