mirror of https://github.com/daffainfo/nuclei.git
json-request option for request/response output in JSON matches
parent
94ba9acbbf
commit
b3fb45d381
|
@ -29,6 +29,7 @@ type Options struct {
|
|||
UpdateTemplates bool // UpdateTemplates updates the templates installed at startup
|
||||
TemplatesDirectory string // TemplatesDirectory is the directory to use for storing templates
|
||||
JSON bool // JSON writes json output to files
|
||||
JSONRequests bool // write requests/responses for matches in JSON output
|
||||
|
||||
Stdin bool // Stdin specifies whether stdin input was given to the process
|
||||
}
|
||||
|
@ -66,6 +67,7 @@ func ParseOptions() *Options {
|
|||
flag.BoolVar(&options.UpdateTemplates, "update-templates", false, "Update Templates updates the installed templates (optional)")
|
||||
flag.StringVar(&options.TemplatesDirectory, "update-directory", "", "Directory to use for storing nuclei-templates")
|
||||
flag.BoolVar(&options.JSON, "json", false, "Write json output to files")
|
||||
flag.BoolVar(&options.JSONRequests, "json-requests", false, "Write requests/responses for matches in JSON output")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
|
|
|
@ -288,6 +288,7 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i
|
|||
ProxySocksURL: r.options.ProxySocksURL,
|
||||
CustomHeaders: r.options.CustomHeaders,
|
||||
JSON: r.options.JSON,
|
||||
JSONRequests: r.options.JSONRequests,
|
||||
CookieReuse: value.CookieReuse,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ type HTTPExecuter struct {
|
|||
debug bool
|
||||
Results bool
|
||||
jsonOutput bool
|
||||
jsonRequest bool
|
||||
httpClient *retryablehttp.Client
|
||||
template *templates.Template
|
||||
bulkHttpRequest *requests.BulkHTTPRequest
|
||||
|
@ -50,6 +51,7 @@ type HTTPOptions struct {
|
|||
ProxySocksURL string
|
||||
Debug bool
|
||||
JSON bool
|
||||
JSONRequests bool
|
||||
CustomHeaders requests.CustomHeaders
|
||||
CookieReuse bool
|
||||
CookieJar *cookiejar.Jar
|
||||
|
@ -84,6 +86,7 @@ func NewHTTPExecuter(options *HTTPOptions) (*HTTPExecuter, error) {
|
|||
executer := &HTTPExecuter{
|
||||
debug: options.Debug,
|
||||
jsonOutput: options.JSON,
|
||||
jsonRequest: options.JSONRequests,
|
||||
httpClient: client,
|
||||
template: options.Template,
|
||||
bulkHttpRequest: options.BulkHttpRequest,
|
||||
|
@ -187,7 +190,7 @@ func (e *HTTPExecuter) handleHTTP(URL string, request *requests.HttpRequest, dyn
|
|||
result.Matches[matcher.Name] = nil
|
||||
// probably redundant but ensures we snapshot current payload values when matchers are valid
|
||||
result.Meta = request.Meta
|
||||
e.writeOutputHTTP(request, matcher, nil)
|
||||
e.writeOutputHTTP(request, resp, body, matcher, nil)
|
||||
e.Results = true
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +214,7 @@ func (e *HTTPExecuter) handleHTTP(URL string, request *requests.HttpRequest, dyn
|
|||
// Write a final string of output if matcher type is
|
||||
// AND or if we have extractors for the mechanism too.
|
||||
if len(e.bulkHttpRequest.Extractors) > 0 || matcherCondition == matchers.ANDCondition {
|
||||
e.writeOutputHTTP(request, nil, extractorResults)
|
||||
e.writeOutputHTTP(request, resp, body, nil, extractorResults)
|
||||
e.Results = true
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@ type jsonOutput struct {
|
|||
Severity string `json:"severity"`
|
||||
Author string `json:"author"`
|
||||
Description string `json:"description"`
|
||||
Request string `json:"request,omitempty"`
|
||||
Response string `json:"response,omitempty"`
|
||||
}
|
||||
|
||||
// unsafeToString converts byte slice to string with zero allocations
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package executer
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"strings"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
@ -10,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
// writeOutputHTTP writes http output to streams
|
||||
func (e *HTTPExecuter) writeOutputHTTP(req *requests.HttpRequest, matcher *matchers.Matcher, extractorResults []string) {
|
||||
func (e *HTTPExecuter) writeOutputHTTP(req *requests.HttpRequest, resp *http.Response, body string, matcher *matchers.Matcher, extractorResults []string) {
|
||||
URL := req.Request.URL.String()
|
||||
|
||||
if e.jsonOutput {
|
||||
|
@ -28,6 +30,21 @@ func (e *HTTPExecuter) writeOutputHTTP(req *requests.HttpRequest, matcher *match
|
|||
if len(extractorResults) > 0 {
|
||||
output.ExtractedResults = extractorResults
|
||||
}
|
||||
if e.jsonRequest {
|
||||
dumpedRequest, err := httputil.DumpRequest(req.Request.Request, true)
|
||||
if err != nil {
|
||||
gologger.Warningf("could not dump request: %s\n", err)
|
||||
} else {
|
||||
output.Request = string(dumpedRequest)
|
||||
}
|
||||
dumpedResponse, err := httputil.DumpResponse(resp, false)
|
||||
if err != nil {
|
||||
gologger.Warningf("could not dump response: %s\n", err)
|
||||
} else {
|
||||
output.Response = string(dumpedResponse) + body
|
||||
}
|
||||
|
||||
}
|
||||
data, err := jsoniter.Marshal(output)
|
||||
if err != nil {
|
||||
gologger.Warningf("Could not marshal json output: %s\n", err)
|
||||
|
|
Loading…
Reference in New Issue