diff --git a/CHANGELOG.md b/CHANGELOG.md index 99b39bc..035ae36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Changed behaviour of `-maxtime`, can now be used for entire process. - A new flag `-ignore-body` so ffuf does not fetch the response content. Default value=false. - Added the wordlists to the header information. + - Added support to output "all" formats (specify the path/filename sans file extension and ffuf will add the appropriate suffix for the filetype) - Changed - Added tls renegotiation flag to fix #193 in http.Client diff --git a/main.go b/main.go index a894990..ab01a92 100644 --- a/main.go +++ b/main.go @@ -101,7 +101,7 @@ func main() { flag.StringVar(&opts.requestProto, "request-proto", "https", "Protocol to use along with raw request") flag.StringVar(&conf.Method, "X", "GET", "HTTP method to use") flag.StringVar(&conf.OutputFile, "o", "", "Write output to file") - flag.StringVar(&opts.outputFormat, "of", "json", "Output file format. Available formats: json, ejson, html, md, csv, ecsv") + flag.StringVar(&opts.outputFormat, "of", "json", "Output file format. Available formats: json, ejson, html, md, csv, ecsv (or, 'all' for all formats)") flag.StringVar(&conf.OutputDirectory, "od", "", "Directory path to store matched results to.") flag.BoolVar(&conf.IgnoreBody, "ignore-body", false, "Do not fetch the response content.") flag.BoolVar(&conf.Quiet, "s", false, "Do not print additional information (silent mode)") @@ -430,7 +430,7 @@ func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error { //Check the output file format option if conf.OutputFile != "" { //No need to check / error out if output file isn't defined - outputFormats := []string{"json", "ejson", "html", "md", "csv", "ecsv"} + outputFormats := []string{"all", "json", "ejson", "html", "md", "csv", "ecsv"} found := false for _, f := range outputFormats { if f == parseOpts.outputFormat { diff --git a/pkg/output/stdout.go b/pkg/output/stdout.go index b7730e1..87c3af6 100644 --- a/pkg/output/stdout.go +++ b/pkg/output/stdout.go @@ -83,7 +83,16 @@ func (s *Stdoutput) Banner() error { // Output file info if len(s.config.OutputFile) > 0 { - printOption([]byte("Output file"), []byte(s.config.OutputFile)) + + // Use filename as specified by user + OutputFile := s.config.OutputFile + + if s.config.OutputFormat == "all" { + // Actually... append all extensions + OutputFile += ".{json,ejson,html,md,csv,ecsv}" + } + + printOption([]byte("Output file"), []byte(OutputFile)) printOption([]byte("File format"), []byte(s.config.OutputFormat)) } @@ -196,10 +205,59 @@ func (s *Stdoutput) Warning(warnstring string) { } } +func (s *Stdoutput) writeToAll(config *ffuf.Config, res []Result) error { + var err error + var BaseFilename string = s.config.OutputFile + + // Go through each type of write, adding + // the suffix to each output file. + + s.config.OutputFile = BaseFilename + ".json" + err = writeJSON(s.config, s.Results) + if err != nil { + s.Error(fmt.Sprintf("%s", err)) + } + + s.config.OutputFile = BaseFilename + ".ejson" + err = writeEJSON(s.config, s.Results) + if err != nil { + s.Error(fmt.Sprintf("%s", err)) + } + + s.config.OutputFile = BaseFilename + ".html" + err = writeHTML(s.config, s.Results) + if err != nil { + s.Error(fmt.Sprintf("%s", err)) + } + + s.config.OutputFile = BaseFilename + ".md" + err = writeMarkdown(s.config, s.Results) + if err != nil { + s.Error(fmt.Sprintf("%s", err)) + } + + s.config.OutputFile = BaseFilename + ".csv" + err = writeCSV(s.config, s.Results, false) + if err != nil { + s.Error(fmt.Sprintf("%s", err)) + } + + s.config.OutputFile = BaseFilename + ".ecsv" + err = writeCSV(s.config, s.Results, true) + if err != nil { + s.Error(fmt.Sprintf("%s", err)) + } + + return nil + +} + func (s *Stdoutput) Finalize() error { var err error if s.config.OutputFile != "" { - if s.config.OutputFormat == "json" { + if s.config.OutputFormat == "all" { + err = s.writeToAll(s.config, s.Results) + } else if s.config.OutputFormat == "json" { err = writeJSON(s.config, s.Results) } else if s.config.OutputFormat == "ejson" { err = writeEJSON(s.config, s.Results)