Add word filter / matcher
This commit is contained in:
parent
a1986d176a
commit
fbafd82c62
14
main.go
14
main.go
@ -21,10 +21,12 @@ type cliOptions struct {
|
||||
filterSize string
|
||||
filterReflect string
|
||||
filterRegex string
|
||||
filterWords string
|
||||
matcherStatus string
|
||||
matcherSize string
|
||||
matcherReflect string
|
||||
matcherRegex string
|
||||
matcherWords string
|
||||
headers headerFlags
|
||||
}
|
||||
|
||||
@ -50,12 +52,14 @@ func main() {
|
||||
flag.BoolVar(&conf.TLSSkipVerify, "k", false, "Skip TLS identity verification (insecure)")
|
||||
flag.StringVar(&opts.filterStatus, "fc", "", "Filter HTTP status codes from response")
|
||||
flag.StringVar(&opts.filterSize, "fs", "", "Filter HTTP response size")
|
||||
flag.StringVar(&opts.filterWords, "fw", "", "Filter by amount of words in response")
|
||||
flag.StringVar(&conf.Data, "d", "", "POST data.")
|
||||
flag.BoolVar(&conf.Colors, "c", false, "Colorize output.")
|
||||
//flag.StringVar(&opts.filterRegex, "fr", "", "Filter regex")
|
||||
//flag.StringVar(&opts.filterReflect, "fref", "", "Filter reflected payload")
|
||||
flag.StringVar(&opts.matcherStatus, "mc", "200,204,301,302,307,401", "Match HTTP status codes from respose")
|
||||
flag.StringVar(&opts.matcherSize, "ms", "", "Match HTTP response size")
|
||||
flag.StringVar(&opts.matcherWords, "mw", "", "Match amount of words in response")
|
||||
//flag.StringVar(&opts.matcherRegex, "mr", "", "Match regex")
|
||||
flag.StringVar(&conf.Method, "X", "GET", "HTTP method to use.")
|
||||
flag.BoolVar(&conf.Quiet, "s", false, "Do not print additional information (silent mode)")
|
||||
@ -160,6 +164,11 @@ func prepareFilters(parseOpts *cliOptions, conf *ffuf.Config) error {
|
||||
errlist = multierror.Append(errlist, err)
|
||||
}
|
||||
}
|
||||
if parseOpts.filterWords != "" {
|
||||
if err := addFilter(conf, "word", parseOpts.filterWords); err != nil {
|
||||
errlist = multierror.Append(errlist, err)
|
||||
}
|
||||
}
|
||||
if parseOpts.matcherStatus != "" {
|
||||
if err := addMatcher(conf, "status", parseOpts.matcherStatus); err != nil {
|
||||
errlist = multierror.Append(errlist, err)
|
||||
@ -170,6 +179,11 @@ func prepareFilters(parseOpts *cliOptions, conf *ffuf.Config) error {
|
||||
errlist = multierror.Append(errlist, err)
|
||||
}
|
||||
}
|
||||
if parseOpts.matcherWords != "" {
|
||||
if err := addMatcher(conf, "word", parseOpts.matcherWords); err != nil {
|
||||
errlist = multierror.Append(errlist, err)
|
||||
}
|
||||
}
|
||||
return errlist.ErrorOrNil()
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ type Response struct {
|
||||
Headers map[string][]string
|
||||
Data []byte
|
||||
ContentLength int64
|
||||
ContentWords int64
|
||||
Cancelled bool
|
||||
Request *Request
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package filter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ffuf/ffuf/pkg/ffuf"
|
||||
)
|
||||
|
||||
@ -11,5 +13,8 @@ func NewFilterByName(name string, value string) (ffuf.FilterProvider, error) {
|
||||
if name == "size" {
|
||||
return NewSizeFilter(value)
|
||||
}
|
||||
return nil, nil
|
||||
if name == "word" {
|
||||
return NewWordFilter(value)
|
||||
}
|
||||
return nil, fmt.Errorf("Could not create filter with name %s", name)
|
||||
}
|
||||
|
||||
43
pkg/filter/words.go
Normal file
43
pkg/filter/words.go
Normal file
@ -0,0 +1,43 @@
|
||||
package filter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ffuf/ffuf/pkg/ffuf"
|
||||
)
|
||||
|
||||
type WordFilter struct {
|
||||
Value []int64
|
||||
}
|
||||
|
||||
func NewWordFilter(value string) (ffuf.FilterProvider, error) {
|
||||
var intvals []int64
|
||||
for _, sv := range strings.Split(value, ",") {
|
||||
intval, err := strconv.ParseInt(sv, 10, 0)
|
||||
if err != nil {
|
||||
return &WordFilter{}, fmt.Errorf("Word filter or matcher (-fw / -mw): invalid value: %s", value)
|
||||
}
|
||||
intvals = append(intvals, intval)
|
||||
}
|
||||
return &WordFilter{Value: intvals}, nil
|
||||
}
|
||||
|
||||
func (f *WordFilter) Filter(response *ffuf.Response) (bool, error) {
|
||||
wordsSize := len(strings.Split(string(response.Data), " "))
|
||||
for _, iv := range f.Value {
|
||||
if iv == int64(wordsSize) {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (f *WordFilter) Repr() string {
|
||||
var strval []string
|
||||
for _, iv := range f.Value {
|
||||
strval = append(strval, strconv.Itoa(int(iv)))
|
||||
}
|
||||
return fmt.Sprintf("Response words: %s", strings.Join(strval, ","))
|
||||
}
|
||||
@ -98,7 +98,7 @@ func (s *Stdoutput) resultQuiet(resp ffuf.Response) {
|
||||
}
|
||||
|
||||
func (s *Stdoutput) resultNormal(resp ffuf.Response) {
|
||||
res_str := fmt.Sprintf("%s%-23s [Status: %s, Size: %d]", TERMINAL_CLEAR_LINE, resp.Request.Input, s.colorizeStatus(resp.StatusCode), resp.ContentLength)
|
||||
res_str := fmt.Sprintf("%s%-23s [Status: %s, Size: %d, Words: %d]", TERMINAL_CLEAR_LINE, resp.Request.Input, s.colorizeStatus(resp.StatusCode), resp.ContentLength, resp.ContentWords)
|
||||
fmt.Println(res_str)
|
||||
}
|
||||
|
||||
|
||||
@ -94,5 +94,8 @@ func (r *SimpleRunner) Execute(req *ffuf.Request) (ffuf.Response, error) {
|
||||
resp.Data = respbody
|
||||
}
|
||||
|
||||
wordsSize := len(strings.Split(string(resp.Data), " "))
|
||||
resp.ContentWords = int64(wordsSize)
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user