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:
parent
55662e607a
commit
081e40f97e
78
README.md
78
README.md
@ -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
|
||||
|
||||
1
main.go
1
main.go
@ -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")
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user