From 80a4aa7783a9c34f0b8ee95c0f2714be97c87039 Mon Sep 17 00:00:00 2001 From: Maxime Catrice Date: Fri, 28 Jan 2022 16:49:53 +0100 Subject: [PATCH] Fix -of all output and add HTTP/2 support (#451) (#462) * Fix -of all output (#451) * Add HTTP/2 support --- CHANGELOG.md | 2 ++ CONTRIBUTORS.md | 1 + help.go | 2 +- main.go | 1 + pkg/ffuf/config.go | 2 ++ pkg/ffuf/optionsparser.go | 3 +++ pkg/output/stdout.go | 12 ++++++------ pkg/runner/simple.go | 2 +- 8 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8efbd86..b9b3d73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ - Fixed an issue where output file was created regardless of `-or` - Fixed an issue where output (often a lot of it) would be printed after entering interactive mode - Fixed an issue when reading wordlist files from ffufrc + - Fixed an issue where `-of all` option only creates one output file (instead of all formats) + - Added HTTP2 support - v1.3.1 - New diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 7c61602..1624978 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -18,6 +18,7 @@ * [eur0pa](https://github.com/eur0pa) * [fabiobauer](https://github.com/fabiobauer) * [fang0654](https://github.com/fang0654) +* [Hazegard](https://github.com/Hazegard) * [helpermika](https://github.com/helpermika) * [Ice3man543](https://github.com/Ice3man543) * [JamTookTheBait](https://github.com/JamTookTheBait) diff --git a/help.go b/help.go index f235e28..37b309a 100644 --- a/help.go +++ b/help.go @@ -54,7 +54,7 @@ func Usage() { Description: "Options controlling the HTTP request and its parts.", Flags: make([]UsageFlag, 0), Hidden: false, - ExpectedFlags: []string{"H", "X", "b", "d", "r", "u", "recursion", "recursion-depth", "recursion-strategy", "replay-proxy", "timeout", "ignore-body", "x", "sni"}, + ExpectedFlags: []string{"H", "X", "b", "d", "r", "u", "recursion", "recursion-depth", "recursion-strategy", "replay-proxy", "timeout", "ignore-body", "x", "sni", "http2"}, } u_general := UsageSection{ Name: "GENERAL OPTIONS", diff --git a/main.go b/main.go index 3463601..97a9c9b 100644 --- a/main.go +++ b/main.go @@ -73,6 +73,7 @@ func ParseFlags(opts *ffuf.ConfigOptions) *ffuf.ConfigOptions { flag.BoolVar(&opts.HTTP.FollowRedirects, "r", opts.HTTP.FollowRedirects, "Follow redirects") flag.BoolVar(&opts.HTTP.IgnoreBody, "ignore-body", opts.HTTP.IgnoreBody, "Do not fetch the response content.") flag.BoolVar(&opts.HTTP.Recursion, "recursion", opts.HTTP.Recursion, "Scan recursively. Only FUZZ keyword is supported, and URL (-u) has to end in it.") + flag.BoolVar(&opts.HTTP.Http2, "http2", opts.HTTP.Http2, "Use HTTP2 protocol") flag.BoolVar(&opts.Input.DirSearchCompat, "D", opts.Input.DirSearchCompat, "DirSearch wordlist compatibility mode. Used in conjunction with -e flag.") flag.BoolVar(&opts.Input.IgnoreWordlistComments, "ic", opts.Input.IgnoreWordlistComments, "Ignore wordlist comments") flag.IntVar(&opts.General.MaxTime, "maxtime", opts.General.MaxTime, "Maximum running time in seconds for entire process.") diff --git a/pkg/ffuf/config.go b/pkg/ffuf/config.go index 9dc666c..0a756ee 100644 --- a/pkg/ffuf/config.go +++ b/pkg/ffuf/config.go @@ -51,6 +51,7 @@ type Config struct { Timeout int `json:"timeout"` Url string `json:"url"` Verbose bool `json:"verbose"` + Http2 bool `json:"http2"` } type InputProviderConfig struct { @@ -96,6 +97,7 @@ func NewConfig(ctx context.Context, cancel context.CancelFunc) Config { conf.Timeout = 10 conf.Url = "" conf.Verbose = false + conf.Http2 = false return conf } diff --git a/pkg/ffuf/optionsparser.go b/pkg/ffuf/optionsparser.go index dc222b5..a6555a7 100644 --- a/pkg/ffuf/optionsparser.go +++ b/pkg/ffuf/optionsparser.go @@ -40,6 +40,7 @@ type HTTPOptions struct { SNI string Timeout int URL string + Http2 bool } type GeneralOptions struct { @@ -135,6 +136,7 @@ func NewConfigOptions() *ConfigOptions { c.HTTP.Timeout = 10 c.HTTP.SNI = "" c.HTTP.URL = "" + c.HTTP.Http2 = false c.Input.DirSearchCompat = false c.Input.Extensions = "" c.Input.IgnoreWordlistComments = false @@ -410,6 +412,7 @@ func ConfigFromOptions(parseOpts *ConfigOptions, ctx context.Context, cancel con conf.MaxTimeJob = parseOpts.General.MaxTimeJob conf.Noninteractive = parseOpts.General.Noninteractive conf.Verbose = parseOpts.General.Verbose + conf.Http2 = parseOpts.HTTP.Http2 // Handle copy as curl situation where POST method is implied by --data flag. If method is set to anything but GET, NOOP if len(conf.Data) > 0 && diff --git a/pkg/output/stdout.go b/pkg/output/stdout.go index 0c68dcc..138e361 100644 --- a/pkg/output/stdout.go +++ b/pkg/output/stdout.go @@ -226,37 +226,37 @@ func (s *Stdoutput) writeToAll(filename string, config *ffuf.Config, res []ffuf. // the suffix to each output file. s.config.OutputFile = BaseFilename + ".json" - err = writeJSON(filename, s.config, res) + err = writeJSON(s.config.OutputFile, s.config, res) if err != nil { s.Error(err.Error()) } s.config.OutputFile = BaseFilename + ".ejson" - err = writeEJSON(filename, s.config, res) + err = writeEJSON(s.config.OutputFile, s.config, res) if err != nil { s.Error(err.Error()) } s.config.OutputFile = BaseFilename + ".html" - err = writeHTML(filename, s.config, res) + err = writeHTML(s.config.OutputFile, s.config, res) if err != nil { s.Error(err.Error()) } s.config.OutputFile = BaseFilename + ".md" - err = writeMarkdown(filename, s.config, res) + err = writeMarkdown(s.config.OutputFile, s.config, res) if err != nil { s.Error(err.Error()) } s.config.OutputFile = BaseFilename + ".csv" - err = writeCSV(filename, s.config, res, false) + err = writeCSV(s.config.OutputFile, s.config, res, false) if err != nil { s.Error(err.Error()) } s.config.OutputFile = BaseFilename + ".ecsv" - err = writeCSV(filename, s.config, res, true) + err = writeCSV(s.config.OutputFile, s.config, res, true) if err != nil { s.Error(err.Error()) } diff --git a/pkg/runner/simple.go b/pkg/runner/simple.go index 3f1c6f5..3ea25bb 100644 --- a/pkg/runner/simple.go +++ b/pkg/runner/simple.go @@ -42,12 +42,12 @@ func NewSimpleRunner(conf *ffuf.Config, replay bool) ffuf.RunnerProvider { proxyURL = http.ProxyURL(pu) } } - simplerunner.config = conf simplerunner.client = &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, Timeout: time.Duration(time.Duration(conf.Timeout) * time.Second), Transport: &http.Transport{ + ForceAttemptHTTP2: conf.Http2, Proxy: proxyURL, MaxIdleConns: 1000, MaxIdleConnsPerHost: 500,