diff --git a/README.md b/README.md index 29919bc..3ae0364 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ CONFIGURATIONS: -c, -concurrency int Concurrency level (default 50) -t, -timeout int Connection timeout in seconds (default 10) -rl, -rate-limit int Set a rate limit (per second) + -px, -proxy string Set a proxy server (URL) OUTPUT: -o, -output string File to write output results @@ -130,6 +131,12 @@ JSON Output cat targets.txt | csprecon -j ``` +Use a Proxy + +```bash +cat targets.txt | csprecon -px http://127.0.0.1:8080 +``` + Changelog 📌 ------- diff --git a/pkg/csprecon/csp.go b/pkg/csprecon/csp.go index 8934020..7dc96d3 100644 --- a/pkg/csprecon/csp.go +++ b/pkg/csprecon/csp.go @@ -12,10 +12,12 @@ import ( "log" "net" "net/http" + "net/url" "regexp" "time" "github.com/PuerkitoBio/goquery" + "github.com/edoardottt/csprecon/pkg/input" "github.com/edoardottt/golazy" "github.com/projectdiscovery/gologger" ) @@ -88,21 +90,34 @@ func ParseBodyCSP(body io.Reader, rCSP *regexp.Regexp) []string { return result } -func customClient(timeout int) *http.Client { +func customClient(options *input.Options) (*http.Client, error) { transport := http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, Proxy: http.ProxyFromEnvironment, Dial: (&net.Dialer{ - Timeout: time.Duration(timeout) * time.Second, + Timeout: time.Duration(options.Timeout) * time.Second, KeepAlive: KeepAlive * time.Second, }).Dial, TLSHandshakeTimeout: TLSHandshakeTimeout * time.Second, } + if options.Proxy != "" { + u, err := url.Parse(options.Proxy) + if err != nil { + return nil, err + } + + transport.Proxy = http.ProxyURL(u) + + if options.Verbose { + gologger.Debug().Msgf("Using Proxy %s", options.Proxy) + } + } + client := http.Client{ Transport: &transport, - Timeout: time.Duration(timeout) * time.Second, + Timeout: time.Duration(options.Timeout) * time.Second, } - return &client + return &client, nil } diff --git a/pkg/csprecon/csprecon.go b/pkg/csprecon/csprecon.go index 9db7f7e..94bb29d 100644 --- a/pkg/csprecon/csprecon.go +++ b/pkg/csprecon/csprecon.go @@ -141,16 +141,19 @@ func execute(r *Runner) { for value := range r.Input { targetURL, err := PrepareURL(value) if err != nil { - if r.Options.Verbose { - gologger.Error().Msgf("%s", err) - } + gologger.Error().Msgf("%s", err) return } rl.Take() - client := customClient(r.Options.Timeout) + client, err := customClient(&r.Options) + if err != nil { + gologger.Error().Msgf("%s", err) + + return + } result, err := CheckCSP(targetURL, r.UserAgent, dregex, client) if err != nil { diff --git a/pkg/input/check.go b/pkg/input/check.go index 912fbf4..149e803 100644 --- a/pkg/input/check.go +++ b/pkg/input/check.go @@ -9,6 +9,7 @@ package input import ( "errors" "fmt" + "net/url" fileutil "github.com/projectdiscovery/utils/file" ) @@ -38,5 +39,20 @@ func (options *Options) validateOptions() error { return fmt.Errorf("rate limit: %w", ErrNegativeValue) } + if options.Proxy != "" && !checkProxy(options.Proxy) { + _, err := url.Parse(options.Proxy) + return fmt.Errorf("proxy URL: %w", err) + } + return nil } + +func checkProxy(proxy string) bool { + if len(proxy) == 0 { + return false + } + + _, err := url.Parse(proxy) + + return err == nil +} diff --git a/pkg/input/flags.go b/pkg/input/flags.go index 44b0a75..4dc9880 100644 --- a/pkg/input/flags.go +++ b/pkg/input/flags.go @@ -36,6 +36,7 @@ type Options struct { Timeout int Cidr bool RateLimit int + Proxy string } // configureOutput configures the output on the screen. @@ -66,6 +67,7 @@ func ParseOptions() *Options { flagSet.IntVarP(&options.Concurrency, "concurrency", "c", DefaultConcurrency, `Concurrency level`), flagSet.IntVarP(&options.Timeout, "timeout", "t", DefaultTimeout, `Connection timeout in seconds`), flagSet.IntVarP(&options.RateLimit, "rate-limit", "rl", DefaultRateLimit, `Set a rate limit (per second)`), + flagSet.StringVarP(&options.Proxy, "proxy", "px", "", `Set a proxy server (URL)`), ) // Output diff --git a/pkg/output/banner.go b/pkg/output/banner.go index bb274f3..faa3463 100644 --- a/pkg/output/banner.go +++ b/pkg/output/banner.go @@ -12,7 +12,7 @@ import "github.com/projectdiscovery/gologger" var printed = false const ( - Version = "v0.2.0" + Version = "v0.2.1" banner = ` ______________ ________ _________ ____ / ___/ ___/ __ \/ ___/ _ \/ ___/ __ \/ __ \ / /__(__ ) /_/ / / / __/ /__/ /_/ / / / / diff --git a/snapcraft.yaml b/snapcraft.yaml index 2dc5c71..84f3def 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -3,7 +3,7 @@ summary: Discover new target domains using Content Security Policy description: | Take as input target URLs and probe them to retrieve their CSP (either from Head or Header) and get new target domains. -version: 0.2.0 +version: 0.2.1 grade: stable base: core20