Add error log support

This commit is contained in:
Alexey Zhuchkov 2021-10-30 12:39:38 +03:00
parent e0afa2cee4
commit 3f1186da2b
4 changed files with 36 additions and 9 deletions

View File

@ -139,6 +139,7 @@ on extensive configurability, massive extensibility and ease of use.`)
flagSet.StringVarP(&options.ProxyURL, "proxy-url", "proxy", "", "URL of the HTTP proxy server"), flagSet.StringVarP(&options.ProxyURL, "proxy-url", "proxy", "", "URL of the HTTP proxy server"),
flagSet.StringVar(&options.ProxySocksURL, "proxy-socks-url", "", "URL of the SOCKS proxy server"), flagSet.StringVar(&options.ProxySocksURL, "proxy-socks-url", "", "URL of the SOCKS proxy server"),
flagSet.StringVarP(&options.TraceLogFile, "trace-log", "tlog", "", "file to write sent requests trace log"), flagSet.StringVarP(&options.TraceLogFile, "trace-log", "tlog", "", "file to write sent requests trace log"),
flagSet.StringVarP(&options.ErrorLogFile, "error-log", "elog", "", "file to write sent requests error log"),
flagSet.BoolVar(&options.Version, "version", false, "show nuclei version"), flagSet.BoolVar(&options.Version, "version", false, "show nuclei version"),
flagSet.BoolVarP(&options.Verbose, "verbose", "v", false, "show verbose output"), flagSet.BoolVarP(&options.Verbose, "verbose", "v", false, "show verbose output"),
flagSet.BoolVar(&options.VerboseVerbose, "vv", false, "display templates loaded for scan"), flagSet.BoolVar(&options.VerboseVerbose, "vv", false, "display templates loaded for scan"),

View File

@ -215,7 +215,7 @@ func New(options *types.Options) (*Runner, error) {
} }
// Create the output file if asked // Create the output file if asked
outputWriter, err := output.NewStandardWriter(!options.NoColor, options.NoMeta, options.NoTimestamp, options.JSON, options.JSONRequests, options.Output, options.TraceLogFile) outputWriter, err := output.NewStandardWriter(!options.NoColor, options.NoMeta, options.NoTimestamp, options.JSON, options.JSONRequests, options.Output, options.TraceLogFile, options.ErrorLogFile)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "could not create output file") return nil, errors.Wrap(err, "could not create output file")
} }

View File

@ -41,6 +41,8 @@ type StandardWriter struct {
outputMutex *sync.Mutex outputMutex *sync.Mutex
traceFile *fileWriter traceFile *fileWriter
traceMutex *sync.Mutex traceMutex *sync.Mutex
errorFile *fileWriter
errorMutex *sync.Mutex
severityColors func(severity.Severity) string severityColors func(severity.Severity) string
} }
@ -97,7 +99,7 @@ type ResultEvent struct {
} }
// NewStandardWriter creates a new output writer based on user configurations // NewStandardWriter creates a new output writer based on user configurations
func NewStandardWriter(colors, noMetadata, noTimestamp, json, jsonReqResp bool, file, traceFile string) (*StandardWriter, error) { func NewStandardWriter(colors, noMetadata, noTimestamp, json, jsonReqResp bool, file, traceFile string, errorFile string) (*StandardWriter, error) {
auroraColorizer := aurora.NewAurora(colors) auroraColorizer := aurora.NewAurora(colors)
var outputFile *fileWriter var outputFile *fileWriter
@ -116,6 +118,14 @@ func NewStandardWriter(colors, noMetadata, noTimestamp, json, jsonReqResp bool,
} }
traceOutput = output traceOutput = output
} }
var errorOutput *fileWriter
if errorFile != "" {
output, err := newFileOutputWriter(errorFile)
if err != nil {
return nil, errors.Wrap(err, "could not create error file")
}
errorOutput = output
}
writer := &StandardWriter{ writer := &StandardWriter{
json: json, json: json,
jsonReqResp: jsonReqResp, jsonReqResp: jsonReqResp,
@ -126,6 +136,8 @@ func NewStandardWriter(colors, noMetadata, noTimestamp, json, jsonReqResp bool,
outputMutex: &sync.Mutex{}, outputMutex: &sync.Mutex{},
traceFile: traceOutput, traceFile: traceOutput,
traceMutex: &sync.Mutex{}, traceMutex: &sync.Mutex{},
errorFile: errorOutput,
errorMutex: &sync.Mutex{},
severityColors: colorizer.New(auroraColorizer), severityColors: colorizer.New(auroraColorizer),
} }
return writer, nil return writer, nil
@ -171,8 +183,8 @@ type JSONTraceRequest struct {
} }
// Request writes a log the requests trace log // Request writes a log the requests trace log
func (w *StandardWriter) Request(templateID, url, requestType string, err error) { func (w *StandardWriter) Request(templateID, url, requestType string, requestErr error) {
if w.traceFile == nil { if w.traceFile == nil && w.errorFile == nil {
return return
} }
request := &JSONTraceRequest{ request := &JSONTraceRequest{
@ -180,8 +192,8 @@ func (w *StandardWriter) Request(templateID, url, requestType string, err error)
URL: url, URL: url,
Type: requestType, Type: requestType,
} }
if err != nil { if requestErr != nil {
request.Error = err.Error() request.Error = requestErr.Error()
} else { } else {
request.Error = "none" request.Error = "none"
} }
@ -190,11 +202,20 @@ func (w *StandardWriter) Request(templateID, url, requestType string, err error)
if err != nil { if err != nil {
return return
} }
if w.traceFile != nil {
w.traceMutex.Lock() w.traceMutex.Lock()
_ = w.traceFile.Write(data) _ = w.traceFile.Write(data)
w.traceMutex.Unlock() w.traceMutex.Unlock()
} }
if requestErr != nil && w.errorFile != nil {
w.errorMutex.Lock()
_ = w.errorFile.Write(data)
w.errorMutex.Unlock()
}
}
// Colorizer returns the colorizer instance for writer // Colorizer returns the colorizer instance for writer
func (w *StandardWriter) Colorizer() aurora.Aurora { func (w *StandardWriter) Colorizer() aurora.Aurora {
return w.aurora return w.aurora
@ -208,4 +229,7 @@ func (w *StandardWriter) Close() {
if w.traceFile != nil { if w.traceFile != nil {
w.traceFile.Close() w.traceFile.Close()
} }
if w.errorFile != nil {
w.errorFile.Close()
}
} }

View File

@ -57,6 +57,8 @@ type Options struct {
TemplatesDirectory string TemplatesDirectory string
// TraceLogFile specifies a file to write with the trace of all requests // TraceLogFile specifies a file to write with the trace of all requests
TraceLogFile string TraceLogFile string
// ErrorLogFile specifies a file to write with the errors of all requests
ErrorLogFile string
// ReportingDB is the db for report storage as well as deduplication // ReportingDB is the db for report storage as well as deduplication
ReportingDB string ReportingDB string
// ReportingConfig is the config file for nuclei reporting module // ReportingConfig is the config file for nuclei reporting module