From 4d8131c8d8afb0c11003926b51e9ef9e181ca65b Mon Sep 17 00:00:00 2001 From: Manuel Bua Date: Sun, 26 Jul 2020 16:36:01 +0200 Subject: [PATCH] Add support for DNS requests --- v2/internal/runner/runner.go | 5 +++-- v2/pkg/executer/executer_dns.go | 15 ++++++++++++++- v2/pkg/executer/executer_http.go | 2 +- v2/pkg/requests/dns-request.go | 5 +++++ v2/pkg/templates/templates.go | 10 +++++++++- v2/pkg/workflows/var.go | 2 +- 6 files changed, 33 insertions(+), 6 deletions(-) diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index 09b485da8..5533d4421 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -290,7 +290,8 @@ func (r *Runner) RunEnumeration() { case *templates.Template: barIndex++ template := t.(*templates.Template) - totalRequests += template.GetHTTPRequestsCount() + totalRequests += template.GetHTTPRequestCount() + totalRequests += template.GetDNSRequestCount() parsedTemplates = append(parsedTemplates, match) default: gologger.Errorf("Could not parse file '%s': %s\n", match, err) @@ -426,7 +427,7 @@ func (r *Runner) processTemplateWithList(p *progress.Progress, template *templat globalresult.Or(result.GotResults) } if dnsExecuter != nil { - result = dnsExecuter.ExecuteDNS(URL) + result = dnsExecuter.ExecuteDNS(p, URL) globalresult.Or(result.GotResults) } if result.Error != nil { diff --git a/v2/pkg/executer/executer_dns.go b/v2/pkg/executer/executer_dns.go index 4c9a34749..1542df9d7 100644 --- a/v2/pkg/executer/executer_dns.go +++ b/v2/pkg/executer/executer_dns.go @@ -3,6 +3,7 @@ package executer import ( "bufio" "fmt" + "github.com/projectdiscovery/nuclei/v2/internal/progress" "os" "sync" @@ -62,7 +63,7 @@ func NewDNSExecuter(options *DNSOptions) *DNSExecuter { } // ExecuteDNS executes the DNS request on a URL -func (e *DNSExecuter) ExecuteDNS(URL string) (result Result) { +func (e *DNSExecuter) ExecuteDNS(p *progress.Progress, URL string) (result Result) { // Parse the URL and return domain if URL. var domain string if isURL(URL) { @@ -75,26 +76,34 @@ func (e *DNSExecuter) ExecuteDNS(URL string) (result Result) { compiledRequest, err := e.dnsRequest.MakeDNSRequest(domain) if err != nil { result.Error = errors.Wrap(err, "could not make dns request") + p.Drop(1) return } if e.debug { + p.StartStdCapture() gologger.Infof("Dumped DNS request for %s (%s)\n\n", URL, e.template.ID) fmt.Fprintf(os.Stderr, "%s\n", compiledRequest.String()) + p.StopStdCapture() } // Send the request to the target servers resp, err := e.dnsClient.Do(compiledRequest) if err != nil { result.Error = errors.Wrap(err, "could not send dns request") + p.Drop(1) return } + p.Update() + gologger.Verbosef("Sent DNS request to %s\n", "dns-request", URL) if e.debug { + p.StartStdCapture() gologger.Infof("Dumped DNS response for %s (%s)\n\n", URL, e.template.ID) fmt.Fprintf(os.Stderr, "%s\n", resp.String()) + p.StopStdCapture() } matcherCondition := e.dnsRequest.GetMatchersCondition() @@ -109,7 +118,9 @@ func (e *DNSExecuter) ExecuteDNS(URL string) (result Result) { // If the matcher has matched, and its an OR // write the first output then move to next matcher. if matcherCondition == matchers.ORCondition && len(e.dnsRequest.Extractors) == 0 { + p.StartStdCapture() e.writeOutputDNS(domain, matcher, nil) + p.StopStdCapture() result.GotResults = true } } @@ -129,7 +140,9 @@ func (e *DNSExecuter) ExecuteDNS(URL string) (result Result) { // Write a final string of output if matcher type is // AND or if we have extractors for the mechanism too. if len(e.dnsRequest.Extractors) > 0 || matcherCondition == matchers.ANDCondition { + p.StartStdCapture() e.writeOutputDNS(domain, nil, extractorResults) + p.StopStdCapture() } return diff --git a/v2/pkg/executer/executer_http.go b/v2/pkg/executer/executer_http.go index 792dabf4b..c39d8a8bd 100644 --- a/v2/pkg/executer/executer_http.go +++ b/v2/pkg/executer/executer_http.go @@ -111,7 +111,7 @@ func (e *HTTPExecuter) ExecuteHTTP(p *progress.Progress, URL string) (result Res return } - remaining := e.template.GetHTTPRequestsCount() + remaining := e.template.GetHTTPRequestCount() e.bulkHttpRequest.CreateGenerator(URL) for e.bulkHttpRequest.Next(URL) && !result.Done { diff --git a/v2/pkg/requests/dns-request.go b/v2/pkg/requests/dns-request.go index ba695c2d8..1cb1b3fae 100644 --- a/v2/pkg/requests/dns-request.go +++ b/v2/pkg/requests/dns-request.go @@ -42,6 +42,11 @@ func (r *DNSRequest) SetMatchersCondition(condition matchers.ConditionType) { r.matchersCondition = condition } +// Returns the total number of requests the YAML rule will perform +func (r *DNSRequest) GetRequestCount() int64 { + return 1 +} + // MakeDNSRequest creates a *dns.Request from a request template func (r *DNSRequest) MakeDNSRequest(domain string) (*dns.Msg, error) { domain = dns.Fqdn(domain) diff --git a/v2/pkg/templates/templates.go b/v2/pkg/templates/templates.go index 73efd990f..6842f359b 100644 --- a/v2/pkg/templates/templates.go +++ b/v2/pkg/templates/templates.go @@ -28,10 +28,18 @@ type Info struct { Description string `yaml:"description,omitempty"` } -func (t* Template) GetHTTPRequestsCount() int64 { +func (t* Template) GetHTTPRequestCount() int64 { var count int64 = 0 for _, request := range t.BulkRequestsHTTP { count += request.GetRequestCount() } return count +} + +func (t *Template) GetDNSRequestCount() int64 { + var count int64 = 0 + for _, request := range t.RequestsDNS { + count += request.GetRequestCount() + } + return count } \ No newline at end of file diff --git a/v2/pkg/workflows/var.go b/v2/pkg/workflows/var.go index 7a28b642d..1638be1cf 100644 --- a/v2/pkg/workflows/var.go +++ b/v2/pkg/workflows/var.go @@ -86,7 +86,7 @@ func (n *NucleiVar) Call(args ...tengo.Object) (ret tengo.Object, err error) { for _, request := range template.DNSOptions.Template.RequestsDNS { template.DNSOptions.DNSRequest = request dnsExecuter := executer.NewDNSExecuter(template.DNSOptions) - result := dnsExecuter.ExecuteDNS(n.URL) + result := dnsExecuter.ExecuteDNS(p,n.URL) if result.Error != nil { gologger.Warningf("Could not compile request for template '%s': %s\n", template.HTTPOptions.Template.ID, result.Error) continue