Skip to content

Commit

Permalink
Release version 1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
OJ committed Mar 1, 2017
2 parents 7ccd130 + 2c3a57c commit 7a6d1c0
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 23 deletions.
29 changes: 16 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Gobuster v1.2 (OJ Reeves @TheColonial)
Gobuster v1.3 (OJ Reeves @TheColonial)
======================================

Gobuster is a tool used to brute-force:
Expand Down Expand Up @@ -29,6 +29,7 @@ Yes, you're probably correct. Feel free to:

### Common Command line options

* `-fw` - Force processing of a domain with wildcard results.
* `-m <mode>` - which mode to use, either `dir` or `dns` (default: `dir`)
* `-q` - disables banner/underline output.
* `-t <threads>` - number of threads to run (default: `10`).
Expand All @@ -38,18 +39,20 @@ Yes, you're probably correct. Feel free to:

### Command line options for `dns` mode

* `-fw` - Force processing of a domain with wildcard DNS.
* `-cn` - show CNAME records (cannot be used with '-i' option).
* `-i` - show all IP addresses for the result.

### Command line options for `dir` mode

* `-a <user agent string>` - specify a user agent string to send in the request header
* `-a <user agent string>` - specify a user agent string to send in the request header.
* `-c <http cookies>` - use this to specify any cookies that you might need (simulating auth).
* `-e` - specify extended mode that renders the full URL.
* `-f` - append `/` for directory brute forces.
* `-k` - Skip verification of SSL certificates.
* `-l` - show the length of the response.
* `-n` - "no status" mode, disables the output of the result's status code.
* `-p <proxy url>` - specify a proxy to use for all requests (scheme much match the URL scheme)
* `-o <file>` - specify a file name to write the output to.
* `-p <proxy url>` - specify a proxy to use for all requests (scheme much match the URL scheme).
* `-r` - follow redirects.
* `-s <status codes>` - comma-separated set of the list of status codes to be deemed a "positive" (default: `200,204,301,302,307`).
* `-x <extensions>` - list of extensions to check for, if any.
Expand Down Expand Up @@ -94,7 +97,7 @@ Default options looks like this:
```
$ gobuster -u http://buffered.io/ -w words.txt
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://buffered.io/
Expand All @@ -111,7 +114,7 @@ Default options with status codes disabled looks like this:
```
$ gobuster -u http://buffered.io/ -w words.txt -n
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://buffered.io/
Expand All @@ -129,7 +132,7 @@ Verbose output looks like this:
```
$ gobuster -u http://buffered.io/ -w words.txt -v
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://buffered.io/
Expand All @@ -148,7 +151,7 @@ Example showing content length:
```
$ gobuster -u http://buffered.io/ -w words.txt -l
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://buffered.io/
Expand Down Expand Up @@ -180,7 +183,7 @@ Normal sample run goes like this:
```
$ gobuster -m dns -w subdomains.txt -u google.com
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dns
[+] Url/Domain : google.com
Expand Down Expand Up @@ -211,7 +214,7 @@ Show IP sample run goes like this:
```
$ gobuster -m dns -w subdomains.txt -u google.com -i
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dns
[+] Url/Domain : google.com
Expand Down Expand Up @@ -243,7 +246,7 @@ Base domain validation warning when the base domain fails to resolve. This is a
```
$ gobuster -m dns -w subdomains.txt -u yp.to -i
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dns
[+] Url/Domain : yp.to
Expand All @@ -258,7 +261,7 @@ Wildcard DNS is also detected properly:
```
$ gobuster -w subdomainsbig.txt -u doesntexist.com -m dns
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dns
[+] Url/Domain : doesntexist.com
Expand All @@ -273,7 +276,7 @@ If the user wants to force processing of a domain that has wildcard entries, use
```
$ gobuster -w subdomainsbig.txt -u doesntexist.com -m dns -fw
Gobuster v1.2 OJ Reeves (@TheColonial)
Gobuster v1.3 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dns
[+] Url/Domain : doesntexist.com
Expand Down
3 changes: 3 additions & 0 deletions THANKS
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
@0x42424242 - initial DNS support
@averagesecurityguy - quiet mode support
@g0tmi1k - content length, wordlist and command line parsing fixes
@gehaxelt - DIR mode UUID wildcard detection
@justinsteven - HTTP basic auth support
@kevinnz - custom user agent support
@knapsy - saving output to file, and CNAME resolution for DNS mode
@rverton - CLI flag to skip SSL verification
@viaMorgoth - base domain validation for DNS mode
@UID1K - initial DNS wildcard check support
@Ne0nd0g - STDIN support for wordlists
106 changes: 96 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"net/url"
"os"
"os/signal"
"regexp"
"strconv"
"strings"
"sync"
Expand Down Expand Up @@ -77,6 +78,7 @@ type State struct {
Quiet bool
Setup SetupFunc
ShowIPs bool
ShowCNAME bool
StatusCodes IntSet
Threads int
Url string
Expand All @@ -85,12 +87,15 @@ type State struct {
Username string
Verbose bool
Wordlist string
OutputFileName string
OutputFile *os.File
IsWildcard bool
WildcardForced bool
WildcardIps StringSet
SignalChan chan os.Signal
Terminate bool
StdIn bool
InsecureSSL bool
}

type RedirectHandler struct {
Expand Down Expand Up @@ -187,6 +192,11 @@ func MakeRequest(s *State, fullUrl, cookie string) (*int, *int64) {

if err != nil {
if ue, ok := err.(*url.Error); ok {

if strings.HasPrefix(ue.Err.Error(), "x509") {
fmt.Println("[-] Invalid certificate")
}

if re, ok := ue.Err.(*RedirectError); ok {
return &re.StatusCode, nil
}
Expand Down Expand Up @@ -239,6 +249,7 @@ func ParseCmdLine() *State {
flag.StringVar(&s.Mode, "m", "dir", "Directory/File mode (dir) or DNS mode (dns)")
flag.StringVar(&s.Wordlist, "w", "", "Path to the wordlist")
flag.StringVar(&codes, "s", "200,204,301,302,307", "Positive status codes (dir mode only)")
flag.StringVar(&s.OutputFileName, "o", "", "Output file to write results to (defaults to stdout)")
flag.StringVar(&s.Url, "u", "", "The target URL or Domain")
flag.StringVar(&s.Cookies, "c", "", "Cookies to use for the requests (dir mode only)")
flag.StringVar(&s.Username, "U", "", "Username for Basic Auth (dir mode only)")
Expand All @@ -248,13 +259,15 @@ func ParseCmdLine() *State {
flag.StringVar(&proxy, "p", "", "Proxy to use for requests [http(s)://host:port] (dir mode only)")
flag.BoolVar(&s.Verbose, "v", false, "Verbose output (errors)")
flag.BoolVar(&s.ShowIPs, "i", false, "Show IP addresses (dns mode only)")
flag.BoolVar(&s.ShowCNAME, "cn", false, "Show CNAME records (dns mode only, cannot be used with '-i' option)")
flag.BoolVar(&s.FollowRedirect, "r", false, "Follow redirects")
flag.BoolVar(&s.Quiet, "q", false, "Don't print the banner and other noise")
flag.BoolVar(&s.Expanded, "e", false, "Expanded mode, print full URLs")
flag.BoolVar(&s.NoStatus, "n", false, "Don't print status codes")
flag.BoolVar(&s.IncludeLength, "l", false, "Include the length of the body in the output (dir mode only)")
flag.BoolVar(&s.UseSlash, "f", false, "Append a forward-slash to each directory request (dir mode only)")
flag.BoolVar(&s.WildcardForced, "fw", false, "Force continued operation when wildcard found (dns mode only)")
flag.BoolVar(&s.WildcardForced, "fw", false, "Force continued operation when wildcard found")
flag.BoolVar(&s.InsecureSSL, "k", false, "Skip SSL certificate verification")

flag.Parse()

Expand Down Expand Up @@ -310,7 +323,24 @@ func ParseCmdLine() *State {
}

if strings.HasPrefix(s.Url, "http") == false {
s.Url = "http://" + s.Url
// check to see if a port was specified
re := regexp.MustCompile(`^[^/]+:(\d+)`)
match := re.FindStringSubmatch(s.Url)

if len(match) < 2 {
// no port, default to http on 80
s.Url = "http://" + s.Url
} else {
port, err := strconv.Atoi(match[1])
if err != nil || (port != 80 && port != 443) {
fmt.Println("[!] Url/Domain (-u): Scheme not specified.")
valid = false
} else if port == 80 {
s.Url = "http://" + s.Url
} else {
s.Url = "https://" + s.Url
}
}
}

// extensions are comma separated
Expand Down Expand Up @@ -372,7 +402,7 @@ func ParseCmdLine() *State {
Transport: &http.Transport{
Proxy: proxyUrlFunc,
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
InsecureSkipVerify: s.InsecureSSL,
},
},
}}
Expand Down Expand Up @@ -466,6 +496,18 @@ func Process(s *State) {
scanner = bufio.NewScanner(wordlist)
}

var outputFile *os.File
if s.OutputFileName != "" {
outputFile, err := os.Create(s.OutputFileName)
if err != nil {
fmt.Printf("[!] Unable to write to %s, falling back to stdout.\n", s.OutputFileName)
s.OutputFileName = ""
s.OutputFile = nil
} else {
s.OutputFile = outputFile
}
}

for scanner.Scan() {
if s.Terminate {
break
Expand All @@ -482,6 +524,9 @@ func Process(s *State) {
processorGroup.Wait()
close(resultChan)
printerGroup.Wait()
if s.OutputFile != nil {
outputFile.Close()
}
Ruler(s)
}

Expand Down Expand Up @@ -512,6 +557,18 @@ func SetupDns(s *State) bool {
}

func SetupDir(s *State) bool {
guid := uuid.NewV4()
wildcardResp, _ := GoGet(s, s.Url, fmt.Sprintf("%s", guid), s.Cookies)

if s.StatusCodes.Contains(*wildcardResp) {
s.IsWildcard = true
fmt.Println("[-] Wildcard response found:", fmt.Sprintf("%s%s", s.Url, guid), "=>", *wildcardResp)
if !s.WildcardForced {
fmt.Println("[-] To force processing of Wildcard responses, specify the '-fw' switch.")
}
return s.WildcardForced
}

return true
}

Expand All @@ -526,6 +583,11 @@ func ProcessDnsEntry(s *State, word string, resultChan chan<- Result) {
}
if s.ShowIPs {
result.Extra = strings.Join(ips, ", ")
} else if s.ShowCNAME {
cname, err := net.LookupCNAME(subdomain)
if err == nil {
result.Extra = cname
}
}
resultChan <- result
}
Expand Down Expand Up @@ -570,12 +632,20 @@ func ProcessDirEntry(s *State, word string, resultChan chan<- Result) {
}

func PrintDnsResult(s *State, r *Result) {
output := ""
if r.Status == 404 {
fmt.Printf("Missing: %s\n", r.Entity)
output = fmt.Sprintf("Missing: %s\n", r.Entity)
} else if s.ShowIPs {
fmt.Printf("Found: %s [%s]\n", r.Entity, r.Extra)
output = fmt.Sprintf("Found: %s [%s]\n", r.Entity, r.Extra)
} else if s.ShowCNAME {
output = fmt.Sprintf("Found: %s [%s]\n", r.Entity, r.Extra)
} else {
fmt.Printf("Found: %s\n", r.Entity)
output = fmt.Sprintf("Found: %s\n", r.Entity)
}
fmt.Printf("%s", output)

if s.OutputFile != nil {
WriteToFile(output, s)
}
}

Expand All @@ -585,9 +655,9 @@ func PrintDirResult(s *State, r *Result) {
// Prefix if we're in verbose mode
if s.Verbose {
if s.StatusCodes.Contains(r.Status) {
output += "Found : "
output = "Found : "
} else {
output += "Missed: "
output = "Missed: "
}
}

Expand All @@ -606,8 +676,20 @@ func PrintDirResult(s *State, r *Result) {
if r.Size != nil {
output += fmt.Sprintf(" [Size: %d]", *r.Size)
}
output += "\n"

fmt.Println(output)
fmt.Printf(output)

if s.OutputFile != nil {
WriteToFile(output, s)
}
}
}

func WriteToFile(output string, s *State) {
_, err := s.OutputFile.WriteString(output)
if err != nil {
panic("[!] Unable to write to file " + s.OutputFileName)
}
}

Expand Down Expand Up @@ -660,7 +742,7 @@ func Banner(state *State) {
}

fmt.Println("")
fmt.Println("Gobuster v1.2 OJ Reeves (@TheColonial)")
fmt.Println("Gobuster v1.3 OJ Reeves (@TheColonial)")
Ruler(state)
}

Expand All @@ -680,6 +762,10 @@ func ShowConfig(state *State) {
}
fmt.Printf("[+] Wordlist : %s\n", wordlist)

if state.OutputFileName != "" {
fmt.Printf("[+] Output file : %s\n", state.OutputFileName)
}

if state.Mode == "dir" {
fmt.Printf("[+] Status codes : %s\n", state.StatusCodes.Stringify())

Expand Down

0 comments on commit 7a6d1c0

Please sign in to comment.