Skip to content

Commit 87de043

Browse files
committed
Fix sending multiple request to same endpoint bug
1 parent d56a183 commit 87de043

File tree

5 files changed

+50
-23
lines changed

5 files changed

+50
-23
lines changed

librecursebuster/logic.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ func ManageNewURLs() {
4343
//decides on whether to add to the directory list, or add to file output
4444
for {
4545
candidate := <-gState.Chans.newPagesChan
46-
4746
//check the candidate is an actual URL
4847
u, err := url.Parse(strings.TrimSpace(candidate.URL))
4948

@@ -185,8 +184,7 @@ func dirBust(page SpiderPage) {
185184
}
186185

187186
atomic.StoreUint32(gState.DirbProgress, 0)
188-
189-
tested := make(map[string]bool) //ensure we don't send things more than once
187+
//ensure we don't send things more than once
190188
for _, word := range gState.WordList { //will receive from the channel until it's closed
191189
//read words off the channel, and test it OR close out because we wanna skip it
192190
if word == "" {
@@ -204,31 +202,40 @@ func dirBust(page SpiderPage) {
204202
for _, method := range gState.Methods {
205203
if len(gState.Extensions) > 0 && gState.Extensions[0] != "" {
206204
for _, ext := range gState.Extensions {
207-
if tested[method+page.URL+word+"."+ext] {
205+
gState.CMut.Lock()
206+
if gState.Checked[method+page.URL+word+"."+ext] {
207+
gState.CMut.Unlock()
208208
continue
209209
}
210210
gState.Chans.workersChan <- struct{}{}
211211
gState.wg.Add(1)
212212
go testURL(method, page.URL+word+"."+ext, gState.Client)
213-
tested[method+page.URL+word+"."+ext] = true
213+
gState.Checked[method+page.URL+word+"."+ext] = true
214+
gState.CMut.Unlock()
214215
}
215216
}
216217
if gState.Cfg.AppendDir {
217-
if tested[method+page.URL+word+"/"] {
218+
gState.CMut.Lock()
219+
if gState.Checked[method+page.URL+word+"/"] {
220+
gState.CMut.Unlock()
218221
continue
219222
}
220223
gState.Chans.workersChan <- struct{}{}
221224
gState.wg.Add(1)
222225
go testURL(method, page.URL+word+"/", gState.Client)
223-
tested[method+page.URL+word+"/"] = true
226+
gState.Checked[method+page.URL+word+"/"] = true
227+
gState.CMut.Unlock()
224228
}
225-
if tested[method+page.URL+word] {
229+
gState.CMut.Lock()
230+
if gState.Checked[method+page.URL+word] {
231+
gState.CMut.Unlock()
226232
continue
227233
}
228234
gState.Chans.workersChan <- struct{}{}
229235
gState.wg.Add(1)
230236
go testURL(method, page.URL+word, gState.Client)
231-
tested[method+page.URL+word] = true
237+
gState.Checked[method+page.URL+word] = true
238+
gState.CMut.Unlock()
232239
//if gState.Cfg.MaxDirs == 1 {
233240
atomic.AddUint32(gState.DirbProgress, 1)
234241
//}

librecursebuster/main_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestBasicFunctionality(t *testing.T) {
4646

4747
finished := make(chan struct{})
4848
cfg := getDefaultConfig()
49-
urlSlice := preSetupTest(cfg, "2001", finished)
49+
urlSlice := preSetupTest(cfg, "2001", finished, t)
5050
found := postSetupTest(urlSlice)
5151

5252
//waitgroup check (if test times out, the waitgroup is broken... somewhere)
@@ -104,7 +104,7 @@ func TestAppendSlash(t *testing.T) {
104104
//add an appendslash value to the wordlist that should _only_ be found if the appendslash var is set
105105
finished := make(chan struct{})
106106
cfg := getDefaultConfig()
107-
urlSlice := preSetupTest(cfg, "2002", finished)
107+
urlSlice := preSetupTest(cfg, "2002", finished, t)
108108
gState.Cfg.AppendDir = true
109109
gState.WordList = append(gState.WordList, "appendslash")
110110
found := postSetupTest(urlSlice)
@@ -121,7 +121,7 @@ func TestBasicAuth(t *testing.T) {
121121
finished := make(chan struct{})
122122
cfg := getDefaultConfig()
123123
cfg.Auth = "dGVzdDp0ZXN0"
124-
urlSlice := preSetupTest(cfg, "2003", finished)
124+
urlSlice := preSetupTest(cfg, "2003", finished, t)
125125
gState.WordList = append(gState.WordList, "basicauth")
126126
found := postSetupTest(urlSlice)
127127
gState.Wait()
@@ -137,7 +137,7 @@ func TestBadCodes(t *testing.T) {
137137
finished := make(chan struct{})
138138
cfg := getDefaultConfig()
139139
cfg.BadResponses = "404,500"
140-
urlSlice := preSetupTest(cfg, "2004", finished)
140+
urlSlice := preSetupTest(cfg, "2004", finished, t)
141141
gState.WordList = append(gState.WordList, "badcode")
142142
found := postSetupTest(urlSlice)
143143
gState.Wait()
@@ -156,7 +156,7 @@ func TestBadHeaders(t *testing.T) {
156156
cfg := getDefaultConfig()
157157
cfg.BadHeader = ArrayStringFlag{}
158158
cfg.BadHeader.Set("X-Bad-Header: test123")
159-
urlSlice := preSetupTest(cfg, "2005", finished)
159+
urlSlice := preSetupTest(cfg, "2005", finished, t)
160160
gState.WordList = append(gState.WordList, "badheader")
161161
found := postSetupTest(urlSlice)
162162
gState.Wait()
@@ -175,7 +175,7 @@ func TestAjax(t *testing.T) {
175175
cfg := getDefaultConfig()
176176
cfg.Ajax = true
177177
cfg.Methods = "GET,POST"
178-
urlSlice := preSetupTest(cfg, "2006", finished)
178+
urlSlice := preSetupTest(cfg, "2006", finished, t)
179179
gState.WordList = append(gState.WordList, "ajaxonly")
180180
gState.WordList = append(gState.WordList, "onlynoajax")
181181
gState.WordList = append(gState.WordList, "ajaxpost")
@@ -252,7 +252,7 @@ func postSetupTest(urlSlice []string) (found map[string]bool) {
252252
return
253253
}
254254

255-
func preSetupTest(cfg *Config, servPort string, finished chan struct{}) (urlSlice []string) {
255+
func preSetupTest(cfg *Config, servPort string, finished chan struct{}, t *testing.T) (urlSlice []string) {
256256
//Test default functions. Basic dirb should work, and all files should be found as expected
257257

258258
//basic state setup
@@ -264,7 +264,7 @@ func preSetupTest(cfg *Config, servPort string, finished chan struct{}) (urlSlic
264264

265265
//start the test server
266266
setup := make(chan struct{})
267-
go testserver.Start(servPort, finished, setup)
267+
go testserver.Start(servPort, finished, setup, t)
268268
<-setup //whoa, concurrency sucks???
269269
//test URL
270270
globalState.Cfg.URL = localURL + servPort

librecursebuster/testserver/main.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"net/http"
66
"strings"
77
"sync"
8+
"testing"
9+
"time"
810
)
911

1012
/*wordlist
@@ -56,7 +58,8 @@ func handler(w http.ResponseWriter, r *http.Request) {
5658
//if it's been visited more than once, instant fail
5759
if visited[r.Method+":"+r.URL.Path] && r.URL.Path != "/" {
5860
//we can visit the base url more than once
59-
//panic("Path visited more than once: " + r.Method + ":" + r.URL.Path)
61+
tes.Fail()
62+
panic("Path visited more than once: " + r.Method + ":" + r.URL.Path)
6063
}
6164
visited[r.Method+":"+r.URL.Path] = true
6265
vMut.Unlock()
@@ -172,13 +175,31 @@ func handler(w http.ResponseWriter, r *http.Request) {
172175
fmt.Println(r.Method, r.URL, respCode, bod)
173176
}
174177

178+
var tes *testing.T
179+
175180
//Start starts the test HTTP server
176-
func Start(port string, finishedTest, setup chan struct{}) {
181+
func Start(port string, finishedTest, setup chan struct{}, t *testing.T) {
177182
s := http.NewServeMux()
178183
visited = make(map[string]bool)
179184
vMut = &sync.RWMutex{}
185+
tes = t
180186
s.HandleFunc("/", handler)
181187
go http.ListenAndServe("127.0.0.1:"+port, s)
188+
189+
for {
190+
time.Sleep(time.Second * 1)
191+
resp, err := http.Get("http://localhost:" + port)
192+
if err != nil {
193+
continue
194+
}
195+
resp.Body.Close()
196+
if resp.StatusCode != http.StatusOK {
197+
continue
198+
}
199+
// Reached this point: server is up and running!
200+
break
201+
}
202+
182203
close(setup)
183204
<-finishedTest //this is an ultra gross hack :(
184205
}

librecursebuster/ui.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
//StartUI is called to begin the UI... stuff
1212
func (s *State) StartUI(uiWG *sync.WaitGroup, quitChan chan struct{}) {
1313
g, err := ui.NewGui(ui.OutputNormal)
14-
g.Mouse = true
1514
if err != nil {
1615
panic(err)
1716
}
@@ -47,15 +46,15 @@ func (s *State) StartUI(uiWG *sync.WaitGroup, quitChan chan struct{}) {
4746
err = s.ui.SetKeybinding("", ui.KeyArrowDown, ui.ModNone, scrollDown)
4847
if err != nil {
4948
panic(err)
50-
}
49+
} /* Mouse stuff broke copying out of the terminal... not ideal
5150
err = s.ui.SetKeybinding("", ui.MouseWheelUp, ui.ModNone, scrollUp)
5251
if err != nil {
5352
panic(err)
5453
}
5554
err = s.ui.SetKeybinding("", ui.MouseWheelDown, ui.ModNone, scrollDown)
5655
if err != nil {
5756
panic(err)
58-
}
57+
}*/
5958
uiWG.Done()
6059
err = s.ui.MainLoop()
6160
if err != nil && err != ui.ErrQuit {

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"github.com/fatih/color"
1515
)
1616

17-
const version = "1.5.10"
17+
const version = "1.5.11"
1818

1919
func main() {
2020
if runtime.GOOS == "windows" { //lol goos

0 commit comments

Comments
 (0)