From 301968cb1ce179226ef7db715d4aa591385f46fb Mon Sep 17 00:00:00 2001 From: Serizao <11671895+Serizao@users.noreply.github.com> Date: Tue, 12 Sep 2023 14:50:31 +0200 Subject: [PATCH] Add cert authentication to crawl (#713) * Add cert authentication to crawl * Update CONTRIBUTORS.md * Update CONTRIBUTORS.md --- CONTRIBUTORS.md | 1 + main.go | 2 ++ pkg/ffuf/config.go | 2 ++ pkg/ffuf/optionsparser.go | 11 +++++++++++ pkg/runner/simple.go | 8 ++++++++ 5 files changed, 24 insertions(+) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1ac6520..4ae7b2c 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -41,6 +41,7 @@ * [putsi](https://github.com/putsi) * [SakiiR](https://github.com/SakiiR) * [seblw](https://github.com/seblw) +* [Serizao](https://github.com/Serizao) * [Shaked](https://github.com/Shaked) * [Skyehopper](https://github.com/Skyehopper) * [SolomonSklash](https://github.com/SolomonSklash) diff --git a/main.go b/main.go index 6074198..372d957 100644 --- a/main.go +++ b/main.go @@ -89,6 +89,8 @@ func ParseFlags(opts *ffuf.ConfigOptions) *ffuf.ConfigOptions { flag.IntVar(&opts.HTTP.Timeout, "timeout", opts.HTTP.Timeout, "HTTP request timeout in seconds.") flag.IntVar(&opts.Input.InputNum, "input-num", opts.Input.InputNum, "Number of inputs to test. Used in conjunction with --input-cmd.") flag.StringVar(&opts.General.AutoCalibrationKeyword, "ack", opts.General.AutoCalibrationKeyword, "Autocalibration keyword") + flag.StringVar(&opts.HTTP.ClientCert, "cc", "", "Client cert to auth must be define with client key too") + flag.StringVar(&opts.HTTP.ClientKey, "ck", "", "Client key to auth must be define with client cert too") flag.StringVar(&opts.General.AutoCalibrationStrategy, "acs", opts.General.AutoCalibrationStrategy, "Autocalibration strategy: \"basic\" or \"advanced\"") flag.StringVar(&opts.General.ConfigFile, "config", "", "Load configuration from a file") flag.StringVar(&opts.General.ScraperFile, "scraperfile", "", "Custom scraper file path") diff --git a/pkg/ffuf/config.go b/pkg/ffuf/config.go index d62ee0f..1ac0391 100644 --- a/pkg/ffuf/config.go +++ b/pkg/ffuf/config.go @@ -64,6 +64,8 @@ type Config struct { Verbose bool `json:"verbose"` Wordlists []string `json:"wordlists"` Http2 bool `json:"http2"` + ClientCert string `json:"client-cert"` + ClientKey string `json:"client-key"` } type InputProviderConfig struct { diff --git a/pkg/ffuf/optionsparser.go b/pkg/ffuf/optionsparser.go index 42d3504..e0aefb5 100644 --- a/pkg/ffuf/optionsparser.go +++ b/pkg/ffuf/optionsparser.go @@ -41,6 +41,8 @@ type HTTPOptions struct { Timeout int `json:"timeout"` URL string `json:"url"` Http2 bool `json:"http2"` + ClientCert string `json:"client-cert"` + ClientKey string `json:"client-key"` } type GeneralOptions struct { @@ -361,6 +363,15 @@ func ConfigFromOptions(parseOpts *ConfigOptions, ctx context.Context, cancel con conf.SNI = parseOpts.HTTP.SNI } + // prepare cert + if parseOpts.HTTP.ClientCert != "" { + conf.ClientCert = parseOpts.HTTP.ClientCert + } + if parseOpts.HTTP.ClientKey != "" { + conf.ClientKey = parseOpts.HTTP.ClientKey + } + + //Prepare headers and make canonical for _, v := range parseOpts.HTTP.Headers { hs := strings.SplitN(v, ":", 2) diff --git a/pkg/runner/simple.go b/pkg/runner/simple.go index 495ff8f..096fafe 100644 --- a/pkg/runner/simple.go +++ b/pkg/runner/simple.go @@ -43,6 +43,13 @@ func NewSimpleRunner(conf *ffuf.Config, replay bool) ffuf.RunnerProvider { proxyURL = http.ProxyURL(pu) } } + cert := []tls.Certificate{} + + if conf.ClientCert != "" && conf.ClientKey != "" { + tmp, _ := tls.LoadX509KeyPair(conf.ClientCert, conf.ClientKey) + cert = []tls.Certificate{tmp} + } + simplerunner.config = conf simplerunner.client = &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, @@ -62,6 +69,7 @@ func NewSimpleRunner(conf *ffuf.Config, replay bool) ffuf.RunnerProvider { MinVersion: tls.VersionTLS10, Renegotiation: tls.RenegotiateOnceAsClient, ServerName: conf.SNI, + Certificates: cert, }, }}