Added redirect location in stdout output (#59)

* Added redirect location in stdout output

* Keep conditional logic outside of the resultNormal function + Better help message for redirect location

* Moved GetRedirectLocation as a Response public method

* Added changelog entry + (Redirect become ->)
This commit is contained in:
SakiiR 2019-10-14 10:29:37 +02:00 committed by Joona Hoikkala
parent 55662e607a
commit 081e40f97e
5 changed files with 99 additions and 70 deletions

View File

@ -7,7 +7,6 @@
\/_/ \/_/ \/___/ \/_/
```
# ffuf - Fuzz Faster U Fool
A fast web fuzzer written in Go.
@ -172,53 +171,58 @@ eg. `ffuf -u https://example.org/FUZZ -w /path/to/wordlist`
## Installation
- [Download](https://github.com/ffuf/ffuf/releases/latest) a prebuilt binary from [releases page](https://github.com/ffuf/ffuf/releases/latest), unpack and run!
or
- If you have go compiler installed: `go get github.com/ffuf/ffuf`
- [Download](https://github.com/ffuf/ffuf/releases/latest) a prebuilt binary from [releases page](https://github.com/ffuf/ffuf/releases/latest), unpack and run!
or
- If you have go compiler installed: `go get github.com/ffuf/ffuf`
The only dependency of ffuf is Go 1.11. No dependencies outside of Go standard library are needed.
## Changelog
- master
- New
- Changed
- New CLI flag: -i, dummy flag that does nothing. for compatibility with copy as curl.
- New CLI flag: -b/--cookie, cookie data for compatibility with copy as curl.
- Filtering and matching by status code, response size or word count now allow using ranges in addition to single values
- New
- New CLI flag: -l, shows target location of redirect responses
- Changed
- New CLI flag: -i, dummy flag that does nothing. for compatibility with copy as curl.
- New CLI flag: -b/--cookie, cookie data for compatibility with copy as curl.
- Filtering and matching by status code, response size or word count now allow using ranges in addition to single values
- v0.10
- New
- New CLI flag: -ac to autocalibrate response size and word filters based on few preset URLs.
- New CLI flag: -timeout to specify custom timeouts for all HTTP requests.
- New CLI flag: --data for compatibility with copy as curl functionality of browsers.
- New CLI flag: --compressed, dummy flag that does nothing. for compatibility with copy as curl.
- New CLI flags: --input-cmd, and --input-num to handle input generation using external commands. Mutators for example. Environment variable FFUF_NUM will be updated on every call of the command.
- When --input-cmd is used, display position instead of the payload in results. The output file (of all formats) will include the payload in addition to the position however.
- Changed
- Wordlist can also be read from standard input
- Defining -d or --data implies POST method if -X doesn't set it to something else than GET
- New
- New CLI flag: -ac to autocalibrate response size and word filters based on few preset URLs.
- New CLI flag: -timeout to specify custom timeouts for all HTTP requests.
- New CLI flag: --data for compatibility with copy as curl functionality of browsers.
- New CLI flag: --compressed, dummy flag that does nothing. for compatibility with copy as curl.
- New CLI flags: --input-cmd, and --input-num to handle input generation using external commands. Mutators for example. Environment variable FFUF_NUM will be updated on every call of the command.
- When --input-cmd is used, display position instead of the payload in results. The output file (of all formats) will include the payload in addition to the position however.
- Changed
- Wordlist can also be read from standard input
- Defining -d or --data implies POST method if -X doesn't set it to something else than GET
- v0.9
- New
- New output file formats: CSV and eCSV (CSV with base64 encoded input field to avoid CSV breakage with payloads containing a comma)
- New CLI flag to follow redirects
- Erroring connections will be retried once
- Error counter in status bar
- New CLI flags: -se (stop on spurious errors) and -sa (stop on all errors, implies -se and -sf)
- New CLI flags: -e to provide a list of extensions to add to wordlist entries, and -D to provide DirSearch wordlist format compatibility.
- Wildcard option for response status code matcher.
- New
- New output file formats: CSV and eCSV (CSV with base64 encoded input field to avoid CSV breakage with payloads containing a comma)
- New CLI flag to follow redirects
- Erroring connections will be retried once
- Error counter in status bar
- New CLI flags: -se (stop on spurious errors) and -sa (stop on all errors, implies -se and -sf)
- New CLI flags: -e to provide a list of extensions to add to wordlist entries, and -D to provide DirSearch wordlist format compatibility.
- Wildcard option for response status code matcher.
- v0.8
- New
- New CLI flag to write output to a file in JSON format
- New CLI flag to stop on spurious 403 responses
- Changed
- Regex matching / filtering now matches the headers alongside of the response body
- New
- New CLI flag to write output to a file in JSON format
- New CLI flag to stop on spurious 403 responses
- Changed
- Regex matching / filtering now matches the headers alongside of the response body
## TODO
- Tests!
- Optional scope for redirects
- Client / server architecture to queue jobs and fetch the results later
- Fuzzing multiple values at the same time
- Output module to push the results to an HTTP API
- Tests!
- Optional scope for redirects
- Client / server architecture to queue jobs and fetch the results later
- Fuzzing multiple values at the same time
- Output module to push the results to an HTTP API

View File

@ -82,6 +82,7 @@ func main() {
flag.StringVar(&conf.Method, "X", "GET", "HTTP method to use")
flag.StringVar(&conf.OutputFile, "o", "", "Write output to file")
flag.StringVar(&opts.outputFormat, "of", "json", "Output file format. Available formats: json, 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.StopOn403, "sf", false, "Stop when > 95% of responses return 403 Forbidden")
flag.BoolVar(&conf.StopOnErrors, "se", false, "Stop on spurious errors")

View File

@ -16,35 +16,36 @@ type optRange struct {
}
type Config struct {
StaticHeaders map[string]string
FuzzHeaders map[string]string
Extensions []string
DirSearchCompat bool
Method string
Url string
TLSVerify bool
Data string
Quiet bool
Colors bool
Wordlist string
InputCommand string
InputNum int
OutputFile string
OutputFormat string
StopOn403 bool
StopOnErrors bool
StopOnAll bool
FollowRedirects bool
AutoCalibration bool
Timeout int
ProgressFrequency int
Delay optRange
Filters []FilterProvider
Matchers []FilterProvider
Threads int
Context context.Context
ProxyURL func(*http.Request) (*url.URL, error)
CommandLine string
StaticHeaders map[string]string
FuzzHeaders map[string]string
Extensions []string
DirSearchCompat bool
Method string
Url string
TLSVerify bool
Data string
Quiet bool
Colors bool
Wordlist string
InputCommand string
InputNum int
OutputFile string
OutputFormat string
StopOn403 bool
StopOnErrors bool
StopOnAll bool
FollowRedirects bool
AutoCalibration bool
ShowRedirectLocation bool
Timeout int
ProgressFrequency int
Delay optRange
Filters []FilterProvider
Matchers []FilterProvider
Threads int
Context context.Context
ProxyURL func(*http.Request) (*url.URL, error)
CommandLine string
}
func NewConfig(ctx context.Context) Config {
@ -60,6 +61,7 @@ func NewConfig(ctx context.Context) Config {
conf.StopOn403 = false
conf.StopOnErrors = false
conf.StopOnAll = false
conf.ShowRedirectLocation = false
conf.FollowRedirects = false
conf.InputCommand = ""
conf.InputNum = 0

View File

@ -15,6 +15,17 @@ type Response struct {
Request *Request
}
// GetRedirectLocation returns the redirect location for a 3xx redirect HTTP response
func (resp *Response) GetRedirectLocation() string {
redirectLocation := ""
if resp.StatusCode >= 300 && resp.StatusCode <= 399 {
redirectLocation = resp.Headers["Location"][0]
}
return redirectLocation
}
func NewResponse(httpresp *http.Response, req *Request) Response {
var resp Response
resp.Request = req

View File

@ -156,14 +156,25 @@ func (s *Stdoutput) resultQuiet(resp ffuf.Response) {
}
func (s *Stdoutput) resultNormal(resp ffuf.Response) {
var res_str string
var responseString string
if len(s.config.InputCommand) > 0 {
// If we're using external command for input, display the position instead of input
res_str = fmt.Sprintf("%s%-23s [Status: %s, Size: %d, Words: %d]", TERMINAL_CLEAR_LINE, strconv.Itoa(resp.Request.Position), s.colorizeStatus(resp.StatusCode), resp.ContentLength, resp.ContentWords)
responseString = fmt.Sprintf("%s%-23s [Status: %s, Size: %d, Words: %d%s]", TERMINAL_CLEAR_LINE, strconv.Itoa(resp.Request.Position), s.colorizeStatus(resp.StatusCode), resp.ContentLength, resp.ContentWords, s.addRedirectLocation(resp))
} else {
res_str = fmt.Sprintf("%s%-23s [Status: %s, Size: %d, Words: %d]", TERMINAL_CLEAR_LINE, resp.Request.Input, s.colorizeStatus(resp.StatusCode), resp.ContentLength, resp.ContentWords)
responseString = fmt.Sprintf("%s%-23s [Status: %s, Size: %d, Words: %d%s]", TERMINAL_CLEAR_LINE, resp.Request.Input, s.colorizeStatus(resp.StatusCode), resp.ContentLength, resp.ContentWords, s.addRedirectLocation(resp))
}
fmt.Println(res_str)
fmt.Println(responseString)
}
// 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) colorizeStatus(status int64) string {