From 2a727201cb0f66265cc3344de7b86aa1b5497be9 Mon Sep 17 00:00:00 2001 From: 0xyy66 Date: Thu, 3 Oct 2024 10:37:48 +0200 Subject: [PATCH] Add exclude-hostname-length flag --- cli/vhost/vhost.go | 2 ++ gobustervhost/gobustervhost.go | 12 +++++++++++- gobustervhost/options.go | 9 +++++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/cli/vhost/vhost.go b/cli/vhost/vhost.go index 8bac8b2..d28cba1 100644 --- a/cli/vhost/vhost.go +++ b/cli/vhost/vhost.go @@ -31,6 +31,7 @@ func getFlags() []cli.Flag { &cli.StringFlag{Name: "exclude-status", Aliases: []string{"xs"}, Usage: "exclude the following status codes. Can also handle ranges like 200,300-400,404.", Value: ""}, &cli.StringFlag{Name: "domain", Aliases: []string{"do"}, Usage: "the domain to append when using an IP address as URL. If left empty and you specify a domain based URL the hostname from the URL is extracted"}, &cli.BoolFlag{Name: "force", Value: false, Usage: "Force execution even when result is not guaranteed."}, + &cli.BoolFlag{Name: "exclude-hostname-length", Aliases: []string{"xh"}, Value: false, Usage: "Automatically adjust exclude-length based on dynamic hostname length in responses"}, }...) return flags @@ -47,6 +48,7 @@ func run(c *cli.Context) error { pluginOpts.AppendDomain = c.Bool("append-domain") pluginOpts.ExcludeLength = c.String("exclude-length") + pluginOpts.ExcludeHostnameLength = c.Bool("exclude-hostname-length") ret, err := libgobuster.ParseCommaSeparatedInt(pluginOpts.ExcludeLength) if err != nil { return fmt.Errorf("invalid value for exclude-length: %w", err) diff --git a/gobustervhost/gobustervhost.go b/gobustervhost/gobustervhost.go index d3a6dc1..36c79a6 100644 --- a/gobustervhost/gobustervhost.go +++ b/gobustervhost/gobustervhost.go @@ -127,12 +127,18 @@ func (v *GobusterVhost) PreRun(ctx context.Context, _ *libgobuster.Progress) err // ProcessWord is the process implementation of gobusterdir func (v *GobusterVhost) ProcessWord(ctx context.Context, word string, progress *libgobuster.Progress) (libgobuster.Result, error) { var subdomain string + var wordLength int if v.options.AppendDomain { subdomain = fmt.Sprintf("%s.%s", word, v.domain) } else { // wordlist needs to include full domains subdomain = word } + if v.options.ExcludeHostnameLength { + wordLength = len(word) + } else { + wordLength = 0 + } // warn people when there is no . detected so they might want to use the other options v.once.Do(func() { @@ -194,7 +200,7 @@ func (v *GobusterVhost) ProcessWord(ctx context.Context, word string, progress * // subdomain must not match default vhost and non existent vhost // or verbose mode is enabled found := body != nil && !bytes.Equal(body, v.normalBody) && !bytes.Equal(body, v.abnormalBody) - if found && !v.options.ExcludeLengthParsed.Contains(int(size)) && !v.options.ExcludeStatusParsed.Contains(statusCode) { + if found && !v.options.ExcludeLengthParsed.Contains(int(size)-wordLength) && !v.options.ExcludeStatusParsed.Contains(statusCode) { r := Result{ Vhost: subdomain, StatusCode: statusCode, @@ -300,6 +306,10 @@ func (v *GobusterVhost) GetConfigString() (string, error) { } } + if _, err := fmt.Fprintf(tw, "[+] Exclude Hostname Length:\t%t\n", v.options.ExcludeHostnameLength); err != nil { + return "", err + } + if err := tw.Flush(); err != nil { return "", fmt.Errorf("error on tostring: %w", err) } diff --git a/gobustervhost/options.go b/gobustervhost/options.go index 7e34c0b..996b314 100644 --- a/gobustervhost/options.go +++ b/gobustervhost/options.go @@ -7,12 +7,13 @@ import ( // OptionsVhost is the struct to hold all options for this plugin type OptionsVhost struct { libgobuster.HTTPOptions - AppendDomain bool - ExcludeLength string - ExcludeLengthParsed libgobuster.Set[int] + AppendDomain bool + ExcludeLength string + ExcludeLengthParsed libgobuster.Set[int] ExcludeStatus string ExcludeStatusParsed libgobuster.Set[int] - Domain string + Domain string + ExcludeHostnameLength bool } // NewOptions returns a new initialized OptionsVhost