From 42489f6d9710e4467f0239f3f5ba4e9a305490e7 Mon Sep 17 00:00:00 2001 From: Ice3man543 Date: Mon, 27 Apr 2020 23:49:53 +0530 Subject: [PATCH] Added proxy URL support --- internal/runner/options.go | 2 ++ internal/runner/runner.go | 13 +++++++++---- pkg/executor/executer_http.go | 12 ++++++++++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/internal/runner/options.go b/internal/runner/options.go index 302f47a5..3ec1ac18 100644 --- a/internal/runner/options.go +++ b/internal/runner/options.go @@ -16,6 +16,7 @@ type Options struct { Timeout int // Timeout is the seconds to wait for a response from the server. Retries int // Retries is the number of times to retry the request Output string // Output is the file to write found subdomains to. + ProxyURL string // ProxyURL is the URL for the proxy server Silent bool // Silent suppresses any extra text and only writes found URLs on screen. Version bool // Version specifies if we should just show version and exit Verbose bool // Verbose flag indicates whether to show verbose output or not @@ -31,6 +32,7 @@ func ParseOptions() *Options { flag.StringVar(&options.Templates, "t", "", "Template input file/files to run on host") flag.StringVar(&options.Targets, "l", "", "List of URLs to run templates on") flag.StringVar(&options.Output, "o", "", "File to write output to (optional)") + flag.StringVar(&options.ProxyURL, "proxy-url", "", "URL of the proxy server") flag.BoolVar(&options.Silent, "silent", false, "Show only results in output") flag.BoolVar(&options.Version, "version", false, "Show version of nuclei") flag.BoolVar(&options.Verbose, "v", false, "Show Verbose output") diff --git a/internal/runner/runner.go b/internal/runner/runner.go index c562d1fb..3545118d 100644 --- a/internal/runner/runner.go +++ b/internal/runner/runner.go @@ -139,9 +139,6 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i } gologger.Infof("%s\n", message) - limiter := make(chan struct{}, r.options.Threads) - wg := &sync.WaitGroup{} - var writer *bufio.Writer if r.output != nil { writer = bufio.NewWriter(r.output) @@ -150,6 +147,7 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i var httpExecutor *executor.HTTPExecutor var dnsExecutor *executor.DNSExecutor + var err error // Create an executor based on the request type. switch value := request.(type) { @@ -160,7 +158,7 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i Writer: writer, }) case *requests.HTTPRequest: - httpExecutor = executor.NewHTTPExecutor(&executor.HTTPOptions{ + httpExecutor, err = executor.NewHTTPExecutor(&executor.HTTPOptions{ Template: template, HTTPRequest: value, Writer: writer, @@ -168,6 +166,13 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i Retries: r.options.Retries, }) } + if err != nil { + gologger.Warningf("Could not create http client: %s\n", err) + return + } + + limiter := make(chan struct{}, r.options.Threads) + wg := &sync.WaitGroup{} scanner := bufio.NewScanner(reader) for scanner.Scan() { diff --git a/pkg/executor/executer_http.go b/pkg/executor/executer_http.go index 2021142f..ccc8c1da 100644 --- a/pkg/executor/executer_http.go +++ b/pkg/executor/executer_http.go @@ -6,6 +6,7 @@ import ( "io" "io/ioutil" "net/http" + "net/url" "sync" "time" @@ -34,20 +35,27 @@ type HTTPOptions struct { Writer *bufio.Writer Timeout int Retries int + ProxyURL string } // NewHTTPExecutor creates a new HTTP executor from a template // and a HTTP request query. -func NewHTTPExecutor(options *HTTPOptions) *HTTPExecutor { +func NewHTTPExecutor(options *HTTPOptions) (*HTTPExecutor, error) { retryablehttpOptions := retryablehttp.DefaultOptionsSpraying retryablehttpOptions.RetryWaitMax = 10 * time.Second retryablehttpOptions.RetryMax = options.Retries followRedirects := options.HTTPRequest.Redirects maxRedirects := options.HTTPRequest.MaxRedirects + proxyURL, err := url.Parse(options.ProxyURL) + if err != nil { + return nil, err + } + // Create the HTTP Client client := retryablehttp.NewWithHTTPClient(&http.Client{ Transport: &http.Transport{ + Proxy: http.ProxyURL(proxyURL), MaxIdleConnsPerHost: -1, TLSClientConfig: &tls.Config{ Renegotiation: tls.RenegotiateOnceAsClient, @@ -81,7 +89,7 @@ func NewHTTPExecutor(options *HTTPOptions) *HTTPExecutor { outputMutex: &sync.Mutex{}, writer: options.Writer, } - return executer + return executer, nil } // ExecuteHTTP executes the HTTP request on a URL