diff --git a/main.go b/main.go index 551ac2e..8247c56 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( ) type cliOptions struct { + extensions string delay string filterStatus string filterSize string @@ -49,6 +50,7 @@ func main() { defer cancel() conf := ffuf.NewConfig(ctx) opts := cliOptions{} + flag.StringVar(&opts.extensions, "e", "", "extensions to bruteforce separated by a comma. `\"wordlist must contain %EXT%\"`") flag.Var(&opts.headers, "H", "Header `\"Name: Value\"`, separated by colon. Multiple -H flags are accepted.") flag.StringVar(&conf.Url, "u", "", "Target URL") flag.StringVar(&conf.Wordlist, "w", "", "Wordlist path") @@ -134,6 +136,12 @@ func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error { if len(conf.Wordlist) == 0 { errs.Add(fmt.Errorf("-w flag is required")) } + // prepare extensions + if parseOpts.extensions != "" { + extensions := strings.Split(parseOpts.extensions, ",") + conf.Extensions = extensions + } + //Prepare headers for _, v := range parseOpts.headers { hs := strings.SplitN(v, ":", 2) diff --git a/pkg/ffuf/config.go b/pkg/ffuf/config.go index 71f18f8..f9061c6 100644 --- a/pkg/ffuf/config.go +++ b/pkg/ffuf/config.go @@ -18,6 +18,7 @@ type optRange struct { type Config struct { StaticHeaders map[string]string FuzzHeaders map[string]string + Extensions []string Method string Url string TLSVerify bool @@ -57,5 +58,6 @@ func NewConfig(ctx context.Context) Config { conf.ProxyURL = http.ProxyFromEnvironment conf.Filters = make([]FilterProvider, 0) conf.Delay = optRange{0, 0, false, false} + conf.Extensions = make([]string, 0) return conf } diff --git a/pkg/input/wordlist.go b/pkg/input/wordlist.go index 86fcbae..631bd71 100644 --- a/pkg/input/wordlist.go +++ b/pkg/input/wordlist.go @@ -3,6 +3,7 @@ package input import ( "bufio" "os" + "strings" "github.com/ffuf/ffuf/pkg/ffuf" ) @@ -71,7 +72,15 @@ func (w *WordlistInput) readFile(path string) error { var data [][]byte reader := bufio.NewScanner(file) for reader.Scan() { - data = append(data, []byte(reader.Text())) + if strings.Index(reader.Text(), "%EXT%") != -1 { + extensions := w.config.Extensions + for _, ext := range extensions { + contnt := strings.Replace(reader.Text(), "%EXT%", ext, -1) + data = append(data, []byte(contnt)) + } + } else { + data = append(data, []byte(reader.Text())) + } } w.data = data return reader.Err()