diff --git a/main.go b/main.go index 0379c1d..fc507bf 100644 --- a/main.go +++ b/main.go @@ -51,6 +51,7 @@ func main() { flag.StringVar(&opts.filterStatus, "fc", "", "Filter HTTP status codes from response") flag.StringVar(&opts.filterSize, "fs", "", "Filter HTTP response size") flag.StringVar(&conf.Data, "d", "", "POST data.") + flag.BoolVar(&conf.Colors, "c", false, "Colorize output.") //flag.StringVar(&opts.filterRegex, "fr", "", "Filter regex") //flag.StringVar(&opts.filterReflect, "fref", "", "Filter reflected payload") flag.StringVar(&opts.matcherStatus, "mc", "200,204,301,302,307,401", "Match HTTP status codes from respose") diff --git a/pkg/ffuf/config.go b/pkg/ffuf/config.go index c8e43c4..7d205b3 100644 --- a/pkg/ffuf/config.go +++ b/pkg/ffuf/config.go @@ -12,6 +12,7 @@ type Config struct { TLSSkipVerify bool Data string Quiet bool + Colors bool Wordlist string Filters []FilterProvider Matchers []FilterProvider diff --git a/pkg/ffuf/job.go b/pkg/ffuf/job.go index 60f2dc5..ffc4989 100644 --- a/pkg/ffuf/job.go +++ b/pkg/ffuf/job.go @@ -70,6 +70,11 @@ func (j *Job) runProgress(wg *sync.WaitGroup) { } func (j *Job) updateProgress() { + //TODO: refactor to use a defined progress struct for future output modules + if j.Config.Quiet { + // Do not print progress status in silent mode + return + } dur := time.Now().Sub(j.startTime) hours := dur / time.Hour dur -= hours * time.Hour diff --git a/pkg/output/const.go b/pkg/output/const.go index 8e89a11..b10bbcf 100644 --- a/pkg/output/const.go +++ b/pkg/output/const.go @@ -4,4 +4,9 @@ package output const ( TERMINAL_CLEAR_LINE = "\r\x1b[2K" + ANSI_CLEAR = "\x1b[0m" + ANSI_RED = "\x1b[31m" + ANSI_GREEN = "\x1b[32m" + ANSI_BLUE = "\x1b[34m" + ANSI_YELLOW = "\x1b[33m" ) diff --git a/pkg/output/const_windows.go b/pkg/output/const_windows.go index de0dbf5..642beba 100644 --- a/pkg/output/const_windows.go +++ b/pkg/output/const_windows.go @@ -4,4 +4,9 @@ package output const ( TERMINAL_CLEAR_LINE = "\r\r" + ANSI_CLEAR = "" + ANSI_RED = "" + ANSI_GREEN = "" + ANSI_BLUE = "" + ANSI_YELLOW = "" ) diff --git a/pkg/output/stdout.go b/pkg/output/stdout.go index 1414450..4add71f 100644 --- a/pkg/output/stdout.go +++ b/pkg/output/stdout.go @@ -98,10 +98,30 @@ func (s *Stdoutput) resultQuiet(resp ffuf.Response) { } func (s *Stdoutput) resultNormal(resp ffuf.Response) { - res_str := fmt.Sprintf("%s%-23s [Status: %d, Size: %d]", TERMINAL_CLEAR_LINE, resp.Request.Input, resp.StatusCode, resp.ContentLength) + res_str := fmt.Sprintf("%s%-23s [Status: %s, Size: %d]", TERMINAL_CLEAR_LINE, resp.Request.Input, s.colorizeStatus(resp.StatusCode), resp.ContentLength) fmt.Println(res_str) } +func (s *Stdoutput) colorizeStatus(status int64) string { + if !s.config.Colors { + return fmt.Sprintf("%d", status) + } + colorCode := ANSI_CLEAR + if status >= 200 && status < 300 { + colorCode = ANSI_GREEN + } + if status >= 300 && status < 400 { + colorCode = ANSI_BLUE + } + if status >= 400 && status < 500 { + colorCode = ANSI_YELLOW + } + if status >= 500 && status < 600 { + colorCode = ANSI_RED + } + return fmt.Sprintf("%s%d%s", colorCode, status, ANSI_CLEAR) +} + func printOption(name []byte, value []byte) { fmt.Printf(" :: %-12s : %s\n", name, value) } diff --git a/pkg/runner/simple.go b/pkg/runner/simple.go index 34c26e1..0a49821 100644 --- a/pkg/runner/simple.go +++ b/pkg/runner/simple.go @@ -64,6 +64,10 @@ func (r *SimpleRunner) Execute(req *ffuf.Request) (ffuf.Response, error) { if _, ok := req.Headers["User-Agent"]; !ok { req.Headers["User-Agent"] = fmt.Sprintf("%s v%s", "Fuzz Faster U Fool", ffuf.VERSION) } + // Handle Go http.Request special cases + if _, ok := req.Headers["Host"]; ok { + httpreq.Host = req.Headers["Host"] + } httpreq = httpreq.WithContext(r.config.Context) for k, v := range req.Headers { httpreq.Header.Set(k, v)