Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ gobuster dir -u https://example.com -w wordlist.txt -l

# Filter by status codes
gobuster dir -u https://example.com -w wordlist.txt -s 200,301,302

# Apply replacement patterns to each word before requesting it
gobuster dir -u https://example.com -w wordlist.txt -p patterns.txt

# Generate follow-up values from successful matches
gobuster dir -u https://example.com -w wordlist.txt --discover-pattern discover-patterns.txt

# Resume a scan from a later offset in the wordlist
gobuster dir -u https://example.com -w wordlist.txt --wordlist-offset 500
```

#### 🔍 DNS Mode (`dns`)
Expand Down
2 changes: 1 addition & 1 deletion cli/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func ParseGlobalOptions(c *cli.Context) (libgobuster.Options, error) {
if opts.Wordlist == "-" && opts.WordlistOffset > 0 {
return opts, errors.New("wordlist-offset is not supported when reading from STDIN")
} else if opts.WordlistOffset < 0 {
return opts, errors.New("wordlist-offset must be bigger or equal to 0")
return opts, errors.New("wordlist-offset must be greater than or equal to 0")
}

opts.OutputFilename = c.String("output")
Expand Down
32 changes: 17 additions & 15 deletions libgobuster/libgobuster.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,21 +280,23 @@ ListenForMore:
case <-ctx.Done():
break ListenForMore
case successGuess := <-successChan:
// Add more guesses based on the results of previous attempts
if successGuess.discoverOnSuccess {
discoverWords := g.plugin.AdditionalSuccessWords(successGuess.word)
if len(discoverWords) > 0 {
g.Progress.IncrementTotalRequests(len(discoverWords))
feederGroup.Add(1)
go g.feeder(feederCtx, guessChan, discoverWords, false, &feederGroup)
}

patternDiscoverWords := g.processDiscoverPatterns(successGuess.word)
if len(patternDiscoverWords) > 0 {
g.Progress.IncrementTotalRequests(len(patternDiscoverWords))
feederGroup.Add(1)
go g.feeder(feederCtx, guessChan, patternDiscoverWords, false, &feederGroup)
}
// Call the success callback for every successful result so generated
// recursive targets are still processed even when the originating guess
// was created with discoverOnSuccess disabled.
discoverWords := g.plugin.AdditionalSuccessWords(successGuess.word)
patternDiscoverWords := g.processDiscoverPatterns(successGuess.word)
if !successGuess.discoverOnSuccess {
break
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 4bd5cbf: the discoverOnSuccess guard now precedes both discovery callbacks.

if len(discoverWords) > 0 {
g.Progress.IncrementTotalRequests(len(discoverWords))
feederGroup.Add(1)
go g.feeder(feederCtx, guessChan, discoverWords, false, &feederGroup)
}
if len(patternDiscoverWords) > 0 {
g.Progress.IncrementTotalRequests(len(patternDiscoverWords))
feederGroup.Add(1)
go g.feeder(feederCtx, guessChan, patternDiscoverWords, false, &feederGroup)
}
case <-time.After(200 * time.Millisecond):
// With requests issued only after the results are synchronously
Expand Down
Loading