Skip to content

Commit

Permalink
add whitelist option
Browse files Browse the repository at this point in the history
  • Loading branch information
C-Sto committed Jan 19, 2019
1 parent 1af0e7b commit 4edd18b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 15 deletions.
47 changes: 46 additions & 1 deletion librecursebuster/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ func TestWeirdWords(t *testing.T) {
t.Parallel()
finished := make(chan struct{})
cfg := getDefaultConfig()
gState, urlSlice := preSetupTest(cfg, "2020", finished, t)
gState, urlSlice := preSetupTest(cfg, "2021", finished, t)
//add some woderful and weird things to the wordlist
for i := 0; i < 256; i++ {
gState.WordList = append(gState.WordList, "te"+string(i)+"st")
Expand All @@ -502,6 +502,51 @@ func TestWeirdWords(t *testing.T) {
}
}

func TestGoodCodes(t *testing.T) {
t.Parallel()
finished := make(chan struct{})
cfg := getDefaultConfig()
cfg.GoodResponses = "500"
gState, urlSlice := preSetupTest(cfg, "2022", finished, t)
found := postSetupTest(urlSlice, gState)
gState.Wait()

tested := []string{}
ok := []string{
"/c", "/c/",
}
for _, i := range ok {
tested = append(tested, i)
if x, ok := found[i]; !ok || x == nil {
t.Error("Did not find " + i)
}
}

//check for values that should not have been found
for k := range found {
if strings.Contains(k, "z") {
t.Error("Found (but should not have) " + k)
}
}

if x, ok := found["/a/x"]; ok && x != nil {
t.Error("Found (but should not have) /a/x")
}

if x, ok := found["/a"]; ok && x != nil {
t.Error("Found (but should not have) /a")
}

if x, ok := found["/a/b"]; ok && x != nil {
t.Error("Found (but should not have) /a/b")
}

if x, ok := found["/b/y"]; ok && x != nil {
t.Error("Found (but should not have) /b/y")
}

}

func postSetupTest(urlSlice []string, gState *State) (found map[string]*http.Response) {
//start up the management goroutines
go gState.ManageRequests()
Expand Down
30 changes: 23 additions & 7 deletions librecursebuster/net.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,18 @@ func (gState *State) evaluateURL(method string, urlString string, client *http.C
}

//Check if we care about it (header only) section
if gState.BadResponses[headResp.StatusCode] {
success = false
//<-gState.Chans.workersChan
return headResp, content, success
if len(gState.GoodResponses) > 0 {
if v, ok := gState.GoodResponses[headResp.StatusCode]; !ok || !v {
success = false
//<-gState.Chans.workersChan
return headResp, content, success
}
} else {
if gState.BadResponses[headResp.StatusCode] {
success = false
//<-gState.Chans.workersChan
return headResp, content, success
}
}

//this is all we have to do if we aren't doing GET's
Expand Down Expand Up @@ -166,9 +174,17 @@ func (gState *State) evaluateURL(method string, urlString string, client *http.C
}

//Check if we care about it (response code only) section
if gState.BadResponses[headResp.StatusCode] {
success = false
return headResp, content, success
if len(gState.GoodResponses) > 0 {
if v, ok := gState.GoodResponses[headResp.StatusCode]; !ok || !v {
success = false
//<-gState.Chans.workersChan
return headResp, content, success
}
} else {
if gState.BadResponses[headResp.StatusCode] {
success = false
return headResp, content, success
}
}

//check for bad headers in the response
Expand Down
17 changes: 16 additions & 1 deletion librecursebuster/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ type State struct {
Blacklist map[string]bool
Whitelist map[string]bool
BadResponses map[int]bool //response codes to consider *dont care* (this might be worth putting in per host state, but idk how)
GoodResponses map[int]bool //response codes to consider *only care*
Extensions []string
Methods []string
// WordlistLen *uint32
Expand Down Expand Up @@ -186,6 +187,7 @@ func (s *State) AddWG() {
func (State) Init() *State {
s := &State{
BadResponses: make(map[int]bool),
GoodResponses: make(map[int]bool),
Whitelist: make(map[string]bool),
Blacklist: make(map[string]bool),
StopDir: make(chan struct{}, 1),
Expand Down Expand Up @@ -265,6 +267,7 @@ type Config struct {
AppendDir bool
Auth string
BadResponses string
GoodResponses string
BadHeader ArrayStringFlag
BodyContent string
BlacklistLocation string
Expand Down Expand Up @@ -353,12 +356,24 @@ func (s *State) SetupState() {
for _, x := range strings.Split(s.Cfg.BadResponses, ",") {
i, err := strconv.Atoi(x)
if err != nil {
fmt.Println("Bad error code supplied!")
fmt.Println("Bad response code supplied!")
panic(err)
}
s.BadResponses[i] = true //this is probably a candidate for individual urls. Unsure how to config that cleanly though
}

for _, x := range strings.Split(s.Cfg.GoodResponses, ",") {
if x == "" {
continue
}
i, err := strconv.Atoi(x)
if err != nil {
fmt.Println("Bad response code supplied!")
panic(err)
}
s.GoodResponses[i] = true
}

s.Client = s.ConfigureHTTPClient(false)
s.BurpClient = s.ConfigureHTTPClient(true)

Expand Down
13 changes: 7 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/fatih/color"
)

const version = "1.6.8"
const version = "1.6.9"

func main() {
if runtime.GOOS == "windows" { //lol goos
Expand All @@ -31,11 +31,12 @@ func main() {
globalState.Cfg.Version = version //**
totesTested := uint64(0)
globalState.TotalTested = &totesTested
flag.BoolVar(&globalState.Cfg.ShowAll, "all", false, "Show, and write the result of all checks") //Test written
flag.BoolVar(&globalState.Cfg.AppendDir, "appendslash", false, "Append a / to all directory bruteforce requests (like extension, but slash instead of .yourthing)") //Test Written
flag.BoolVar(&globalState.Cfg.Ajax, "ajax", false, "Add the X-Requested-With: XMLHttpRequest header to all requests") //Test Written
flag.StringVar(&globalState.Cfg.Auth, "auth", "", "Basic auth. Supply this with the base64 encoded portion to be placed after the word 'Basic' in the Authorization header.") //Test Written
flag.StringVar(&globalState.Cfg.BadResponses, "bad", "404", "Responses to consider 'bad' or 'not found'. Comma-separated. This works the opposite way of gobuster!") //Test Written
flag.BoolVar(&globalState.Cfg.ShowAll, "all", false, "Show, and write the result of all checks") //Test written
flag.BoolVar(&globalState.Cfg.AppendDir, "appendslash", false, "Append a / to all directory bruteforce requests (like extension, but slash instead of .yourthing)") //Test Written
flag.BoolVar(&globalState.Cfg.Ajax, "ajax", false, "Add the X-Requested-With: XMLHttpRequest header to all requests") //Test Written
flag.StringVar(&globalState.Cfg.Auth, "auth", "", "Basic auth. Supply this with the base64 encoded portion to be placed after the word 'Basic' in the Authorization header.") //Test Written
flag.StringVar(&globalState.Cfg.BadResponses, "bad", "404", "Responses to consider 'bad' or 'not found'. Comma-separated. This works the opposite way of gobuster!") //Test Written
flag.StringVar(&globalState.Cfg.GoodResponses, "good", "", "Whitelist of response codes to consider good. If this flag is used, ONLY the provided codes will be considered 'good'.")
flag.Var(&globalState.Cfg.BadHeader, "badheader", "Check for presence of this header. If an prefix match is found, the response is considered bad.Supply as key:value. Can specify multiple - eg '-badheader Location:cats -badheader X-ATT-DeviceId:XXXXX'") //Test Written
flag.StringVar(&globalState.Cfg.BodyContent, "body", "", "File containing content to send in the body of the request. Content-length header will be set accordingly. Note: HEAD requests will/should fail (server will reply with a 400). Set the '-nohead' option to prevent HEAD being sent before a GET.") //Test Written
flag.StringVar(&globalState.Cfg.BlacklistLocation, "blacklist", "", "Blacklist of prefixes to not check. Will not check on exact matches.") //Test Written
Expand Down

0 comments on commit 4edd18b

Please sign in to comment.