Added better debug and verbose modes

This commit is contained in:
Ice3man543 2020-06-22 19:30:01 +05:30
parent b3e970405d
commit be3157eac3
4 changed files with 50 additions and 0 deletions

View File

@ -11,6 +11,7 @@ import (
// Options contains the configuration options for tuning // Options contains the configuration options for tuning
// the template requesting process. // the template requesting process.
type Options struct { type Options struct {
Debug bool // Debug mode allows debugging request/responses for the engine
Templates string // Signature specifies the template/templates to use Templates string // Signature specifies the template/templates to use
Targets string // Targets specifies the targets to scan using templates. Targets string // Targets specifies the targets to scan using templates.
Threads int // Thread controls the number of concurrent requests to make. Threads int // Thread controls the number of concurrent requests to make.
@ -45,6 +46,7 @@ func ParseOptions() *Options {
flag.IntVar(&options.Timeout, "timeout", 5, "Time to wait in seconds before timeout") flag.IntVar(&options.Timeout, "timeout", 5, "Time to wait in seconds before timeout")
flag.IntVar(&options.Retries, "retries", 1, "Number of times to retry a failed request") flag.IntVar(&options.Retries, "retries", 1, "Number of times to retry a failed request")
flag.Var(&options.CustomHeaders, "H", "Custom Header.") flag.Var(&options.CustomHeaders, "H", "Custom Header.")
flag.BoolVar(&options.Debug, "debug", false, "Allow debugging of request/responses")
flag.Parse() flag.Parse()

View File

@ -189,12 +189,14 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i
switch value := request.(type) { switch value := request.(type) {
case *requests.DNSRequest: case *requests.DNSRequest:
dnsExecutor = executor.NewDNSExecutor(&executor.DNSOptions{ dnsExecutor = executor.NewDNSExecutor(&executor.DNSOptions{
Debug: r.options.Debug,
Template: template, Template: template,
DNSRequest: value, DNSRequest: value,
Writer: writer, Writer: writer,
}) })
case *requests.HTTPRequest: case *requests.HTTPRequest:
httpExecutor, err = executor.NewHTTPExecutor(&executor.HTTPOptions{ httpExecutor, err = executor.NewHTTPExecutor(&executor.HTTPOptions{
Debug: r.options.Debug,
Template: template, Template: template,
HTTPRequest: value, HTTPRequest: value,
Writer: writer, Writer: writer,

View File

@ -7,12 +7,15 @@ import (
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/http/httputil"
"net/url" "net/url"
"os"
"strings" "strings"
"sync" "sync"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/nuclei/pkg/extractors" "github.com/projectdiscovery/nuclei/pkg/extractors"
"github.com/projectdiscovery/nuclei/pkg/matchers" "github.com/projectdiscovery/nuclei/pkg/matchers"
"github.com/projectdiscovery/nuclei/pkg/requests" "github.com/projectdiscovery/nuclei/pkg/requests"
@ -24,6 +27,7 @@ import (
// HTTPExecutor is client for performing HTTP requests // HTTPExecutor is client for performing HTTP requests
// for a template. // for a template.
type HTTPExecutor struct { type HTTPExecutor struct {
debug bool
httpClient *retryablehttp.Client httpClient *retryablehttp.Client
template *templates.Template template *templates.Template
httpRequest *requests.HTTPRequest httpRequest *requests.HTTPRequest
@ -41,6 +45,7 @@ type HTTPOptions struct {
Retries int Retries int
ProxyURL string ProxyURL string
ProxySocksURL string ProxySocksURL string
Debug bool
CustomHeaders requests.CustomHeaders CustomHeaders requests.CustomHeaders
} }
@ -62,6 +67,7 @@ func NewHTTPExecutor(options *HTTPOptions) (*HTTPExecutor, error) {
client.CheckRetry = retryablehttp.HostSprayRetryPolicy() client.CheckRetry = retryablehttp.HostSprayRetryPolicy()
executer := &HTTPExecutor{ executer := &HTTPExecutor{
debug: options.Debug,
httpClient: client, httpClient: client,
template: options.Template, template: options.Template,
httpRequest: options.HTTPRequest, httpRequest: options.HTTPRequest,
@ -88,6 +94,16 @@ mainLoop:
} }
e.setCustomHeaders(compiledRequest) e.setCustomHeaders(compiledRequest)
req := compiledRequest.Request req := compiledRequest.Request
if e.debug {
gologger.Infof("Dumped HTTP request for %s (%s)\n\n", URL, e.template.ID)
dumpedRequest, err := httputil.DumpRequest(req.Request, true)
if err != nil {
return errors.Wrap(err, "could not dump http request")
}
fmt.Fprintf(os.Stderr, "%s", string(dumpedRequest))
}
resp, err := e.httpClient.Do(req) resp, err := e.httpClient.Do(req)
if err != nil { if err != nil {
if resp != nil { if resp != nil {
@ -96,6 +112,15 @@ mainLoop:
return errors.Wrap(err, "could not make http request") return errors.Wrap(err, "could not make http request")
} }
if e.debug {
gologger.Infof("Dumped HTTP response for %s (%s)\n\n", URL, e.template.ID)
dumpedResponse, err := httputil.DumpResponse(resp, true)
if err != nil {
return errors.Wrap(err, "could not dump http response")
}
fmt.Fprintf(os.Stderr, "%s\n", string(dumpedResponse))
}
data, err := ioutil.ReadAll(resp.Body) data, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
io.Copy(ioutil.Discard, resp.Body) io.Copy(ioutil.Discard, resp.Body)
@ -157,6 +182,9 @@ mainLoop:
e.writeOutputHTTP(compiledRequest, nil, extractorResults) e.writeOutputHTTP(compiledRequest, nil, extractorResults)
} }
} }
gologger.Verbosef("Sent HTTP request to %s\n", "http-request", URL)
return nil return nil
} }

View File

@ -2,9 +2,12 @@ package executor
import ( import (
"bufio" "bufio"
"fmt"
"os"
"sync" "sync"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/nuclei/pkg/matchers" "github.com/projectdiscovery/nuclei/pkg/matchers"
"github.com/projectdiscovery/nuclei/pkg/requests" "github.com/projectdiscovery/nuclei/pkg/requests"
"github.com/projectdiscovery/nuclei/pkg/templates" "github.com/projectdiscovery/nuclei/pkg/templates"
@ -14,6 +17,7 @@ import (
// DNSExecutor is a client for performing a DNS request // DNSExecutor is a client for performing a DNS request
// for a template. // for a template.
type DNSExecutor struct { type DNSExecutor struct {
debug bool
dnsClient *retryabledns.Client dnsClient *retryabledns.Client
template *templates.Template template *templates.Template
dnsRequest *requests.DNSRequest dnsRequest *requests.DNSRequest
@ -31,6 +35,7 @@ var DefaultResolvers = []string{
// DNSOptions contains configuration options for the DNS executor. // DNSOptions contains configuration options for the DNS executor.
type DNSOptions struct { type DNSOptions struct {
Debug bool
Template *templates.Template Template *templates.Template
DNSRequest *requests.DNSRequest DNSRequest *requests.DNSRequest
Writer *bufio.Writer Writer *bufio.Writer
@ -42,6 +47,7 @@ func NewDNSExecutor(options *DNSOptions) *DNSExecutor {
dnsClient := retryabledns.New(DefaultResolvers, options.DNSRequest.Retries) dnsClient := retryabledns.New(DefaultResolvers, options.DNSRequest.Retries)
executer := &DNSExecutor{ executer := &DNSExecutor{
debug: options.Debug,
dnsClient: dnsClient, dnsClient: dnsClient,
template: options.Template, template: options.Template,
dnsRequest: options.DNSRequest, dnsRequest: options.DNSRequest,
@ -67,12 +73,24 @@ func (e *DNSExecutor) ExecuteDNS(URL string) error {
return errors.Wrap(err, "could not make dns request") return errors.Wrap(err, "could not make dns request")
} }
if e.debug {
gologger.Infof("Dumped DNS request for %s (%s)\n\n", URL, e.template.ID)
fmt.Fprintf(os.Stderr, "%s\n", compiledRequest.String())
}
// Send the request to the target servers // Send the request to the target servers
resp, err := e.dnsClient.Do(compiledRequest) resp, err := e.dnsClient.Do(compiledRequest)
if err != nil { if err != nil {
return errors.Wrap(err, "could not send dns request") return errors.Wrap(err, "could not send dns request")
} }
gologger.Verbosef("Sent DNS request to %s\n", "dns-request", URL)
if e.debug {
gologger.Infof("Dumped DNS response for %s (%s)\n\n", URL, e.template.ID)
fmt.Fprintf(os.Stderr, "%s\n", resp.String())
}
matcherCondition := e.dnsRequest.GetMatchersCondition() matcherCondition := e.dnsRequest.GetMatchersCondition()
for _, matcher := range e.dnsRequest.Matchers { for _, matcher := range e.dnsRequest.Matchers {
// Check if the matcher matched // Check if the matcher matched