Add word filter / matcher

This commit is contained in:
Joona Hoikkala 2018-11-12 19:06:49 +02:00
parent a1986d176a
commit fbafd82c62
No known key found for this signature in database
GPG Key ID: D5AA86BBF9B29A5C
6 changed files with 68 additions and 2 deletions

14
main.go
View File

@ -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()
}

View File

@ -10,6 +10,7 @@ type Response struct {
Headers map[string][]string
Data []byte
ContentLength int64
ContentWords int64
Cancelled bool
Request *Request
}

View File

@ -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
View 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, ","))
}

View File

@ -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)
}

View File

@ -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
}