diff --git a/README.md b/README.md index 072fab48..594e9f77 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ This will display help for the tool. Here are all the switches it supports. | -t | Templates input file/files to check across hosts | nuclei -t nuclei-templates/cves/ | | -nC | Don't Use colors in output | nuclei -nC | | -json | Prints and write output in json format | nuclei -json | +| -json-requests | Write requests/responses for matches in JSON output | nuclei -json -json-requests | | -o | File to save output result (optional) | nuclei -o output.txt | | -pbar | Enable the progress bar (optional) | nuclei -pbar | | -silent | Show only found results in output | nuclei -silent | diff --git a/v2/internal/runner/runner.go b/v2/internal/runner/runner.go index 79f26eb7..7c994605 100644 --- a/v2/internal/runner/runner.go +++ b/v2/internal/runner/runner.go @@ -466,14 +466,15 @@ func (r *Runner) processTemplateWithList(p progress.IProgress, template *templat switch value := request.(type) { case *requests.DNSRequest: dnsExecuter = executer.NewDNSExecuter(&executer.DNSOptions{ - Debug: r.options.Debug, - Template: template, - DNSRequest: value, - Writer: writer, - JSON: r.options.JSON, - ColoredOutput: !r.options.NoColor, - Colorizer: r.colorizer, - Decolorizer: r.decolorizer, + Debug: r.options.Debug, + Template: template, + DNSRequest: value, + Writer: writer, + JSON: r.options.JSON, + JSONRequests: r.options.JSONRequests, + ColoredOutput: !r.options.NoColor, + Colorizer: r.colorizer, + Decolorizer: r.decolorizer, }) case *requests.BulkHTTPRequest: httpExecuter, err = executer.NewHTTPExecuter(&executer.HTTPOptions{ @@ -609,18 +610,18 @@ func (r *Runner) ProcessWorkflow(p progress.IProgress, workflow *workflows.Workf ProxySocksURL: r.options.ProxySocksURL, CustomHeaders: r.options.CustomHeaders, CookieJar: jar, - ColoredOutput: !r.options.NoColor, - Colorizer: r.colorizer, - Decolorizer: r.decolorizer, + ColoredOutput: !r.options.NoColor, + Colorizer: r.colorizer, + Decolorizer: r.decolorizer, } } else if len(t.RequestsDNS) > 0 { template.DNSOptions = &executer.DNSOptions{ - Debug: r.options.Debug, - Template: t, - Writer: writer, - ColoredOutput: !r.options.NoColor, - Colorizer: r.colorizer, - Decolorizer: r.decolorizer, + Debug: r.options.Debug, + Template: t, + Writer: writer, + ColoredOutput: !r.options.NoColor, + Colorizer: r.colorizer, + Decolorizer: r.decolorizer, } } if template.DNSOptions != nil || template.HTTPOptions != nil { diff --git a/v2/pkg/executer/executer_dns.go b/v2/pkg/executer/executer_dns.go index 9d6e6976..02fb1f55 100644 --- a/v2/pkg/executer/executer_dns.go +++ b/v2/pkg/executer/executer_dns.go @@ -22,6 +22,7 @@ import ( type DNSExecuter struct { debug bool jsonOutput bool + jsonRequest bool Results bool dnsClient *retryabledns.Client template *templates.Template @@ -44,11 +45,12 @@ var DefaultResolvers = []string{ // DNSOptions contains configuration options for the DNS executer. type DNSOptions struct { - Debug bool - JSON bool - Template *templates.Template - DNSRequest *requests.DNSRequest - Writer *bufio.Writer + Debug bool + JSON bool + JSONRequests bool + Template *templates.Template + DNSRequest *requests.DNSRequest + Writer *bufio.Writer ColoredOutput bool Colorizer aurora.Aurora @@ -63,6 +65,7 @@ func NewDNSExecuter(options *DNSOptions) *DNSExecuter { executer := &DNSExecuter{ debug: options.Debug, jsonOutput: options.JSON, + jsonRequest: options.JSONRequests, dnsClient: dnsClient, template: options.Template, dnsRequest: options.DNSRequest, @@ -127,7 +130,7 @@ func (e *DNSExecuter) ExecuteDNS(p progress.IProgress, URL string) (result Resul // 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 { - e.writeOutputDNS(domain, matcher, nil) + e.writeOutputDNS(domain, compiledRequest, resp, matcher, nil) result.GotResults = true } } @@ -147,7 +150,7 @@ func (e *DNSExecuter) ExecuteDNS(p progress.IProgress, URL string) (result Resul // 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 { - e.writeOutputDNS(domain, nil, extractorResults) + e.writeOutputDNS(domain, compiledRequest, resp, nil, extractorResults) result.GotResults = true } diff --git a/v2/pkg/executer/output_dns.go b/v2/pkg/executer/output_dns.go index 07932593..14ef3f94 100644 --- a/v2/pkg/executer/output_dns.go +++ b/v2/pkg/executer/output_dns.go @@ -1,6 +1,7 @@ package executer import ( + "github.com/miekg/dns" "strings" jsoniter "github.com/json-iterator/go" @@ -9,7 +10,7 @@ import ( ) // writeOutputDNS writes dns output to streams -func (e *DNSExecuter) writeOutputDNS(domain string, matcher *matchers.Matcher, extractorResults []string) { +func (e *DNSExecuter) writeOutputDNS(domain string, req *dns.Msg, resp *dns.Msg, matcher *matchers.Matcher, extractorResults []string) { if e.jsonOutput { output := jsonOutput{ Template: e.template.ID, @@ -25,6 +26,10 @@ func (e *DNSExecuter) writeOutputDNS(domain string, matcher *matchers.Matcher, e if len(extractorResults) > 0 { output.ExtractedResults = extractorResults } + if e.jsonRequest { + output.Request = req.String() + output.Response = resp.String() + } data, err := jsoniter.Marshal(output) if err != nil { gologger.Warningf("Could not marshal json output: %s\n", err)