Codebase list gobuster / f7d27d1
Update upstream source from tag 'upstream/3.3.0' Update to upstream version '3.3.0' with Debian dir 0aadaa329dacdcbe89c3a96fd80f0016be6e39b1 Sophie Brun 1 year, 6 months ago
25 changed file(s) with 409 addition(s) and 161 deletion(s). Raw diff Collapse all Expand all
66 updates:
77 - package-ecosystem: "gomod"
88 directory: "/"
9 target-branch: "dev"
910 schedule:
1011 interval: "weekly"
1112
1213 - package-ecosystem: "github-actions"
1314 directory: "/"
15 target-branch: "dev"
1416 schedule:
1517 # Check for updates to GitHub Actions every weekday
1618 interval: "daily"
2020 All funds that are donated to this project will be donated to charity. A full log of charity donations will be available in this repository as they are processed.
2121
2222 # Changes
23
24 ## 3.3
25
26 - Support TLS client certificates / mtl
27 - support loading extensions from file
28 - support fuzzing POST body, HTTP headers and basic auth
29 - new option to not canonicalize header names
2330
2431 ## 3.2
2532
478485 ### Options
479486
480487 ```text
481 Uses VHOST enumeration mode (you most probably want to use the IP adress as the URL parameter
488 Uses VHOST enumeration mode (you most probably want to use the IP address as the URL parameter)
482489
483490 Usage:
484491 gobuster vhost [flags]
4141 return nil, nil, err
4242 }
4343
44 plugin := gobusterdir.NewOptionsDir()
44 pluginOpts := gobusterdir.NewOptionsDir()
4545
4646 httpOpts, err := parseCommonHTTPOptions(cmdDir)
4747 if err != nil {
4848 return nil, nil, err
4949 }
50 plugin.Password = httpOpts.Password
51 plugin.URL = httpOpts.URL
52 plugin.UserAgent = httpOpts.UserAgent
53 plugin.Username = httpOpts.Username
54 plugin.Proxy = httpOpts.Proxy
55 plugin.Cookies = httpOpts.Cookies
56 plugin.Timeout = httpOpts.Timeout
57 plugin.FollowRedirect = httpOpts.FollowRedirect
58 plugin.NoTLSValidation = httpOpts.NoTLSValidation
59 plugin.Headers = httpOpts.Headers
60 plugin.Method = httpOpts.Method
61 plugin.RetryOnTimeout = httpOpts.RetryOnTimeout
62 plugin.RetryAttempts = httpOpts.RetryAttempts
50 pluginOpts.Password = httpOpts.Password
51 pluginOpts.URL = httpOpts.URL
52 pluginOpts.UserAgent = httpOpts.UserAgent
53 pluginOpts.Username = httpOpts.Username
54 pluginOpts.Proxy = httpOpts.Proxy
55 pluginOpts.Cookies = httpOpts.Cookies
56 pluginOpts.Timeout = httpOpts.Timeout
57 pluginOpts.FollowRedirect = httpOpts.FollowRedirect
58 pluginOpts.NoTLSValidation = httpOpts.NoTLSValidation
59 pluginOpts.Headers = httpOpts.Headers
60 pluginOpts.Method = httpOpts.Method
61 pluginOpts.RetryOnTimeout = httpOpts.RetryOnTimeout
62 pluginOpts.RetryAttempts = httpOpts.RetryAttempts
63 pluginOpts.TLSCertificate = httpOpts.TLSCertificate
64 pluginOpts.NoCanonicalizeHeaders = httpOpts.NoCanonicalizeHeaders
6365
64 plugin.Extensions, err = cmdDir.Flags().GetString("extensions")
66 pluginOpts.Extensions, err = cmdDir.Flags().GetString("extensions")
6567 if err != nil {
6668 return nil, nil, fmt.Errorf("invalid value for extensions: %w", err)
6769 }
68 ret, err := helper.ParseExtensions(plugin.Extensions)
70
71 ret, err := helper.ParseExtensions(pluginOpts.Extensions)
6972 if err != nil {
7073 return nil, nil, fmt.Errorf("invalid value for extensions: %w", err)
7174 }
72 plugin.ExtensionsParsed = ret
75 pluginOpts.ExtensionsParsed = ret
76
77 pluginOpts.ExtensionsFile, err = cmdDir.Flags().GetString("extensions-file")
78 if err != nil {
79 return nil, nil, fmt.Errorf("invalid value for extensions file: %w", err)
80 }
81
82 if pluginOpts.ExtensionsFile != "" {
83 extensions, err := helper.ParseExtensionsFile(pluginOpts.ExtensionsFile)
84 if err != nil {
85 return nil, nil, fmt.Errorf("invalid value for extensions file: %w", err)
86 }
87 pluginOpts.ExtensionsParsed.AddRange(extensions)
88 }
7389
7490 // parse normal status codes
75 plugin.StatusCodes, err = cmdDir.Flags().GetString("status-codes")
91 pluginOpts.StatusCodes, err = cmdDir.Flags().GetString("status-codes")
7692 if err != nil {
7793 return nil, nil, fmt.Errorf("invalid value for status-codes: %w", err)
7894 }
79 ret2, err := helper.ParseCommaSeparatedInt(plugin.StatusCodes)
95 ret2, err := helper.ParseCommaSeparatedInt(pluginOpts.StatusCodes)
8096 if err != nil {
8197 return nil, nil, fmt.Errorf("invalid value for status-codes: %w", err)
8298 }
83 plugin.StatusCodesParsed = ret2
99 pluginOpts.StatusCodesParsed = ret2
84100
85101 // blacklist will override the normal status codes
86 plugin.StatusCodesBlacklist, err = cmdDir.Flags().GetString("status-codes-blacklist")
102 pluginOpts.StatusCodesBlacklist, err = cmdDir.Flags().GetString("status-codes-blacklist")
87103 if err != nil {
88104 return nil, nil, fmt.Errorf("invalid value for status-codes-blacklist: %w", err)
89105 }
90 ret3, err := helper.ParseCommaSeparatedInt(plugin.StatusCodesBlacklist)
106 ret3, err := helper.ParseCommaSeparatedInt(pluginOpts.StatusCodesBlacklist)
91107 if err != nil {
92108 return nil, nil, fmt.Errorf("invalid value for status-codes-blacklist: %w", err)
93109 }
94 plugin.StatusCodesBlacklistParsed = ret3
110 pluginOpts.StatusCodesBlacklistParsed = ret3
95111
96 if plugin.StatusCodes != "" && plugin.StatusCodesBlacklist != "" {
112 if pluginOpts.StatusCodes != "" && pluginOpts.StatusCodesBlacklist != "" {
97113 return nil, nil, fmt.Errorf("status-codes (%q) and status-codes-blacklist (%q) are both set - please set only one. status-codes-blacklist is set by default so you might want to disable it by supplying an empty string.",
98 plugin.StatusCodes, plugin.StatusCodesBlacklist)
114 pluginOpts.StatusCodes, pluginOpts.StatusCodesBlacklist)
99115 }
100116
101 if plugin.StatusCodes == "" && plugin.StatusCodesBlacklist == "" {
117 if pluginOpts.StatusCodes == "" && pluginOpts.StatusCodesBlacklist == "" {
102118 return nil, nil, fmt.Errorf("status-codes and status-codes-blacklist are both not set, please set one")
103119 }
104120
105 plugin.UseSlash, err = cmdDir.Flags().GetBool("add-slash")
121 pluginOpts.UseSlash, err = cmdDir.Flags().GetBool("add-slash")
106122 if err != nil {
107123 return nil, nil, fmt.Errorf("invalid value for add-slash: %w", err)
108124 }
109125
110 plugin.Expanded, err = cmdDir.Flags().GetBool("expanded")
126 pluginOpts.Expanded, err = cmdDir.Flags().GetBool("expanded")
111127 if err != nil {
112128 return nil, nil, fmt.Errorf("invalid value for expanded: %w", err)
113129 }
114130
115 plugin.NoStatus, err = cmdDir.Flags().GetBool("no-status")
131 pluginOpts.NoStatus, err = cmdDir.Flags().GetBool("no-status")
116132 if err != nil {
117133 return nil, nil, fmt.Errorf("invalid value for no-status: %w", err)
118134 }
119135
120 plugin.HideLength, err = cmdDir.Flags().GetBool("hide-length")
136 pluginOpts.HideLength, err = cmdDir.Flags().GetBool("hide-length")
121137 if err != nil {
122138 return nil, nil, fmt.Errorf("invalid value for hide-length: %w", err)
123139 }
124140
125 plugin.DiscoverBackup, err = cmdDir.Flags().GetBool("discover-backup")
141 pluginOpts.DiscoverBackup, err = cmdDir.Flags().GetBool("discover-backup")
126142 if err != nil {
127143 return nil, nil, fmt.Errorf("invalid value for discover-backup: %w", err)
128144 }
129145
130 plugin.ExcludeLength, err = cmdDir.Flags().GetIntSlice("exclude-length")
146 pluginOpts.ExcludeLength, err = cmdDir.Flags().GetIntSlice("exclude-length")
131147 if err != nil {
132148 return nil, nil, fmt.Errorf("invalid value for excludelength: %w", err)
133149 }
134150
135 return globalopts, plugin, nil
151 return globalopts, pluginOpts, nil
136152 }
137153
138154 // nolint:gochecknoinits
149165 cmdDir.Flags().StringP("status-codes", "s", "", "Positive status codes (will be overwritten with status-codes-blacklist if set)")
150166 cmdDir.Flags().StringP("status-codes-blacklist", "b", "404", "Negative status codes (will override status-codes if set)")
151167 cmdDir.Flags().StringP("extensions", "x", "", "File extension(s) to search for")
168 cmdDir.Flags().StringP("extensions-file", "X", "", "Read file extension(s) to search from the file")
152169 cmdDir.Flags().BoolP("expanded", "e", false, "Expanded mode, print full URLs")
153170 cmdDir.Flags().BoolP("no-status", "n", false, "Don't print status codes")
154171 cmdDir.Flags().Bool("hide-length", false, "Hide the length of the body in the output")
4141 if err != nil {
4242 return nil, nil, err
4343 }
44 plugin := gobusterdns.NewOptionsDNS()
44 pluginOpts := gobusterdns.NewOptionsDNS()
4545
46 plugin.Domain, err = cmdDNS.Flags().GetString("domain")
46 pluginOpts.Domain, err = cmdDNS.Flags().GetString("domain")
4747 if err != nil {
4848 return nil, nil, fmt.Errorf("invalid value for domain: %w", err)
4949 }
5050
51 plugin.ShowIPs, err = cmdDNS.Flags().GetBool("show-ips")
51 pluginOpts.ShowIPs, err = cmdDNS.Flags().GetBool("show-ips")
5252 if err != nil {
5353 return nil, nil, fmt.Errorf("invalid value for show-ips: %w", err)
5454 }
5555
56 plugin.ShowCNAME, err = cmdDNS.Flags().GetBool("show-cname")
56 pluginOpts.ShowCNAME, err = cmdDNS.Flags().GetBool("show-cname")
5757 if err != nil {
5858 return nil, nil, fmt.Errorf("invalid value for show-cname: %w", err)
5959 }
6060
61 plugin.WildcardForced, err = cmdDNS.Flags().GetBool("wildcard")
61 pluginOpts.WildcardForced, err = cmdDNS.Flags().GetBool("wildcard")
6262 if err != nil {
6363 return nil, nil, fmt.Errorf("invalid value for wildcard: %w", err)
6464 }
6565
66 plugin.Timeout, err = cmdDNS.Flags().GetDuration("timeout")
66 pluginOpts.Timeout, err = cmdDNS.Flags().GetDuration("timeout")
6767 if err != nil {
6868 return nil, nil, fmt.Errorf("invalid value for timeout: %w", err)
6969 }
7070
71 plugin.Resolver, err = cmdDNS.Flags().GetString("resolver")
71 pluginOpts.Resolver, err = cmdDNS.Flags().GetString("resolver")
7272 if err != nil {
7373 return nil, nil, fmt.Errorf("invalid value for resolver: %w", err)
7474 }
7575
76 if plugin.Resolver != "" && runtime.GOOS == "windows" {
76 if pluginOpts.Resolver != "" && runtime.GOOS == "windows" {
7777 return nil, nil, fmt.Errorf("currently can not set custom dns resolver on windows. See https://golang.org/pkg/net/#hdr-Name_Resolution")
7878 }
7979
80 return globalopts, plugin, nil
80 return globalopts, pluginOpts, nil
8181 }
8282
8383 // nolint:gochecknoinits
33 "errors"
44 "fmt"
55 "log"
6 "strings"
67
78 "github.com/OJ/gobuster/v3/cli"
89 "github.com/OJ/gobuster/v3/gobusterfuzz"
1819 globalopts, pluginopts, err := parseFuzzOptions()
1920 if err != nil {
2021 return fmt.Errorf("error on parsing arguments: %w", err)
22 }
23
24 if !containsFuzzKeyword(*pluginopts) {
25 return fmt.Errorf("please provide the %s keyword", gobusterfuzz.FuzzKeyword)
2126 }
2227
2328 plugin, err := gobusterfuzz.NewGobusterFuzz(globalopts, pluginopts)
4146 return nil, nil, err
4247 }
4348
44 plugin := gobusterfuzz.NewOptionsFuzz()
49 pluginOpts := gobusterfuzz.NewOptionsFuzz()
4550
4651 httpOpts, err := parseCommonHTTPOptions(cmdFuzz)
4752 if err != nil {
4853 return nil, nil, err
4954 }
50 plugin.Password = httpOpts.Password
51 plugin.URL = httpOpts.URL
52 plugin.UserAgent = httpOpts.UserAgent
53 plugin.Username = httpOpts.Username
54 plugin.Proxy = httpOpts.Proxy
55 plugin.Cookies = httpOpts.Cookies
56 plugin.Timeout = httpOpts.Timeout
57 plugin.FollowRedirect = httpOpts.FollowRedirect
58 plugin.NoTLSValidation = httpOpts.NoTLSValidation
59 plugin.Headers = httpOpts.Headers
60 plugin.Method = httpOpts.Method
61 plugin.RetryOnTimeout = httpOpts.RetryOnTimeout
62 plugin.RetryAttempts = httpOpts.RetryAttempts
55 pluginOpts.Password = httpOpts.Password
56 pluginOpts.URL = httpOpts.URL
57 pluginOpts.UserAgent = httpOpts.UserAgent
58 pluginOpts.Username = httpOpts.Username
59 pluginOpts.Proxy = httpOpts.Proxy
60 pluginOpts.Cookies = httpOpts.Cookies
61 pluginOpts.Timeout = httpOpts.Timeout
62 pluginOpts.FollowRedirect = httpOpts.FollowRedirect
63 pluginOpts.NoTLSValidation = httpOpts.NoTLSValidation
64 pluginOpts.Headers = httpOpts.Headers
65 pluginOpts.Method = httpOpts.Method
66 pluginOpts.RetryOnTimeout = httpOpts.RetryOnTimeout
67 pluginOpts.RetryAttempts = httpOpts.RetryAttempts
68 pluginOpts.TLSCertificate = httpOpts.TLSCertificate
69 pluginOpts.NoCanonicalizeHeaders = httpOpts.NoCanonicalizeHeaders
6370
6471 // blacklist will override the normal status codes
65 plugin.ExcludedStatusCodes, err = cmdFuzz.Flags().GetString("excludestatuscodes")
72 pluginOpts.ExcludedStatusCodes, err = cmdFuzz.Flags().GetString("excludestatuscodes")
6673 if err != nil {
6774 return nil, nil, fmt.Errorf("invalid value for excludestatuscodes: %w", err)
6875 }
69 ret, err := helper.ParseCommaSeparatedInt(plugin.ExcludedStatusCodes)
76 ret, err := helper.ParseCommaSeparatedInt(pluginOpts.ExcludedStatusCodes)
7077 if err != nil {
7178 return nil, nil, fmt.Errorf("invalid value for excludestatuscodes: %w", err)
7279 }
73 plugin.ExcludedStatusCodesParsed = ret
80 pluginOpts.ExcludedStatusCodesParsed = ret
7481
75 plugin.ExcludeLength, err = cmdFuzz.Flags().GetIntSlice("exclude-length")
82 pluginOpts.ExcludeLength, err = cmdFuzz.Flags().GetIntSlice("exclude-length")
7683 if err != nil {
7784 return nil, nil, fmt.Errorf("invalid value for excludelength: %w", err)
7885 }
7986
80 return globalopts, plugin, nil
87 pluginOpts.RequestBody, err = cmdFuzz.Flags().GetString("body")
88 if err != nil {
89 return nil, nil, fmt.Errorf("invalid value for body: %w", err)
90 }
91
92 return globalopts, pluginOpts, nil
8193 }
8294
8395 // nolint:gochecknoinits
8496 func init() {
8597 cmdFuzz = &cobra.Command{
8698 Use: "fuzz",
87 Short: "Uses fuzzing mode",
99 Short: fmt.Sprintf("Uses fuzzing mode. Replaces the keyword %s in the URL, Headers and the request body", gobusterfuzz.FuzzKeyword),
88100 RunE: runFuzz,
89101 }
90102
93105 }
94106 cmdFuzz.Flags().StringP("excludestatuscodes", "b", "", "Negative status codes (will override statuscodes if set)")
95107 cmdFuzz.Flags().IntSlice("exclude-length", []int{}, "exclude the following content length (completely ignores the status). Supply multiple times to exclude multiple sizes.")
108 cmdFuzz.Flags().StringP("body", "B", "", "Request body")
96109
97110 cmdFuzz.PersistentPreRun = func(cmd *cobra.Command, args []string) {
98111 configureGlobalOptions()
100113
101114 rootCmd.AddCommand(cmdFuzz)
102115 }
116
117 func containsFuzzKeyword(pluginopts gobusterfuzz.OptionsFuzz) bool {
118 if strings.Contains(pluginopts.URL, gobusterfuzz.FuzzKeyword) {
119 return true
120 }
121
122 if strings.Contains(pluginopts.RequestBody, gobusterfuzz.FuzzKeyword) {
123 return true
124 }
125
126 for _, h := range pluginopts.Headers {
127 if strings.Contains(h.Name, gobusterfuzz.FuzzKeyword) || strings.Contains(h.Value, gobusterfuzz.FuzzKeyword) {
128 return true
129 }
130 }
131
132 if strings.Contains(pluginopts.Username, gobusterfuzz.FuzzKeyword) {
133 return true
134 }
135
136 if strings.Contains(pluginopts.Password, gobusterfuzz.FuzzKeyword) {
137 return true
138 }
139
140 return false
141 }
4747 pluginopts.NoTLSValidation = httpOpts.NoTLSValidation
4848 pluginopts.RetryOnTimeout = httpOpts.RetryOnTimeout
4949 pluginopts.RetryAttempts = httpOpts.RetryAttempts
50 pluginopts.TLSCertificate = httpOpts.TLSCertificate
5051
5152 pluginopts.MaxFilesToList, err = cmdGCS.Flags().GetInt("maxfiles")
5253 if err != nil {
00 package cmd
11
22 import (
3 "crypto/tls"
4 "encoding/pem"
35 "fmt"
6 "os"
47 "regexp"
58 "strconv"
69 "strings"
1013 "github.com/OJ/gobuster/v3/helper"
1114 "github.com/OJ/gobuster/v3/libgobuster"
1215 "github.com/spf13/cobra"
16 "golang.org/x/crypto/pkcs12"
1317 "golang.org/x/term"
1418 )
1519
2125 cmd.Flags().BoolP("no-tls-validation", "k", false, "Skip TLS certificate verification")
2226 cmd.Flags().BoolP("retry", "", false, "Should retry on request timeout")
2327 cmd.Flags().IntP("retry-attempts", "", 3, "Times to retry on request timeout")
28 // client certificates, either pem or p12
29 cmd.Flags().StringP("client-cert-pem", "", "", "public key in PEM format for optional TLS client certificates")
30 cmd.Flags().StringP("client-cert-pem-key", "", "", "private key in PEM format for optional TLS client certificates (this key needs to have no password)")
31 cmd.Flags().StringP("client-cert-p12", "", "", "a p12 file to use for options TLS client certificates")
32 cmd.Flags().StringP("client-cert-p12-password", "", "", "the password to the p12 file")
2433 }
2534
2635 func addCommonHTTPOptions(cmd *cobra.Command) error {
3140 cmd.Flags().StringP("password", "P", "", "Password for Basic Auth")
3241 cmd.Flags().BoolP("follow-redirect", "r", false, "Follow redirects")
3342 cmd.Flags().StringArrayP("headers", "H", []string{""}, "Specify HTTP headers, -H 'Header1: val1' -H 'Header2: val2'")
43 cmd.Flags().BoolP("no-canonicalize-headers", "", false, "Do not canonicalize HTTP header names. If set header names are sent as is.")
3444 cmd.Flags().StringP("method", "m", "GET", "Use the following HTTP method")
3545
3646 if err := cmd.MarkFlagRequired("url"); err != nil {
8494 if err != nil {
8595 return options, fmt.Errorf("invalid value for no-tls-validation: %w", err)
8696 }
97
98 pemFile, err := cmd.Flags().GetString("client-cert-pem")
99 if err != nil {
100 return options, fmt.Errorf("invalid value for client-cert-pem: %w", err)
101 }
102 pemKeyFile, err := cmd.Flags().GetString("client-cert-pem-key")
103 if err != nil {
104 return options, fmt.Errorf("invalid value for client-cert-pem-key: %w", err)
105 }
106 p12File, err := cmd.Flags().GetString("client-cert-p12")
107 if err != nil {
108 return options, fmt.Errorf("invalid value for client-cert-p12: %w", err)
109 }
110 p12Pass, err := cmd.Flags().GetString("client-cert-p12-password")
111 if err != nil {
112 return options, fmt.Errorf("invalid value for client-cert-p12-password: %w", err)
113 }
114
115 if pemFile != "" && p12File != "" {
116 return options, fmt.Errorf("please supply either a pem or a p12, not both")
117 }
118
119 if pemFile != "" {
120 cert, err := tls.LoadX509KeyPair(pemFile, pemKeyFile)
121 if err != nil {
122 return options, fmt.Errorf("could not load supplied pem key: %w", err)
123 }
124 options.TLSCertificate = &cert
125 } else if p12File != "" {
126 p12Content, err := os.ReadFile(p12File)
127 if err != nil {
128 return options, fmt.Errorf("could not read p12 %s: %w", p12File, err)
129 }
130 blocks, err := pkcs12.ToPEM(p12Content, p12Pass)
131 if err != nil {
132 return options, fmt.Errorf("could not load P12: %w", err)
133 }
134 var pemData []byte
135 for _, b := range blocks {
136 pemData = append(pemData, pem.EncodeToMemory(b)...)
137 }
138 cert, err := tls.X509KeyPair(pemData, pemData)
139 if err != nil {
140 return options, fmt.Errorf("could not load certificate from P12: %w", err)
141 }
142 options.TLSCertificate = &cert
143 }
144
87145 return options, nil
88146 }
89147
101159 options.NoTLSValidation = basic.NoTLSValidation
102160 options.RetryOnTimeout = basic.RetryOnTimeout
103161 options.RetryAttempts = basic.RetryAttempts
162 options.TLSCertificate = basic.TLSCertificate
104163
105164 options.URL, err = cmd.Flags().GetString("url")
106165 if err != nil {
171230 options.Headers = append(options.Headers, header)
172231 }
173232
233 noCanonHeaders, err := cmd.Flags().GetBool("no-canonicalize-headers")
234 if err != nil {
235 return options, fmt.Errorf("invalid value for no-canonicalize-headers: %w", err)
236 }
237 options.NoCanonicalizeHeaders = noCanonHeaders
238
174239 // Prompt for PW if not provided
175240 if options.Username != "" && options.Password == "" {
176241 fmt.Printf("[?] Auth Password: ")
3434 return nil, nil, err
3535 }
3636
37 plugin := gobusters3.NewOptionsS3()
37 pluginOpts := gobusters3.NewOptionsS3()
3838
3939 httpOpts, err := parseBasicHTTPOptions(cmdS3)
4040 if err != nil {
4141 return nil, nil, err
4242 }
4343
44 plugin.UserAgent = httpOpts.UserAgent
45 plugin.Proxy = httpOpts.Proxy
46 plugin.Timeout = httpOpts.Timeout
47 plugin.NoTLSValidation = httpOpts.NoTLSValidation
48 plugin.RetryOnTimeout = httpOpts.RetryOnTimeout
49 plugin.RetryAttempts = httpOpts.RetryAttempts
44 pluginOpts.UserAgent = httpOpts.UserAgent
45 pluginOpts.Proxy = httpOpts.Proxy
46 pluginOpts.Timeout = httpOpts.Timeout
47 pluginOpts.NoTLSValidation = httpOpts.NoTLSValidation
48 pluginOpts.RetryOnTimeout = httpOpts.RetryOnTimeout
49 pluginOpts.RetryAttempts = httpOpts.RetryAttempts
50 pluginOpts.TLSCertificate = httpOpts.TLSCertificate
5051
51 plugin.MaxFilesToList, err = cmdS3.Flags().GetInt("maxfiles")
52 pluginOpts.MaxFilesToList, err = cmdS3.Flags().GetInt("maxfiles")
5253 if err != nil {
5354 return nil, nil, fmt.Errorf("invalid value for maxfiles: %w", err)
5455 }
5556
56 return globalopts, plugin, nil
57 return globalopts, pluginOpts, nil
5758 }
5859
5960 // nolint:gochecknoinits
3434 if err != nil {
3535 return nil, nil, err
3636 }
37 var plugin gobustervhost.OptionsVhost
37
38 pluginOpts := gobustervhost.NewOptionsVhost()
3839
3940 httpOpts, err := parseCommonHTTPOptions(cmdVhost)
4041 if err != nil {
4142 return nil, nil, err
4243 }
43 plugin.Password = httpOpts.Password
44 plugin.URL = httpOpts.URL
45 plugin.UserAgent = httpOpts.UserAgent
46 plugin.Username = httpOpts.Username
47 plugin.Proxy = httpOpts.Proxy
48 plugin.Cookies = httpOpts.Cookies
49 plugin.Timeout = httpOpts.Timeout
50 plugin.FollowRedirect = httpOpts.FollowRedirect
51 plugin.NoTLSValidation = httpOpts.NoTLSValidation
52 plugin.Headers = httpOpts.Headers
53 plugin.Method = httpOpts.Method
54 plugin.RetryOnTimeout = httpOpts.RetryOnTimeout
55 plugin.RetryAttempts = httpOpts.RetryAttempts
44 pluginOpts.Password = httpOpts.Password
45 pluginOpts.URL = httpOpts.URL
46 pluginOpts.UserAgent = httpOpts.UserAgent
47 pluginOpts.Username = httpOpts.Username
48 pluginOpts.Proxy = httpOpts.Proxy
49 pluginOpts.Cookies = httpOpts.Cookies
50 pluginOpts.Timeout = httpOpts.Timeout
51 pluginOpts.FollowRedirect = httpOpts.FollowRedirect
52 pluginOpts.NoTLSValidation = httpOpts.NoTLSValidation
53 pluginOpts.Headers = httpOpts.Headers
54 pluginOpts.Method = httpOpts.Method
55 pluginOpts.RetryOnTimeout = httpOpts.RetryOnTimeout
56 pluginOpts.RetryAttempts = httpOpts.RetryAttempts
57 pluginOpts.TLSCertificate = httpOpts.TLSCertificate
58 pluginOpts.NoCanonicalizeHeaders = httpOpts.NoCanonicalizeHeaders
5659
57 plugin.AppendDomain, err = cmdVhost.Flags().GetBool("append-domain")
60 pluginOpts.AppendDomain, err = cmdVhost.Flags().GetBool("append-domain")
5861 if err != nil {
5962 return nil, nil, fmt.Errorf("invalid value for append-domain: %w", err)
6063 }
6164
62 plugin.ExcludeLength, err = cmdVhost.Flags().GetIntSlice("exclude-length")
65 pluginOpts.ExcludeLength, err = cmdVhost.Flags().GetIntSlice("exclude-length")
6366 if err != nil {
6467 return nil, nil, fmt.Errorf("invalid value for excludelength: %w", err)
6568 }
6669
67 plugin.Domain, err = cmdVhost.Flags().GetString("domain")
70 pluginOpts.Domain, err = cmdVhost.Flags().GetString("domain")
6871 if err != nil {
6972 return nil, nil, fmt.Errorf("invalid value for domain: %w", err)
7073 }
7174
72 return globalopts, &plugin, nil
75 return globalopts, pluginOpts, nil
7376 }
7477
7578 // nolint:gochecknoinits
7679 func init() {
7780 cmdVhost = &cobra.Command{
7881 Use: "vhost",
79 Short: "Uses VHOST enumeration mode (you most probably want to use the IP adress as the URL parameter",
82 Short: "Uses VHOST enumeration mode (you most probably want to use the IP address as the URL parameter)",
8083 RunE: runVhost,
8184 }
8285 if err := addCommonHTTPOptions(cmdVhost); err != nil {
1717 h := httpServer(b, "test")
1818 defer h.Close()
1919
20 pluginopts := gobustervhost.OptionsVhost{}
20 pluginopts := gobustervhost.NewOptionsVhost()
2121 pluginopts.URL = h.URL
2222 pluginopts.Timeout = 10 * time.Second
2323
5353 for x := 0; x < b.N; x++ {
5454 os.Stdout = devnull
5555 os.Stderr = devnull
56 plugin, err := gobustervhost.NewGobusterVhost(&globalopts, &pluginopts)
56 plugin, err := gobustervhost.NewGobusterVhost(&globalopts, pluginopts)
5757 if err != nil {
5858 b.Fatalf("error on creating gobusterdir: %v", err)
5959 }
44 require (
55 github.com/fatih/color v1.13.0
66 github.com/google/uuid v1.3.0
7 github.com/spf13/cobra v1.5.0
8 golang.org/x/term v0.0.0-20220919170432-7a66f970e087
7 github.com/spf13/cobra v1.6.1
8 golang.org/x/crypto v0.1.0
9 golang.org/x/term v0.1.0
910 )
1011
1112 require (
1314 github.com/mattn/go-colorable v0.1.13 // indirect
1415 github.com/mattn/go-isatty v0.0.16 // indirect
1516 github.com/spf13/pflag v1.0.5 // indirect
16 golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 // indirect
17 golang.org/x/sys v0.1.0 // indirect
1718 )
22 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
33 github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
44 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
5 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
65 github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
76 github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
87 github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
1312 github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
1413 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
1514 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
16 github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
17 github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
15 github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
16 github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
1817 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
1918 github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
19 golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
20 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
2021 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2122 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2223 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2324 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
24 golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875 h1:AzgQNqF+FKwyQ5LbVrVqOcuuFB67N47F9+htZYH0wFM=
25 golang.org/x/sys v0.0.0-20221006211917-84dc82d7e875/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
26 golang.org/x/term v0.0.0-20220919170432-7a66f970e087 h1:tPwmk4vmvVCMdr98VgL4JH+qZxPL8fqlUOHnyOM8N3w=
27 golang.org/x/term v0.0.0-20220919170432-7a66f970e087/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
25 golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
26 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
27 golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
28 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
2829 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
29 gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
30 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
6161 NoTLSValidation: opts.NoTLSValidation,
6262 RetryOnTimeout: opts.RetryOnTimeout,
6363 RetryAttempts: opts.RetryAttempts,
64 TLSCertificate: opts.TLSCertificate,
6465 }
6566
6667 httpOpts := libgobuster.HTTPOptions{
67 BasicHTTPOptions: basicOptions,
68 FollowRedirect: opts.FollowRedirect,
69 Username: opts.Username,
70 Password: opts.Password,
71 Headers: opts.Headers,
72 Cookies: opts.Cookies,
73 Method: opts.Method,
68 BasicHTTPOptions: basicOptions,
69 FollowRedirect: opts.FollowRedirect,
70 Username: opts.Username,
71 Password: opts.Password,
72 Headers: opts.Headers,
73 NoCanonicalizeHeaders: opts.NoCanonicalizeHeaders,
74 Cookies: opts.Cookies,
75 Method: opts.Method,
7476 }
7577
7678 h, err := libgobuster.NewHTTPClient(&httpOpts)
320322 }
321323 }
322324
323 if o.Extensions != "" {
325 if o.Extensions != "" || o.ExtensionsFile != "" {
324326 if _, err := fmt.Fprintf(tw, "[+] Extensions:\t%s\n", o.ExtensionsParsed.Stringify()); err != nil {
327 return "", err
328 }
329 }
330
331 if o.ExtensionsFile != "" {
332 if _, err := fmt.Fprintf(tw, "[+] Extensions file:\t%s\n", o.ExtensionsFile); err != nil {
325333 return "", err
326334 }
327335 }
88 libgobuster.HTTPOptions
99 Extensions string
1010 ExtensionsParsed libgobuster.Set[string]
11 ExtensionsFile string
1112 StatusCodes string
1213 StatusCodesParsed libgobuster.Set[int]
1314 StatusCodesBlacklist string
1212 "github.com/OJ/gobuster/v3/libgobuster"
1313 )
1414
15 const FuzzKeyword = "FUZZ"
16
1517 // ErrWildcard is returned if a wildcard response is found
1618 type ErrWildcard struct {
1719 url string
5254 NoTLSValidation: opts.NoTLSValidation,
5355 RetryOnTimeout: opts.RetryOnTimeout,
5456 RetryAttempts: opts.RetryAttempts,
57 TLSCertificate: opts.TLSCertificate,
5558 }
5659
5760 httpOpts := libgobuster.HTTPOptions{
58 BasicHTTPOptions: basicOptions,
59 FollowRedirect: opts.FollowRedirect,
60 Username: opts.Username,
61 Password: opts.Password,
62 Headers: opts.Headers,
63 Cookies: opts.Cookies,
64 Method: opts.Method,
61 BasicHTTPOptions: basicOptions,
62 FollowRedirect: opts.FollowRedirect,
63 Username: opts.Username,
64 Password: opts.Password,
65 Headers: opts.Headers,
66 NoCanonicalizeHeaders: opts.NoCanonicalizeHeaders,
67 Cookies: opts.Cookies,
68 Method: opts.Method,
6569 }
6670
6771 h, err := libgobuster.NewHTTPClient(&httpOpts)
8488
8589 // ProcessWord is the process implementation of gobusterfuzz
8690 func (d *GobusterFuzz) ProcessWord(ctx context.Context, word string, progress *libgobuster.Progress) error {
87 url := strings.ReplaceAll(d.options.URL, "FUZZ", word)
91 url := strings.ReplaceAll(d.options.URL, FuzzKeyword, word)
92
93 requestOptions := libgobuster.RequestOptions{}
94
95 if len(d.options.Headers) > 0 {
96 requestOptions.ModifiedHeaders = make([]libgobuster.HTTPHeader, len(d.options.Headers))
97 for i := range d.options.Headers {
98 requestOptions.ModifiedHeaders[i] = libgobuster.HTTPHeader{
99 Name: strings.ReplaceAll(d.options.Headers[i].Name, FuzzKeyword, word),
100 Value: strings.ReplaceAll(d.options.Headers[i].Value, FuzzKeyword, word),
101 }
102 }
103 }
104
105 if d.options.RequestBody != "" {
106 data := strings.ReplaceAll(d.options.RequestBody, FuzzKeyword, word)
107 buffer := strings.NewReader(data)
108 requestOptions.Body = buffer
109 }
110
111 // fuzzing of basic auth
112 if strings.Contains(d.options.Username, FuzzKeyword) || strings.Contains(d.options.Password, FuzzKeyword) {
113 requestOptions.UpdatedBasicAuthUsername = strings.ReplaceAll(d.options.Username, FuzzKeyword, word)
114 requestOptions.UpdatedBasicAuthPassword = strings.ReplaceAll(d.options.Password, FuzzKeyword, word)
115 }
88116
89117 tries := 1
90118 if d.options.RetryOnTimeout && d.options.RetryAttempts > 0 {
96124 var size int64
97125 for i := 1; i <= tries; i++ {
98126 var err error
99 statusCode, size, _, _, err = d.http.Request(ctx, url, libgobuster.RequestOptions{})
127 statusCode, size, _, _, err = d.http.Request(ctx, url, requestOptions)
100128 if err != nil {
101129 // check if it's a timeout and if we should try again and try again
102130 // otherwise the timeout error is raised
99 ExcludedStatusCodes string
1010 ExcludedStatusCodesParsed libgobuster.Set[int]
1111 ExcludeLength []int
12 RequestBody string
1213 }
1314
1415 // NewOptionsFuzz returns a new initialized OptionsFuzz
4444 NoTLSValidation: opts.NoTLSValidation,
4545 RetryOnTimeout: opts.RetryOnTimeout,
4646 RetryAttempts: opts.RetryAttempts,
47 TLSCertificate: opts.TLSCertificate,
4748 }
4849
4950 httpOpts := libgobuster.HTTPOptions{
4444 NoTLSValidation: opts.NoTLSValidation,
4545 RetryOnTimeout: opts.RetryOnTimeout,
4646 RetryAttempts: opts.RetryAttempts,
47 TLSCertificate: opts.TLSCertificate,
4748 }
4849
4950 httpOpts := libgobuster.HTTPOptions{
4747 NoTLSValidation: opts.NoTLSValidation,
4848 RetryOnTimeout: opts.RetryOnTimeout,
4949 RetryAttempts: opts.RetryAttempts,
50 TLSCertificate: opts.TLSCertificate,
5051 }
5152
5253 httpOpts := libgobuster.HTTPOptions{
53 BasicHTTPOptions: basicOptions,
54 FollowRedirect: opts.FollowRedirect,
55 Username: opts.Username,
56 Password: opts.Password,
57 Headers: opts.Headers,
58 Cookies: opts.Cookies,
59 Method: opts.Method,
54 BasicHTTPOptions: basicOptions,
55 FollowRedirect: opts.FollowRedirect,
56 Username: opts.Username,
57 Password: opts.Password,
58 Headers: opts.Headers,
59 NoCanonicalizeHeaders: opts.NoCanonicalizeHeaders,
60 Cookies: opts.Cookies,
61 Method: opts.Method,
6062 }
6163
6264 h, err := libgobuster.NewHTTPClient(&httpOpts)
1010 ExcludeLength []int
1111 Domain string
1212 }
13
14 // NewOptionsVhost returns a new initialized OptionsVhost
15 func NewOptionsVhost() *OptionsVhost {
16 return &OptionsVhost{}
17 }
00 package helper
11
22 import (
3 "bufio"
34 "fmt"
5 "os"
46 "strconv"
57 "strings"
68
2022 // remove leading . from extensions
2123 ret.Add(strings.TrimPrefix(e, "."))
2224 }
25 return ret, nil
26 }
27
28 func ParseExtensionsFile(file string) ([]string, error) {
29 var ret []string
30
31 stream, err := os.Open(file)
32 if err != nil {
33 return ret, err
34 }
35 defer stream.Close()
36
37 scanner := bufio.NewScanner(stream)
38 for scanner.Scan() {
39 e := scanner.Text()
40 e = strings.TrimSpace(e)
41 // remove leading . from extensions
42 ret = append(ret, (strings.TrimPrefix(e, ".")))
43 }
44
45 if err := scanner.Err(); err != nil {
46 return nil, err
47 }
48
2349 return ret, nil
2450 }
2551
1818
1919 // HTTPClient represents a http object
2020 type HTTPClient struct {
21 client *http.Client
22 userAgent string
23 defaultUserAgent string
24 username string
25 password string
26 headers []HTTPHeader
27 cookies string
28 method string
29 host string
21 client *http.Client
22 userAgent string
23 defaultUserAgent string
24 username string
25 password string
26 headers []HTTPHeader
27 noCanonicalizeHeaders bool
28 cookies string
29 method string
30 host string
3031 }
3132
3233 // RequestOptions is used to pass options to a single individual request
3334 type RequestOptions struct {
34 Host string
35 Body io.Reader
36 ReturnBody bool
35 Host string
36 Body io.Reader
37 ReturnBody bool
38 ModifiedHeaders []HTTPHeader
39 UpdatedBasicAuthUsername string
40 UpdatedBasicAuthPassword string
3741 }
3842
3943 // NewHTTPClient returns a new HTTPClient
6165 }
6266 } else {
6367 redirectFunc = nil
68 }
69
70 tlsConfig := tls.Config{
71 InsecureSkipVerify: opt.NoTLSValidation,
72 }
73 if opt.TLSCertificate != nil {
74 tlsConfig.Certificates = []tls.Certificate{*opt.TLSCertificate}
6475 }
6576
6677 client.client = &http.Client{
7081 Proxy: proxyURLFunc,
7182 MaxIdleConns: 100,
7283 MaxIdleConnsPerHost: 100,
73 TLSClientConfig: &tls.Config{
74 InsecureSkipVerify: opt.NoTLSValidation,
75 },
84 TLSClientConfig: &tlsConfig,
7685 }}
7786 client.username = opt.Username
7887 client.password = opt.Password
7988 client.userAgent = opt.UserAgent
8089 client.defaultUserAgent = DefaultUserAgent()
8190 client.headers = opt.Headers
91 client.noCanonicalizeHeaders = opt.NoCanonicalizeHeaders
8292 client.cookies = opt.Cookies
8393 client.method = opt.Method
8494 if client.method == "" {
97107 // Request makes an http request and returns the status, the content length, the headers, the body and an error
98108 // if you want the body returned set the corresponding property inside RequestOptions
99109 func (client *HTTPClient) Request(ctx context.Context, fullURL string, opts RequestOptions) (int, int64, http.Header, []byte, error) {
100 resp, err := client.makeRequest(ctx, fullURL, opts.Host, opts.Body)
110 resp, err := client.makeRequest(ctx, fullURL, opts)
101111 if err != nil {
102112 // ignore context canceled errors
103113 if errors.Is(ctx.Err(), context.Canceled) {
127137 return resp.StatusCode, length, resp.Header, body, nil
128138 }
129139
130 func (client *HTTPClient) makeRequest(ctx context.Context, fullURL, host string, data io.Reader) (*http.Response, error) {
131 req, err := http.NewRequest(client.method, fullURL, data)
140 func (client *HTTPClient) makeRequest(ctx context.Context, fullURL string, opts RequestOptions) (*http.Response, error) {
141 req, err := http.NewRequest(client.method, fullURL, opts.Body)
132142 if err != nil {
133143 return nil, err
134144 }
141151 }
142152
143153 // Use host for VHOST mode on a per request basis, otherwise the one provided from headers
144 if host != "" {
145 req.Host = host
154 if opts.Host != "" {
155 req.Host = opts.Host
146156 } else if client.host != "" {
147157 req.Host = client.host
148158 }
154164 }
155165
156166 // add custom headers
157 for _, h := range client.headers {
158 req.Header.Set(h.Name, h.Value)
159 }
160
161 if client.username != "" {
167 // if ModifiedHeaders are supplied use those, otherwise use the original ones
168 // currently only relevant on fuzzing
169 if len(opts.ModifiedHeaders) > 0 {
170 for _, h := range opts.ModifiedHeaders {
171 if client.noCanonicalizeHeaders {
172 // https://stackoverflow.com/questions/26351716/how-to-keep-key-case-sensitive-in-request-header-using-golang
173 req.Header[h.Name] = []string{h.Value}
174 } else {
175 req.Header.Set(h.Name, h.Value)
176 }
177 }
178 } else {
179 for _, h := range client.headers {
180 if client.noCanonicalizeHeaders {
181 // https://stackoverflow.com/questions/26351716/how-to-keep-key-case-sensitive-in-request-header-using-golang
182 req.Header[h.Name] = []string{h.Value}
183 } else {
184 req.Header.Set(h.Name, h.Value)
185 }
186 }
187 }
188
189 if opts.UpdatedBasicAuthUsername != "" {
190 req.SetBasicAuth(opts.UpdatedBasicAuthUsername, opts.UpdatedBasicAuthPassword)
191 } else if client.username != "" {
162192 req.SetBasicAuth(client.username, client.password)
163193 }
164194
174174 }
175175 close(wordChan)
176176 workerGroup.Wait()
177
178 if err := scanner.Err(); err != nil {
179 return err
180 }
181
177182 return nil
178183 }
179184
00 package libgobuster
11
22 import (
3 "crypto/tls"
34 "time"
45 )
56
1112 Timeout time.Duration
1213 RetryOnTimeout bool
1314 RetryAttempts int
15 TLSCertificate *tls.Certificate
1416 }
1517
1618 // HTTPOptions is the struct to pass in all http options to Gobuster
1719 type HTTPOptions struct {
1820 BasicHTTPOptions
19 Password string
20 URL string
21 Username string
22 Cookies string
23 Headers []HTTPHeader
24 FollowRedirect bool
25 Method string
21 Password string
22 URL string
23 Username string
24 Cookies string
25 Headers []HTTPHeader
26 NoCanonicalizeHeaders bool
27 FollowRedirect bool
28 Method string
2629 }
11
22 const (
33 // VERSION contains the current gobuster version
4 VERSION = "3.2.0-dev"
4 VERSION = "3.3"
55 )