Empty filter (#330)

* add support to filter empty result files.

* update readme

* add contributors.

* add changelog

* Update ffufrc.example
This commit is contained in:
Bp0lr 2020-11-23 18:39:06 +00:00 committed by GitHub
parent c6a6293499
commit bc5e61ecc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 32 additions and 1 deletions

View File

@ -6,6 +6,7 @@
- Ffuf now reads a default configuration file `$HOME/.ffufrc` upon startup. Options set in this file - Ffuf now reads a default configuration file `$HOME/.ffufrc` upon startup. Options set in this file
are overwritten by the ones provided on CLI. are overwritten by the ones provided on CLI.
- Change banner logging to stderr instead of stdout. - Change banner logging to stderr instead of stdout.
- New CLI flag `-or` to avoid creating result files if we didn't get any.
- Changed - Changed
- Pre-flight errors are now displayed also after the usage text to prevent the need to scroll through backlog. - Pre-flight errors are now displayed also after the usage text to prevent the need to scroll through backlog.

View File

@ -1,5 +1,6 @@
# Contributors # Contributors
* [AverageSecurityGuy](https://github.com/averagesecurityguy) * [AverageSecurityGuy](https://github.com/averagesecurityguy)
* [bp0](https://github.com/bp0lr)
* [bjhulst](https://github.com/bjhulst) * [bjhulst](https://github.com/bjhulst)
* [bsysop](https://twitter.com/bsysop) * [bsysop](https://twitter.com/bsysop)
* [ccsplit](https://github.com/ccsplit) * [ccsplit](https://github.com/ccsplit)

View File

@ -195,6 +195,7 @@ OUTPUT OPTIONS:
-o Write output to file -o Write output to file
-od Directory path to store matched results to. -od Directory path to store matched results to.
-of Output file format. Available formats: json, ejson, html, md, csv, ecsv (or, 'all' for all formats) (default: json) -of Output file format. Available formats: json, ejson, html, md, csv, ecsv (or, 'all' for all formats) (default: json)
-or Don't create the output file if we don't have results
EXAMPLE USAGE: EXAMPLE USAGE:
Fuzz file paths from wordlist.txt, match all responses but filter out those with content-size 42. Fuzz file paths from wordlist.txt, match all responses but filter out those with content-size 42.

View File

@ -60,6 +60,7 @@
outputdirectory = "/tmp/rawoutputdir" outputdirectory = "/tmp/rawoutputdir"
outputfile = "output.json" outputfile = "output.json"
outputformat = "json" outputformat = "json"
outputcreateemptyfile = false
[filter] [filter]
lines = "" lines = ""

View File

@ -96,7 +96,7 @@ func Usage() {
Description: "Options for output. Output file formats, file names and debug file locations.", Description: "Options for output. Output file formats, file names and debug file locations.",
Flags: make([]UsageFlag, 0), Flags: make([]UsageFlag, 0),
Hidden: false, Hidden: false,
ExpectedFlags: []string{"debug-log", "o", "of", "od"}, ExpectedFlags: []string{"debug-log", "o", "of", "od", "or"},
} }
sections := []UsageSection{u_http, u_general, u_compat, u_matcher, u_filter, u_input, u_output} sections := []UsageSection{u_http, u_general, u_compat, u_matcher, u_filter, u_input, u_output}

View File

@ -58,6 +58,7 @@ func ParseFlags(opts *ffuf.ConfigOptions) *ffuf.ConfigOptions {
flag.BoolVar(&ignored, "compressed", true, "Dummy flag for copy as curl functionality (ignored)") flag.BoolVar(&ignored, "compressed", true, "Dummy flag for copy as curl functionality (ignored)")
flag.BoolVar(&ignored, "i", true, "Dummy flag for copy as curl functionality (ignored)") flag.BoolVar(&ignored, "i", true, "Dummy flag for copy as curl functionality (ignored)")
flag.BoolVar(&ignored, "k", false, "Dummy flag for backwards compatibility") flag.BoolVar(&ignored, "k", false, "Dummy flag for backwards compatibility")
flag.BoolVar(&opts.Output.OutputCreateEmptyFile, "or", opts.Output.OutputCreateEmptyFile, "Don't create the output file if we don't have results")
flag.BoolVar(&opts.General.AutoCalibration, "ac", opts.General.AutoCalibration, "Automatically calibrate filtering options") flag.BoolVar(&opts.General.AutoCalibration, "ac", opts.General.AutoCalibration, "Automatically calibrate filtering options")
flag.BoolVar(&opts.General.Colors, "c", opts.General.Colors, "Colorize output.") flag.BoolVar(&opts.General.Colors, "c", opts.General.Colors, "Colorize output.")
flag.BoolVar(&opts.General.Quiet, "s", opts.General.Quiet, "Do not print additional information (silent mode)") flag.BoolVar(&opts.General.Quiet, "s", opts.General.Quiet, "Do not print additional information (silent mode)")

View File

@ -32,6 +32,7 @@ type Config struct {
OutputDirectory string `json:"outputdirectory"` OutputDirectory string `json:"outputdirectory"`
OutputFile string `json:"outputfile"` OutputFile string `json:"outputfile"`
OutputFormat string `json:"outputformat"` OutputFormat string `json:"outputformat"`
OutputCreateEmptyFile bool `json:"OutputCreateEmptyFile"`
ProgressFrequency int `json:"-"` ProgressFrequency int `json:"-"`
ProxyURL string `json:"proxyurl"` ProxyURL string `json:"proxyurl"`
Quiet bool `json:"quiet"` Quiet bool `json:"quiet"`

View File

@ -75,6 +75,7 @@ type OutputOptions struct {
OutputDirectory string OutputDirectory string
OutputFile string OutputFile string
OutputFormat string OutputFormat string
OutputCreateEmptyFile bool
} }
type FilterOptions struct { type FilterOptions struct {
@ -140,6 +141,7 @@ func NewConfigOptions() *ConfigOptions {
c.Output.OutputDirectory = "" c.Output.OutputDirectory = ""
c.Output.OutputFile = "" c.Output.OutputFile = ""
c.Output.OutputFormat = "json" c.Output.OutputFormat = "json"
c.Output.OutputCreateEmptyFile = false
return c return c
} }
@ -374,6 +376,7 @@ func ConfigFromOptions(parseOpts *ConfigOptions, ctx context.Context, cancel con
conf.InputMode = parseOpts.Input.InputMode conf.InputMode = parseOpts.Input.InputMode
conf.OutputFile = parseOpts.Output.OutputFile conf.OutputFile = parseOpts.Output.OutputFile
conf.OutputDirectory = parseOpts.Output.OutputDirectory conf.OutputDirectory = parseOpts.Output.OutputDirectory
conf.OutputCreateEmptyFile = parseOpts.Output.OutputCreateEmptyFile
conf.IgnoreBody = parseOpts.HTTP.IgnoreBody conf.IgnoreBody = parseOpts.HTTP.IgnoreBody
conf.Quiet = parseOpts.General.Quiet conf.Quiet = parseOpts.General.Quiet
conf.StopOn403 = parseOpts.General.StopOn403 conf.StopOn403 = parseOpts.General.StopOn403

View File

@ -12,6 +12,11 @@ import (
var staticheaders = []string{"url", "redirectlocation", "position", "status_code", "content_length", "content_words", "content_lines", "resultfile"} var staticheaders = []string{"url", "redirectlocation", "position", "status_code", "content_length", "content_words", "content_lines", "resultfile"}
func writeCSV(config *ffuf.Config, res []Result, encode bool) error { func writeCSV(config *ffuf.Config, res []Result, encode bool) error {
if(config.OutputCreateEmptyFile && (len(res) == 0)){
return nil
}
header := make([]string, 0) header := make([]string, 0)
f, err := os.Create(config.OutputFile) f, err := os.Create(config.OutputFile)
if err != nil { if err != nil {

View File

@ -176,6 +176,10 @@ func colorizeResults(results []Result) []Result {
func writeHTML(config *ffuf.Config, results []Result) error { func writeHTML(config *ffuf.Config, results []Result) error {
if(config.OutputCreateEmptyFile && (len(results) == 0)){
return nil
}
results = colorizeResults(results) results = colorizeResults(results)
ti := time.Now() ti := time.Now()

View File

@ -36,6 +36,11 @@ type jsonFileOutput struct {
} }
func writeEJSON(config *ffuf.Config, res []Result) error { func writeEJSON(config *ffuf.Config, res []Result) error {
if(config.OutputCreateEmptyFile && (len(res) == 0)){
return nil
}
t := time.Now() t := time.Now()
outJSON := ejsonFileOutput{ outJSON := ejsonFileOutput{
CommandLine: config.CommandLine, CommandLine: config.CommandLine,

View File

@ -22,6 +22,10 @@ const (
func writeMarkdown(config *ffuf.Config, res []Result) error { func writeMarkdown(config *ffuf.Config, res []Result) error {
if(config.OutputCreateEmptyFile && (len(res) == 0)){
return nil
}
ti := time.Now() ti := time.Now()
keywords := make([]string, 0) keywords := make([]string, 0)

View File

@ -210,6 +210,10 @@ func (s *Stdoutput) writeToAll(config *ffuf.Config, res []Result) error {
// Go through each type of write, adding // Go through each type of write, adding
// the suffix to each output file. // the suffix to each output file.
if(config.OutputCreateEmptyFile && (len(res) == 0)){
return nil
}
s.config.OutputFile = BaseFilename + ".json" s.config.OutputFile = BaseFilename + ".json"
err = writeJSON(s.config, s.Results) err = writeJSON(s.config, s.Results)
if err != nil { if err != nil {