1
1
mirror of https://github.com/OJ/gobuster.git synced 2024-11-15 08:45:21 +01:00

more debugging and fix #460

This commit is contained in:
firefart 2023-11-19 06:38:10 +01:00
parent 2d84a5b8e3
commit 08f6652cd8
19 changed files with 68 additions and 32 deletions

@ -6,3 +6,4 @@
.vscode/
gobuster
.git/
mitm*

2
.gitignore vendored

@ -20,3 +20,5 @@
.vscode/
gobuster
mitm*

@ -104,12 +104,13 @@ func run(c *cli.Context) error {
return err
}
plugin, err := gobusterdir.New(&globalOpts, pluginOpts)
log := libgobuster.NewLogger(globalOpts.Debug)
plugin, err := gobusterdir.New(&globalOpts, pluginOpts, log)
if err != nil {
return fmt.Errorf("error on creating gobusterdir: %w", err)
}
log := libgobuster.NewLogger(globalOpts.Debug)
if err := internalcli.Gobuster(c.Context, &globalOpts, plugin, log); err != nil {
var wErr *gobusterdir.ErrWildcard
if errors.As(err, &wErr) {

@ -74,7 +74,7 @@ func BenchmarkDirMode(b *testing.B) {
for x := 0; x < b.N; x++ {
os.Stdout = devnull
os.Stderr = devnull
plugin, err := gobusterdir.New(&globalopts, pluginopts)
plugin, err := gobusterdir.New(&globalopts, pluginopts, log)
if err != nil {
b.Fatalf("error on creating gobusterdir: %v", err)
}

@ -67,12 +67,13 @@ func run(c *cli.Context) error {
return fmt.Errorf("please provide the %s keyword", gobusterfuzz.FuzzKeyword)
}
plugin, err := gobusterfuzz.New(&globalOpts, pluginOpts)
log := libgobuster.NewLogger(globalOpts.Debug)
plugin, err := gobusterfuzz.New(&globalOpts, pluginOpts, log)
if err != nil {
return fmt.Errorf("error on creating gobusterfuzz: %w", err)
}
log := libgobuster.NewLogger(globalOpts.Debug)
if err := internalcli.Gobuster(c.Context, &globalOpts, plugin, log); err != nil {
log.Debugf("%#v", err)
return fmt.Errorf("error on running gobuster on %s: %w", pluginOpts.URL, err)

@ -47,12 +47,13 @@ func run(c *cli.Context) error {
return err
}
plugin, err := gobustergcs.New(&globalOpts, pluginOpts)
log := libgobuster.NewLogger(globalOpts.Debug)
plugin, err := gobustergcs.New(&globalOpts, pluginOpts, log)
if err != nil {
return fmt.Errorf("error on creating gobustergcs: %w", err)
}
log := libgobuster.NewLogger(globalOpts.Debug)
if err := internalcli.Gobuster(c.Context, &globalOpts, plugin, log); err != nil {
log.Debugf("%#v", err)
return fmt.Errorf("error on running gobuster: %w", err)

@ -127,7 +127,7 @@ func writeToFile(f *os.File, output string) error {
}
// Gobuster is the main entry point for the CLI
func Gobuster(ctx context.Context, opts *libgobuster.Options, plugin libgobuster.GobusterPlugin, log libgobuster.Logger) error {
func Gobuster(ctx context.Context, opts *libgobuster.Options, plugin libgobuster.GobusterPlugin, log *libgobuster.Logger) error {
// Sanity checks
if opts == nil {
return fmt.Errorf("please provide valid options")

@ -47,12 +47,13 @@ func run(c *cli.Context) error {
return err
}
plugin, err := gobusters3.New(&globalOpts, pluginOpts)
log := libgobuster.NewLogger(globalOpts.Debug)
plugin, err := gobusters3.New(&globalOpts, pluginOpts, log)
if err != nil {
return fmt.Errorf("error on creating gobusters3: %w", err)
}
log := libgobuster.NewLogger(globalOpts.Debug)
if err := internalcli.Gobuster(c.Context, &globalOpts, plugin, log); err != nil {
log.Debugf("%#v", err)
return fmt.Errorf("error on running gobuster: %w", err)

@ -64,12 +64,13 @@ func run(c *cli.Context) error {
return err
}
plugin, err := gobustervhost.New(&globalOpts, pluginOpts)
log := libgobuster.NewLogger(globalOpts.Debug)
plugin, err := gobustervhost.New(&globalOpts, pluginOpts, log)
if err != nil {
return fmt.Errorf("error on creating gobustervhost: %w", err)
}
log := libgobuster.NewLogger(globalOpts.Debug)
if err := internalcli.Gobuster(c.Context, &globalOpts, plugin, log); err != nil {
log.Debugf("%#v", err)
return fmt.Errorf("error on running gobuster on %s: %w", pluginOpts.URL, err)

@ -61,7 +61,7 @@ func BenchmarkVhostMode(b *testing.B) {
for x := 0; x < b.N; x++ {
os.Stdout = devnull
os.Stderr = devnull
plugin, err := gobustervhost.New(&globalopts, pluginopts)
plugin, err := gobustervhost.New(&globalopts, pluginopts, log)
if err != nil {
b.Fatalf("error on creating gobusterdir: %v", err)
}

@ -51,7 +51,7 @@ type GobusterDir struct {
}
// New creates a new initialized GobusterDir
func New(globalopts *libgobuster.Options, opts *OptionsDir) (*GobusterDir, error) {
func New(globalopts *libgobuster.Options, opts *OptionsDir, logger *libgobuster.Logger) (*GobusterDir, error) {
if globalopts == nil {
return nil, fmt.Errorf("please provide valid global options")
}
@ -86,7 +86,7 @@ func New(globalopts *libgobuster.Options, opts *OptionsDir) (*GobusterDir, error
Method: opts.Method,
}
h, err := libgobuster.NewHTTPClient(&httpOpts)
h, err := libgobuster.NewHTTPClient(&httpOpts, globalopts.Debug, logger)
if err != nil {
return nil, err
}

@ -37,7 +37,7 @@ type GobusterFuzz struct {
}
// New creates a new initialized GobusterFuzz
func New(globalopts *libgobuster.Options, opts *OptionsFuzz) (*GobusterFuzz, error) {
func New(globalopts *libgobuster.Options, opts *OptionsFuzz, logger *libgobuster.Logger) (*GobusterFuzz, error) {
if globalopts == nil {
return nil, fmt.Errorf("please provide valid global options")
}
@ -72,7 +72,7 @@ func New(globalopts *libgobuster.Options, opts *OptionsFuzz) (*GobusterFuzz, err
Method: opts.Method,
}
h, err := libgobuster.NewHTTPClient(&httpOpts)
h, err := libgobuster.NewHTTPClient(&httpOpts, globalopts.Debug, logger)
if err != nil {
return nil, err
}
@ -99,6 +99,12 @@ func (d *GobusterFuzz) ProcessWord(ctx context.Context, word string, progress *l
if len(d.options.Headers) > 0 {
requestOptions.ModifiedHeaders = make([]libgobuster.HTTPHeader, len(d.options.Headers))
for i := range d.options.Headers {
// Host header can't be set via Headers, needs to be a separate field
if d.options.Headers[i].Name == "Host" {
requestOptions.Host = strings.ReplaceAll(d.options.Headers[i].Value, FuzzKeyword, word)
continue
}
requestOptions.ModifiedHeaders[i] = libgobuster.HTTPHeader{
Name: strings.ReplaceAll(d.options.Headers[i].Name, FuzzKeyword, word),
Value: strings.ReplaceAll(d.options.Headers[i].Value, FuzzKeyword, word),

@ -27,7 +27,7 @@ type GobusterGCS struct {
}
// New creates a new initialized GobusterGCS
func New(globalopts *libgobuster.Options, opts *OptionsGCS) (*GobusterGCS, error) {
func New(globalopts *libgobuster.Options, opts *OptionsGCS, logger *libgobuster.Logger) (*GobusterGCS, error) {
if globalopts == nil {
return nil, fmt.Errorf("please provide valid global options")
}
@ -57,7 +57,7 @@ func New(globalopts *libgobuster.Options, opts *OptionsGCS) (*GobusterGCS, error
FollowRedirect: true,
}
h, err := libgobuster.NewHTTPClient(&httpOpts)
h, err := libgobuster.NewHTTPClient(&httpOpts, globalopts.Debug, logger)
if err != nil {
return nil, err
}

@ -27,7 +27,7 @@ type GobusterS3 struct {
}
// New creates a new initialized GobusterS3
func New(globalopts *libgobuster.Options, opts *OptionsS3) (*GobusterS3, error) {
func New(globalopts *libgobuster.Options, opts *OptionsS3, logger *libgobuster.Logger) (*GobusterS3, error) {
if globalopts == nil {
return nil, fmt.Errorf("please provide valid global options")
}
@ -57,7 +57,7 @@ func New(globalopts *libgobuster.Options, opts *OptionsS3) (*GobusterS3, error)
FollowRedirect: true,
}
h, err := libgobuster.NewHTTPClient(&httpOpts)
h, err := libgobuster.NewHTTPClient(&httpOpts, globalopts.Debug, logger)
if err != nil {
return nil, err
}

@ -31,7 +31,7 @@ type GobusterVhost struct {
}
// New creates a new initialized GobusterDir
func New(globalopts *libgobuster.Options, opts *OptionsVhost) (*GobusterVhost, error) {
func New(globalopts *libgobuster.Options, opts *OptionsVhost, logger *libgobuster.Logger) (*GobusterVhost, error) {
if globalopts == nil {
return nil, fmt.Errorf("please provide valid global options")
}
@ -66,7 +66,7 @@ func New(globalopts *libgobuster.Options, opts *OptionsVhost) (*GobusterVhost, e
Method: opts.Method,
}
h, err := libgobuster.NewHTTPClient(&httpOpts)
h, err := libgobuster.NewHTTPClient(&httpOpts, globalopts.Debug, logger)
if err != nil {
return nil, err
}

@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"net/http/httputil"
"net/url"
"strings"
)
@ -29,6 +30,8 @@ type HTTPClient struct {
cookies string
method string
host string
debug bool
logger *Logger
}
// RequestOptions is used to pass options to a single individual request
@ -42,7 +45,7 @@ type RequestOptions struct {
}
// NewHTTPClient returns a new HTTPClient
func NewHTTPClient(opt *HTTPOptions) (*HTTPClient, error) {
func NewHTTPClient(opt *HTTPOptions, debug bool, logger *Logger) (*HTTPClient, error) {
var proxyURLFunc func(*http.Request) (*url.URL, error)
var client HTTPClient
proxyURLFunc = http.ProxyFromEnvironment
@ -104,6 +107,8 @@ func NewHTTPClient(opt *HTTPOptions) (*HTTPClient, error) {
break
}
}
client.debug = debug
client.logger = logger
return &client, nil
}
@ -171,6 +176,11 @@ func (client *HTTPClient) makeRequest(ctx context.Context, fullURL string, opts
// currently only relevant on fuzzing
if len(opts.ModifiedHeaders) > 0 {
for _, h := range opts.ModifiedHeaders {
// empty headers are not valid
if h.Name == "" {
continue
}
if client.noCanonicalizeHeaders {
// https://stackoverflow.com/questions/26351716/how-to-keep-key-case-sensitive-in-request-header-using-golang
req.Header[h.Name] = []string{h.Value}
@ -195,6 +205,14 @@ func (client *HTTPClient) makeRequest(ctx context.Context, fullURL string, opts
req.SetBasicAuth(client.username, client.password)
}
if client.debug {
dump, err := httputil.DumpRequestOut(req, false)
if err != nil {
return nil, err
}
client.logger.Debugf("%s", dump)
}
resp, err := client.client.Do(req)
if err != nil {
var ue *url.Error

@ -51,7 +51,8 @@ func TestRequest(t *testing.T) {
h := httpServerT(t, ret)
defer h.Close()
var o HTTPOptions
c, err := NewHTTPClient(&o)
log := NewLogger(false)
c, err := NewHTTPClient(&o, false, log)
if err != nil {
t.Fatalf("Got Error: %v", err)
}
@ -78,7 +79,8 @@ func BenchmarkRequestWithoutBody(b *testing.B) {
h := httpServerB(b, r)
defer h.Close()
var o HTTPOptions
c, err := NewHTTPClient(&o)
log := NewLogger(false)
c, err := NewHTTPClient(&o, false, log)
if err != nil {
b.Fatalf("Got Error: %v", err)
}
@ -98,7 +100,8 @@ func BenchmarkRequestWitBody(b *testing.B) {
h := httpServerB(b, r)
defer h.Close()
var o HTTPOptions
c, err := NewHTTPClient(&o)
log := NewLogger(false)
c, err := NewHTTPClient(&o, false, log)
if err != nil {
b.Fatalf("Got Error: %v", err)
}
@ -118,8 +121,9 @@ func BenchmarkNewHTTPClient(b *testing.B) {
h := httpServerB(b, r)
defer h.Close()
var o HTTPOptions
log := NewLogger(false)
for x := 0; x < b.N; x++ {
_, err := NewHTTPClient(&o)
_, err := NewHTTPClient(&o, false, log)
if err != nil {
b.Fatalf("Got Error: %v", err)
}

@ -25,13 +25,13 @@ type ResultToStringFunc func(*Gobuster, *Result) (*string, error)
// Gobuster is the main object when creating a new run
type Gobuster struct {
Opts *Options
Logger Logger
Logger *Logger
plugin GobusterPlugin
Progress *Progress
}
// NewGobuster returns a new Gobuster object
func NewGobuster(opts *Options, plugin GobusterPlugin, logger Logger) (*Gobuster, error) {
func NewGobuster(opts *Options, plugin GobusterPlugin, logger *Logger) (*Gobuster, error) {
var g Gobuster
g.Opts = opts
g.plugin = plugin

@ -16,8 +16,8 @@ type Logger struct {
debug bool
}
func NewLogger(debug bool) Logger {
return Logger{
func NewLogger(debug bool) *Logger {
return &Logger{
log: log.New(os.Stdout, "", 0),
errorLog: log.New(os.Stderr, color.New(color.FgRed).Sprint("[ERROR] "), 0),
debugLog: log.New(os.Stderr, color.New(color.FgBlue).Sprint("[DEBUG] "), 0),