mirror of
https://github.com/OJ/gobuster.git
synced 2024-09-25 01:10:42 +02:00
parent
5e51b3fb49
commit
44d4693c6e
@ -13,6 +13,7 @@ linters:
|
|||||||
- godot
|
- godot
|
||||||
- goerr113
|
- goerr113
|
||||||
- gofumpt
|
- gofumpt
|
||||||
|
- exhaustivestruct
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
@ -25,8 +26,9 @@ func runDir(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := cli.Gobuster(mainContext, globalopts, plugin); err != nil {
|
if err := cli.Gobuster(mainContext, globalopts, plugin); err != nil {
|
||||||
if goberr, ok := err.(*gobusterdir.ErrWildcard); ok {
|
var wErr *gobusterdir.ErrWildcard
|
||||||
return fmt.Errorf("%s. To continue please exclude the status code, the length or use the --wildcard switch", goberr.Error())
|
if errors.As(err, &wErr) {
|
||||||
|
return fmt.Errorf("%w. To continue please exclude the status code, the length or use the --wildcard switch", wErr)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("error on running gobuster: %w", err)
|
return fmt.Errorf("error on running gobuster: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,11 @@ func parseBasicHTTPOptions(cmd *cobra.Command) (libgobuster.BasicHTTPOptions, er
|
|||||||
return options, fmt.Errorf("invalid value for random-agent: %w", err)
|
return options, fmt.Errorf("invalid value for random-agent: %w", err)
|
||||||
}
|
}
|
||||||
if randomUA {
|
if randomUA {
|
||||||
options.UserAgent = helper.GetRandomUserAgent()
|
ua, err := helper.GetRandomUserAgent()
|
||||||
|
if err != nil {
|
||||||
|
return options, err
|
||||||
|
}
|
||||||
|
options.UserAgent = ua
|
||||||
}
|
}
|
||||||
|
|
||||||
options.Proxy, err = cmd.Flags().GetString("proxy")
|
options.Proxy, err = cmd.Flags().GetString("proxy")
|
||||||
|
7
go.mod
7
go.mod
@ -1,10 +1,11 @@
|
|||||||
module github.com/OJ/gobuster/v3
|
module github.com/OJ/gobuster/v3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.1.2
|
github.com/google/uuid v1.1.4
|
||||||
github.com/spf13/cobra v1.1.1
|
github.com/spf13/cobra v1.1.1
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
|
||||||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13 // indirect
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad // indirect
|
||||||
|
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
go 1.15
|
go 1.15
|
||||||
|
18
go.sum
18
go.sum
@ -62,8 +62,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
|
|||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
github.com/google/uuid v1.1.4 h1:0ecGp3skIrHWPNGPJDaBIghfA6Sp7Ruo2Io8eLKzWm0=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.4/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
@ -178,8 +178,8 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@ -234,8 +234,14 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13 h1:5jaG59Zhd+8ZXe8C+lgiAGqkOaZBruqrWclLkgAww34=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad h1:MCsdmFSdEd4UEa5TKS5JztCRHK/WtvNei1edOj5RSRo=
|
||||||
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM=
|
||||||
|
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||||
|
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
|
||||||
|
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package helper
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"crypto/rand"
|
||||||
"time"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
var userAgents = [...]string{
|
var userAgents = [...]string{
|
||||||
@ -4666,7 +4666,10 @@ var userAgents = [...]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetRandomUserAgent picks a random user agent from a predefined list
|
// GetRandomUserAgent picks a random user agent from a predefined list
|
||||||
func GetRandomUserAgent() string {
|
func GetRandomUserAgent() (string, error) {
|
||||||
rand.Seed(time.Now().Unix())
|
n, err := rand.Int(rand.Reader, big.NewInt(int64(len(userAgents))))
|
||||||
return userAgents[rand.Intn(len(userAgents))]
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return userAgents[n.Int64()], err
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package libgobuster
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
@ -116,7 +117,7 @@ func lineCounter(r io.Reader) (int, error) {
|
|||||||
count += bytes.Count(buf[:c], lineSep)
|
count += bytes.Count(buf[:c], lineSep)
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case err == io.EOF:
|
case errors.Is(err, io.EOF):
|
||||||
return count, nil
|
return count, nil
|
||||||
|
|
||||||
case err != nil:
|
case err != nil:
|
||||||
|
@ -29,6 +29,7 @@ type HTTPClient struct {
|
|||||||
headers []HTTPHeader
|
headers []HTTPHeader
|
||||||
cookies string
|
cookies string
|
||||||
method string
|
method string
|
||||||
|
host string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestOptions is used to pass options to a single individual request
|
// RequestOptions is used to pass options to a single individual request
|
||||||
@ -87,6 +88,13 @@ func NewHTTPClient(c context.Context, opt *HTTPOptions) (*HTTPClient, error) {
|
|||||||
if client.method == "" {
|
if client.method == "" {
|
||||||
client.method = http.MethodGet
|
client.method = http.MethodGet
|
||||||
}
|
}
|
||||||
|
// Host header needs to be set separately
|
||||||
|
for _, h := range opt.Headers {
|
||||||
|
if h.Name == "Host" {
|
||||||
|
client.host = h.Value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
return &client, nil
|
return &client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +144,11 @@ func (client *HTTPClient) makeRequest(fullURL, host string, data io.Reader) (*ht
|
|||||||
req.Header.Set("Cookie", client.cookies)
|
req.Header.Set("Cookie", client.cookies)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use host for VHOST mode on a per request basis, otherwise the one provided from headers
|
||||||
if host != "" {
|
if host != "" {
|
||||||
req.Host = host
|
req.Host = host
|
||||||
|
} else if client.host != "" {
|
||||||
|
req.Host = client.host
|
||||||
}
|
}
|
||||||
|
|
||||||
if client.userAgent != "" {
|
if client.userAgent != "" {
|
||||||
|
@ -3,8 +3,9 @@ package libgobuster
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
@ -26,19 +27,26 @@ func httpServerT(t *testing.T, content string) *httptest.Server {
|
|||||||
return ts
|
return ts
|
||||||
}
|
}
|
||||||
|
|
||||||
func randomString(length int) string {
|
func randomString(length int) (string, error) {
|
||||||
var letter = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
var letter = []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
letterLen := len(letter)
|
letterLen := len(letter)
|
||||||
|
|
||||||
b := make([]byte, length)
|
b := make([]byte, length)
|
||||||
for i := range b {
|
for i := range b {
|
||||||
b[i] = letter[rand.Intn(letterLen)]
|
n, err := rand.Int(rand.Reader, big.NewInt(int64(letterLen)))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
return string(b)
|
b[i] = letter[n.Int64()]
|
||||||
|
}
|
||||||
|
return string(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRequest(t *testing.T) {
|
func TestRequest(t *testing.T) {
|
||||||
ret := randomString(100)
|
ret, err := randomString(100)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
h := httpServerT(t, ret)
|
h := httpServerT(t, ret)
|
||||||
defer h.Close()
|
defer h.Close()
|
||||||
var o HTTPOptions
|
var o HTTPOptions
|
||||||
@ -62,7 +70,11 @@ func TestRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkRequestWithoutBody(b *testing.B) {
|
func BenchmarkRequestWithoutBody(b *testing.B) {
|
||||||
h := httpServerB(b, randomString(10000))
|
r, err := randomString(10000)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
h := httpServerB(b, r)
|
||||||
defer h.Close()
|
defer h.Close()
|
||||||
var o HTTPOptions
|
var o HTTPOptions
|
||||||
c, err := NewHTTPClient(context.Background(), &o)
|
c, err := NewHTTPClient(context.Background(), &o)
|
||||||
@ -78,7 +90,11 @@ func BenchmarkRequestWithoutBody(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkRequestWitBody(b *testing.B) {
|
func BenchmarkRequestWitBody(b *testing.B) {
|
||||||
h := httpServerB(b, randomString(10000))
|
r, err := randomString(10000)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
h := httpServerB(b, r)
|
||||||
defer h.Close()
|
defer h.Close()
|
||||||
var o HTTPOptions
|
var o HTTPOptions
|
||||||
c, err := NewHTTPClient(context.Background(), &o)
|
c, err := NewHTTPClient(context.Background(), &o)
|
||||||
@ -94,7 +110,11 @@ func BenchmarkRequestWitBody(b *testing.B) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkNewHTTPClient(b *testing.B) {
|
func BenchmarkNewHTTPClient(b *testing.B) {
|
||||||
h := httpServerB(b, randomString(500))
|
r, err := randomString(500)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
h := httpServerB(b, r)
|
||||||
defer h.Close()
|
defer h.Close()
|
||||||
var o HTTPOptions
|
var o HTTPOptions
|
||||||
for x := 0; x < b.N; x++ {
|
for x := 0; x < b.N; x++ {
|
||||||
|
Loading…
Reference in New Issue
Block a user