Add output to CSV file (#12)
This commit is contained in:
parent
ab09685804
commit
9934cfdfc3
@ -99,7 +99,7 @@ To define the test case for ffuf, use the keyword `FUZZ` anywhere in the URL (`-
|
|||||||
-o string
|
-o string
|
||||||
Write output to file
|
Write output to file
|
||||||
-of string
|
-of string
|
||||||
Output file format. Available formats: json (default "json")
|
Output file format. Available formats: json, csv, ecsv (default "json")
|
||||||
-p delay
|
-p delay
|
||||||
Seconds of delay between requests, or a range of random delay. For example "0.1" or "0.1-2.0"
|
Seconds of delay between requests, or a range of random delay. For example "0.1" or "0.1-2.0"
|
||||||
-s Do not print additional information (silent mode)
|
-s Do not print additional information (silent mode)
|
||||||
|
|||||||
4
main.go
4
main.go
@ -67,7 +67,7 @@ func main() {
|
|||||||
flag.StringVar(&opts.proxyURL, "x", "", "HTTP Proxy URL")
|
flag.StringVar(&opts.proxyURL, "x", "", "HTTP Proxy URL")
|
||||||
flag.StringVar(&conf.Method, "X", "GET", "HTTP method to use")
|
flag.StringVar(&conf.Method, "X", "GET", "HTTP method to use")
|
||||||
flag.StringVar(&conf.OutputFile, "o", "", "Write output to file")
|
flag.StringVar(&conf.OutputFile, "o", "", "Write output to file")
|
||||||
flag.StringVar(&opts.outputFormat, "of", "json", "Output file format. Available formats: json")
|
flag.StringVar(&opts.outputFormat, "of", "json", "Output file format. Available formats: json, csv, ecsv")
|
||||||
flag.BoolVar(&conf.Quiet, "s", false, "Do not print additional information (silent mode)")
|
flag.BoolVar(&conf.Quiet, "s", false, "Do not print additional information (silent mode)")
|
||||||
flag.BoolVar(&conf.StopOn403, "sf", false, "Stop when > 90% of responses return 403 Forbidden")
|
flag.BoolVar(&conf.StopOn403, "sf", false, "Stop when > 90% of responses return 403 Forbidden")
|
||||||
flag.IntVar(&conf.Threads, "t", 40, "Number of concurrent threads.")
|
flag.IntVar(&conf.Threads, "t", 40, "Number of concurrent threads.")
|
||||||
@ -186,7 +186,7 @@ func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error {
|
|||||||
//Check the output file format option
|
//Check the output file format option
|
||||||
if conf.OutputFile != "" {
|
if conf.OutputFile != "" {
|
||||||
//No need to check / error out if output file isn't defined
|
//No need to check / error out if output file isn't defined
|
||||||
outputFormats := []string{"json"}
|
outputFormats := []string{"json", "csv", "ecsv"}
|
||||||
found := false
|
found := false
|
||||||
for _, f := range outputFormats {
|
for _, f := range outputFormats {
|
||||||
if f == parseOpts.outputFormat {
|
if f == parseOpts.outputFormat {
|
||||||
|
|||||||
51
pkg/output/file_csv.go
Normal file
51
pkg/output/file_csv.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package output
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/csv"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/ffuf/ffuf/pkg/ffuf"
|
||||||
|
)
|
||||||
|
|
||||||
|
var header = []string{"input", "status_code", "content_length", "content_words"}
|
||||||
|
|
||||||
|
func writeCSV(config *ffuf.Config, res []Result, encode bool) error {
|
||||||
|
f, err := os.Create(config.OutputFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
w := csv.NewWriter(f)
|
||||||
|
defer w.Flush()
|
||||||
|
|
||||||
|
if err := w.Write(header); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, r := range res {
|
||||||
|
if encode {
|
||||||
|
r.Input = base64encode(r.Input)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := w.Write(toCSV(r))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func base64encode(in string) string {
|
||||||
|
return base64.StdEncoding.EncodeToString([]byte(in))
|
||||||
|
}
|
||||||
|
|
||||||
|
func toCSV(r Result) []string {
|
||||||
|
return []string{
|
||||||
|
r.Input,
|
||||||
|
strconv.FormatInt(r.StatusCode, 10),
|
||||||
|
strconv.FormatInt(r.ContentLength, 10),
|
||||||
|
strconv.FormatInt(r.ContentWords, 10),
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -90,6 +90,10 @@ func (s *Stdoutput) Finalize() error {
|
|||||||
if s.config.OutputFile != "" {
|
if s.config.OutputFile != "" {
|
||||||
if s.config.OutputFormat == "json" {
|
if s.config.OutputFormat == "json" {
|
||||||
err = writeJSON(s.config, s.Results)
|
err = writeJSON(s.config, s.Results)
|
||||||
|
} else if s.config.OutputFormat == "csv" {
|
||||||
|
err = writeCSV(s.config, s.Results, false)
|
||||||
|
} else if s.config.OutputFormat == "ecsv" {
|
||||||
|
err = writeCSV(s.config, s.Results, true)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Error(fmt.Sprintf("%s", err))
|
s.Error(fmt.Sprintf("%s", err))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user