diff --git a/README.md b/README.md index 316f6ba1..2773792f 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ All funds that are donated to this project will be donated to charity. A full lo ## 3.7 -- TODO +- More user friendly error messages ## 3.6 diff --git a/cli/cmd/dir.go b/cli/cmd/dir.go index 0ea9834b..17209da4 100644 --- a/cli/cmd/dir.go +++ b/cli/cmd/dir.go @@ -32,7 +32,7 @@ func runDir(cmd *cobra.Command, args []string) error { return fmt.Errorf("%w. To continue please exclude the status code or the length", wErr) } log.Debugf("%#v", err) - return fmt.Errorf("error on running gobuster: %w", err) + return fmt.Errorf("error on running gobuster on %s: %w", pluginopts.URL, err) } return nil } diff --git a/cli/cmd/dns.go b/cli/cmd/dns.go index c37fb0c1..f6d118ad 100644 --- a/cli/cmd/dns.go +++ b/cli/cmd/dns.go @@ -34,7 +34,7 @@ func runDNS(cmd *cobra.Command, args []string) error { return fmt.Errorf("%w. To force processing of Wildcard DNS, specify the '--wildcard' switch", wErr) } log.Debugf("%#v", err) - return fmt.Errorf("error on running gobuster: %w", err) + return fmt.Errorf("error on running gobuster on %s: %w", pluginopts.Domain, err) } return nil } diff --git a/cli/cmd/fuzz.go b/cli/cmd/fuzz.go index b763b7d5..dc4ea422 100644 --- a/cli/cmd/fuzz.go +++ b/cli/cmd/fuzz.go @@ -37,7 +37,7 @@ func runFuzz(cmd *cobra.Command, args []string) error { return fmt.Errorf("%w. To continue please exclude the status code or the length", wErr) } log.Debugf("%#v", err) - return fmt.Errorf("error on running gobuster: %w", err) + return fmt.Errorf("error on running gobuster on %s: %w", pluginopts.URL, err) } return nil } diff --git a/cli/cmd/tftp.go b/cli/cmd/tftp.go index 7180abe8..69c627e8 100644 --- a/cli/cmd/tftp.go +++ b/cli/cmd/tftp.go @@ -29,7 +29,7 @@ func runTFTP(cmd *cobra.Command, args []string) error { log := libgobuster.NewLogger(globalopts.Debug) if err := cli.Gobuster(mainContext, globalopts, plugin, log); err != nil { log.Debugf("%#v", err) - return fmt.Errorf("error on running gobuster: %w", err) + return fmt.Errorf("error on running gobuster on %s: %w", pluginopts.Server, err) } return nil } diff --git a/cli/cmd/vhost.go b/cli/cmd/vhost.go index c707750b..8b7c7d55 100644 --- a/cli/cmd/vhost.go +++ b/cli/cmd/vhost.go @@ -27,7 +27,7 @@ func runVhost(cmd *cobra.Command, args []string) error { log := libgobuster.NewLogger(globalopts.Debug) if err := cli.Gobuster(mainContext, globalopts, plugin, log); err != nil { log.Debugf("%#v", err) - return fmt.Errorf("error on running gobuster: %w", err) + return fmt.Errorf("error on running gobuster on %s: %w", pluginopts.URL, err) } return nil } diff --git a/gobusterdir/gobusterdir.go b/gobusterdir/gobusterdir.go index 7bf6fdab..71482ab7 100644 --- a/gobusterdir/gobusterdir.go +++ b/gobusterdir/gobusterdir.go @@ -7,9 +7,10 @@ import ( "errors" "fmt" "io" - "net" "net/http" + "os" "strings" + "syscall" "text/tabwriter" "unicode/utf8" @@ -102,7 +103,11 @@ func (d *GobusterDir) PreRun(ctx context.Context, progress *libgobuster.Progress _, _, _, _, err := d.http.Request(ctx, d.options.URL, libgobuster.RequestOptions{}) if err != nil { if errors.Is(err, io.EOF) { - return fmt.Errorf("server closed connection without sending any data back when connecting to %s. Maybe you are connecting via https to on http port or vice versa?", d.options.URL) + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused } return fmt.Errorf("unable to connect to %s: %w", d.options.URL, err) } @@ -115,6 +120,13 @@ func (d *GobusterDir) PreRun(ctx context.Context, progress *libgobuster.Progress wildcardResp, wildcardLength, _, _, err := d.http.Request(ctx, url, libgobuster.RequestOptions{}) if err != nil { + if errors.Is(err, io.EOF) { + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused + } return err } @@ -207,7 +219,7 @@ func (d *GobusterDir) ProcessWord(ctx context.Context, word string, progress *li if err != nil { // check if it's a timeout and if we should try again and try again // otherwise the timeout error is raised - if netErr, ok := err.(net.Error); ok && netErr.Timeout() && i != tries { + if os.IsTimeout(err) && i != tries { continue } else if strings.Contains(err.Error(), "invalid control character in URL") { // put error in error chan so it's printed out and ignore it @@ -215,6 +227,13 @@ func (d *GobusterDir) ProcessWord(ctx context.Context, word string, progress *li progress.ErrorChan <- err continue } else { + if errors.Is(err, io.EOF) { + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused + } return err } } diff --git a/gobusterfuzz/gobusterfuzz.go b/gobusterfuzz/gobusterfuzz.go index 5dd39316..3b033a50 100644 --- a/gobusterfuzz/gobusterfuzz.go +++ b/gobusterfuzz/gobusterfuzz.go @@ -4,9 +4,12 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" - "net" + "io" + "os" "strings" + "syscall" "text/tabwriter" "github.com/OJ/gobuster/v3/libgobuster" @@ -128,7 +131,7 @@ func (d *GobusterFuzz) ProcessWord(ctx context.Context, word string, progress *l if err != nil { // check if it's a timeout and if we should try again and try again // otherwise the timeout error is raised - if netErr, ok := err.(net.Error); ok && netErr.Timeout() && i != tries { + if os.IsTimeout(err) && i != tries { continue } else if strings.Contains(err.Error(), "invalid control character in URL") { // put error in error chan so it's printed out and ignore it @@ -136,6 +139,13 @@ func (d *GobusterFuzz) ProcessWord(ctx context.Context, word string, progress *l progress.ErrorChan <- err continue } else { + if errors.Is(err, io.EOF) { + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused + } return err } } diff --git a/gobustergcs/gobustersgcs.go b/gobustergcs/gobustersgcs.go index 50b0f687..2ec47ecb 100644 --- a/gobustergcs/gobustersgcs.go +++ b/gobustergcs/gobustersgcs.go @@ -5,11 +5,14 @@ import ( "bytes" "context" "encoding/json" + "errors" "fmt" - "net" + "io" "net/http" + "os" "regexp" "strings" + "syscall" "text/tabwriter" "github.com/OJ/gobuster/v3/libgobuster" @@ -98,7 +101,7 @@ func (s *GobusterGCS) ProcessWord(ctx context.Context, word string, progress *li if err != nil { // check if it's a timeout and if we should try again and try again // otherwise the timeout error is raised - if netErr, ok := err.(net.Error); ok && netErr.Timeout() && i != tries { + if os.IsTimeout(err) && i != tries { continue } else if strings.Contains(err.Error(), "invalid control character in URL") { // put error in error chan so it's printed out and ignore it @@ -106,6 +109,13 @@ func (s *GobusterGCS) ProcessWord(ctx context.Context, word string, progress *li progress.ErrorChan <- err continue } else { + if errors.Is(err, io.EOF) { + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused + } return err } } diff --git a/gobusters3/gobusters3.go b/gobusters3/gobusters3.go index 5a183528..d7aebabb 100644 --- a/gobusters3/gobusters3.go +++ b/gobusters3/gobusters3.go @@ -5,11 +5,14 @@ import ( "bytes" "context" "encoding/xml" + "errors" "fmt" - "net" + "io" "net/http" + "os" "regexp" "strings" + "syscall" "text/tabwriter" "github.com/OJ/gobuster/v3/libgobuster" @@ -97,7 +100,7 @@ func (s *GobusterS3) ProcessWord(ctx context.Context, word string, progress *lib if err != nil { // check if it's a timeout and if we should try again and try again // otherwise the timeout error is raised - if netErr, ok := err.(net.Error); ok && netErr.Timeout() && i != tries { + if os.IsTimeout(err) && i != tries { continue } else if strings.Contains(err.Error(), "invalid control character in URL") { // put error in error chan so it's printed out and ignore it @@ -105,6 +108,13 @@ func (s *GobusterS3) ProcessWord(ctx context.Context, word string, progress *lib progress.ErrorChan <- err continue } else { + if errors.Is(err, io.EOF) { + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused + } return err } } diff --git a/gobustervhost/gobustervhost.go b/gobustervhost/gobustervhost.go index de413f5d..a283a868 100644 --- a/gobustervhost/gobustervhost.go +++ b/gobustervhost/gobustervhost.go @@ -7,10 +7,11 @@ import ( "errors" "fmt" "io" - "net" "net/http" "net/url" + "os" "strings" + "syscall" "text/tabwriter" "github.com/OJ/gobuster/v3/libgobuster" @@ -97,7 +98,11 @@ func (v *GobusterVhost) PreRun(ctx context.Context, progress *libgobuster.Progre _, _, _, body, err := v.http.Request(ctx, v.options.URL, libgobuster.RequestOptions{ReturnBody: true}) if err != nil { if errors.Is(err, io.EOF) { - return fmt.Errorf("server closed connection without sending any data back when connecting to %s. Maybe you are connecting via https to on http port or vice versa?", v.options.URL) + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused } return fmt.Errorf("unable to connect to %s: %w", v.options.URL, err) } @@ -108,7 +113,11 @@ func (v *GobusterVhost) PreRun(ctx context.Context, progress *libgobuster.Progre _, _, _, body, err = v.http.Request(ctx, v.options.URL, libgobuster.RequestOptions{Host: subdomain, ReturnBody: true}) if err != nil { if errors.Is(err, io.EOF) { - return fmt.Errorf("server closed connection without sending any data back when connecting to %s. Maybe you are connecting via https to on http port or vice versa?", v.options.URL) + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused } return fmt.Errorf("unable to connect to %s: %w", v.options.URL, err) } @@ -142,7 +151,7 @@ func (v *GobusterVhost) ProcessWord(ctx context.Context, word string, progress * if err != nil { // check if it's a timeout and if we should try again and try again // otherwise the timeout error is raised - if netErr, ok := err.(net.Error); ok && netErr.Timeout() && i != tries { + if os.IsTimeout(err) && i != tries { continue } else if strings.Contains(err.Error(), "invalid control character in URL") { // put error in error chan so it's printed out and ignore it @@ -150,6 +159,13 @@ func (v *GobusterVhost) ProcessWord(ctx context.Context, word string, progress * progress.ErrorChan <- err continue } else { + if errors.Is(err, io.EOF) { + return libgobuster.ErrorEOF + } else if os.IsTimeout(err) { + return libgobuster.ErrorTimeout + } else if errors.Is(err, syscall.ECONNREFUSED) { + return libgobuster.ErrorConnectionRefused + } return err } } diff --git a/libgobuster/errors.go b/libgobuster/errors.go new file mode 100644 index 00000000..e68cfc7e --- /dev/null +++ b/libgobuster/errors.go @@ -0,0 +1,9 @@ +package libgobuster + +import "errors" + +var ( + ErrorTimeout = errors.New("timeout occured during the request") + ErrorEOF = errors.New("server closed connection without sending any data back. Maybe you are connecting via https to on http port or vice versa?") + ErrorConnectionRefused = errors.New("connection refused") +)