Get rid of the last external dependency
This commit is contained in:
parent
e82f762825
commit
c9217e39f5
@ -112,6 +112,8 @@ eg. `ffuf -u https://example.org/FUZZ -w /path/to/wordlist`
|
|||||||
or
|
or
|
||||||
- If you have go compiler installed: `go get github.com/ffuf/ffuf`
|
- If you have go compiler installed: `go get github.com/ffuf/ffuf`
|
||||||
|
|
||||||
|
The only dependency of ffuf is Go 1.11. No dependencies outside of Go standard library are needed.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
- Tests!
|
- Tests!
|
||||||
- Option to follow redirects
|
- Option to follow redirects
|
||||||
|
|||||||
40
main.go
40
main.go
@ -12,8 +12,6 @@ import (
|
|||||||
"github.com/ffuf/ffuf/pkg/input"
|
"github.com/ffuf/ffuf/pkg/input"
|
||||||
"github.com/ffuf/ffuf/pkg/output"
|
"github.com/ffuf/ffuf/pkg/output"
|
||||||
"github.com/ffuf/ffuf/pkg/runner"
|
"github.com/ffuf/ffuf/pkg/runner"
|
||||||
|
|
||||||
"github.com/hashicorp/go-multierror"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type cliOptions struct {
|
type cliOptions struct {
|
||||||
@ -84,14 +82,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func prepareJob(conf *ffuf.Config) (*ffuf.Job, error) {
|
func prepareJob(conf *ffuf.Config) (*ffuf.Job, error) {
|
||||||
var errlist *multierror.Error
|
errs := ffuf.NewMultierror()
|
||||||
// TODO: implement error handling for runnerprovider and outputprovider
|
// TODO: implement error handling for runnerprovider and outputprovider
|
||||||
// We only have http runner right now
|
// We only have http runner right now
|
||||||
runprovider := runner.NewRunnerByName("http", conf)
|
runprovider := runner.NewRunnerByName("http", conf)
|
||||||
// We only have wordlist inputprovider right now
|
// We only have wordlist inputprovider right now
|
||||||
inputprovider, err := input.NewInputProviderByName("wordlist", conf)
|
inputprovider, err := input.NewInputProviderByName("wordlist", conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errlist = multierror.Append(errlist, fmt.Errorf("%s", err))
|
errs.Add(fmt.Errorf("%s", err))
|
||||||
}
|
}
|
||||||
// We only have stdout outputprovider right now
|
// We only have stdout outputprovider right now
|
||||||
outprovider := output.NewOutputProviderByName("stdout", conf)
|
outprovider := output.NewOutputProviderByName("stdout", conf)
|
||||||
@ -100,18 +98,18 @@ func prepareJob(conf *ffuf.Config) (*ffuf.Job, error) {
|
|||||||
Runner: runprovider,
|
Runner: runprovider,
|
||||||
Output: outprovider,
|
Output: outprovider,
|
||||||
Input: inputprovider,
|
Input: inputprovider,
|
||||||
}, errlist.ErrorOrNil()
|
}, errs.ErrorOrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error {
|
func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error {
|
||||||
//TODO: refactor in a proper flag library that can handle things like required flags
|
//TODO: refactor in a proper flag library that can handle things like required flags
|
||||||
var errlist *multierror.Error
|
errs := ffuf.NewMultierror()
|
||||||
foundkeyword := false
|
foundkeyword := false
|
||||||
if len(conf.Url) == 0 {
|
if len(conf.Url) == 0 {
|
||||||
errlist = multierror.Append(errlist, fmt.Errorf("-u flag is required"))
|
errs.Add(fmt.Errorf("-u flag is required"))
|
||||||
}
|
}
|
||||||
if len(conf.Wordlist) == 0 {
|
if len(conf.Wordlist) == 0 {
|
||||||
errlist = multierror.Append(errlist, fmt.Errorf("-w flag is required"))
|
errs.Add(fmt.Errorf("-w flag is required"))
|
||||||
}
|
}
|
||||||
//Prepare headers
|
//Prepare headers
|
||||||
for _, v := range parseOpts.headers {
|
for _, v := range parseOpts.headers {
|
||||||
@ -131,7 +129,7 @@ func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error {
|
|||||||
conf.StaticHeaders[strings.TrimSpace(hs[0])] = strings.TrimSpace(hs[1])
|
conf.StaticHeaders[strings.TrimSpace(hs[0])] = strings.TrimSpace(hs[1])
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
errlist = multierror.Append(errlist, fmt.Errorf("Header defined by -H needs to have a value. \":\" should be used as a separator"))
|
errs.Add(fmt.Errorf("Header defined by -H needs to have a value. \":\" should be used as a separator"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Search for keyword from URL and POST data too
|
//Search for keyword from URL and POST data too
|
||||||
@ -143,54 +141,54 @@ func prepareConfig(parseOpts *cliOptions, conf *ffuf.Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !foundkeyword {
|
if !foundkeyword {
|
||||||
errlist = multierror.Append(errlist, fmt.Errorf("No FUZZ keyword(s) found in headers, URL or POST data, nothing to do"))
|
errs.Add(fmt.Errorf("No FUZZ keyword(s) found in headers, URL or POST data, nothing to do"))
|
||||||
}
|
}
|
||||||
return errlist.ErrorOrNil()
|
return errs.ErrorOrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareFilters(parseOpts *cliOptions, conf *ffuf.Config) error {
|
func prepareFilters(parseOpts *cliOptions, conf *ffuf.Config) error {
|
||||||
var errlist *multierror.Error
|
errs := ffuf.NewMultierror()
|
||||||
if parseOpts.filterStatus != "" {
|
if parseOpts.filterStatus != "" {
|
||||||
if err := addFilter(conf, "status", parseOpts.filterStatus); err != nil {
|
if err := addFilter(conf, "status", parseOpts.filterStatus); err != nil {
|
||||||
errlist = multierror.Append(errlist, err)
|
errs.Add(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if parseOpts.filterSize != "" {
|
if parseOpts.filterSize != "" {
|
||||||
if err := addFilter(conf, "size", parseOpts.filterSize); err != nil {
|
if err := addFilter(conf, "size", parseOpts.filterSize); err != nil {
|
||||||
errlist = multierror.Append(errlist, err)
|
errs.Add(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if parseOpts.filterRegexp != "" {
|
if parseOpts.filterRegexp != "" {
|
||||||
if err := addFilter(conf, "regexp", parseOpts.filterRegexp); err != nil {
|
if err := addFilter(conf, "regexp", parseOpts.filterRegexp); err != nil {
|
||||||
errlist = multierror.Append(errlist, err)
|
errs.Add(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if parseOpts.filterWords != "" {
|
if parseOpts.filterWords != "" {
|
||||||
if err := addFilter(conf, "word", parseOpts.filterWords); err != nil {
|
if err := addFilter(conf, "word", parseOpts.filterWords); err != nil {
|
||||||
errlist = multierror.Append(errlist, err)
|
errs.Add(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if parseOpts.matcherStatus != "" {
|
if parseOpts.matcherStatus != "" {
|
||||||
if err := addMatcher(conf, "status", parseOpts.matcherStatus); err != nil {
|
if err := addMatcher(conf, "status", parseOpts.matcherStatus); err != nil {
|
||||||
errlist = multierror.Append(errlist, err)
|
errs.Add(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if parseOpts.matcherSize != "" {
|
if parseOpts.matcherSize != "" {
|
||||||
if err := addMatcher(conf, "size", parseOpts.matcherSize); err != nil {
|
if err := addMatcher(conf, "size", parseOpts.matcherSize); err != nil {
|
||||||
errlist = multierror.Append(errlist, err)
|
errs.Add(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if parseOpts.matcherRegexp != "" {
|
if parseOpts.matcherRegexp != "" {
|
||||||
if err := addMatcher(conf, "regexp", parseOpts.matcherRegexp); err != nil {
|
if err := addMatcher(conf, "regexp", parseOpts.matcherRegexp); err != nil {
|
||||||
errlist = multierror.Append(errlist, err)
|
errs.Add(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if parseOpts.matcherWords != "" {
|
if parseOpts.matcherWords != "" {
|
||||||
if err := addMatcher(conf, "word", parseOpts.matcherWords); err != nil {
|
if err := addMatcher(conf, "word", parseOpts.matcherWords); err != nil {
|
||||||
errlist = multierror.Append(errlist, err)
|
errs.Add(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errlist.ErrorOrNil()
|
return errs.ErrorOrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
func addFilter(conf *ffuf.Config, name string, option string) error {
|
func addFilter(conf *ffuf.Config, name string, option string) error {
|
||||||
|
|||||||
30
pkg/ffuf/multierror.go
Normal file
30
pkg/ffuf/multierror.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package ffuf
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Multierror struct {
|
||||||
|
errors []error
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewMultierror returns a new Multierror
|
||||||
|
func NewMultierror() Multierror {
|
||||||
|
return Multierror{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Multierror) Add(err error) {
|
||||||
|
m.errors = append(m.errors, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Multierror) ErrorOrNil() error {
|
||||||
|
var errString string
|
||||||
|
if len(m.errors) > 0 {
|
||||||
|
errString += fmt.Sprintf("%d errors occured.\n", len(m.errors))
|
||||||
|
for _, e := range m.errors {
|
||||||
|
errString += fmt.Sprintf("\t* %s\n", e)
|
||||||
|
}
|
||||||
|
return fmt.Errorf("%s", errString)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user