Skip to content

Commit

Permalink
Added redirect location in stdout output (#59)
Browse files Browse the repository at this point in the history
* 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 ->)
  • Loading branch information
SakiiR authored and joohoi committed Oct 14, 2019
1 parent 55662e6 commit 081e40f
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 71 deletions.
80 changes: 42 additions & 38 deletions README.md
Expand Up @@ -7,7 +7,6 @@
\/_/ \/_/ \/___/ \/_/
```


# ffuf - Fuzz Faster U Fool

A fast web fuzzer written in Go.
Expand Down Expand Up @@ -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 change: 1 addition & 0 deletions main.go
Expand Up @@ -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")
Expand Down
60 changes: 31 additions & 29 deletions pkg/ffuf/config.go
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
11 changes: 11 additions & 0 deletions pkg/ffuf/response.go
Expand Up @@ -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
Expand Down
19 changes: 15 additions & 4 deletions pkg/output/stdout.go
Expand Up @@ -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 {
Expand Down

0 comments on commit 081e40f

Please sign in to comment.