Skip to content

Commit

Permalink
new tool added, edirb
Browse files Browse the repository at this point in the history
  • Loading branch information
NitescuLucian committed Mar 14, 2023
1 parent 1e27fc3 commit ece24d1
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
115 changes: 115 additions & 0 deletions edirb/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package main

import (
"bufio"
"bytes"
"flag"
"fmt"
"io"
"net/http"
"os"
"strings"
"sync"
"time"
)

func main() {
threads := flag.Int("t", 100, "Number of threads for requests")
wordlist := flag.String("w", "", "Wordlist file path for bruteforce")

flag.Parse()

if *wordlist == "" {
fmt.Fprintf(os.Stderr, "usage: %s -w wordlist target\n", os.Args[0])
os.Exit(1)
}

// Read the items for bruteforcing from the wordlist file
file, err := os.Open(*wordlist)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer file.Close()

var items []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
item := scanner.Text()
items = append(items, item)
}

if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading wordlist file:", err)
os.Exit(1)
}

// Bruteforce items for each target concurrently
var targets []string
scanner = bufio.NewScanner(os.Stdin)
for scanner.Scan() {
target := scanner.Text()
// Check if the target has a trailing slash
if !strings.HasSuffix(target, "/") {
target += "/"
}
targets = append(targets, target)
}

if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading standard input:", err)
os.Exit(1)
}

// Create a channel with buffer size 10 to limit threads
sem := make(chan struct{}, *threads)

for _, item := range items {
var wg sync.WaitGroup
for _, target := range targets {

wg.Add(1)
// Wait for a free slot in the channel
sem <- struct{}{}

go func(target, item string) {
defer func() {
// Release the slot in the channel
<-sem
wg.Done()
}()

url := fmt.Sprintf("%s%s", target, item)
client := &http.Client{
// so that you will not hang yourself over 120 seconds threads
Timeout: time.Second * 5,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}

resp, err := client.Get(url)
if err != nil {
return
}
var buf bytes.Buffer
_, err = io.Copy(&buf, resp.Body)
if err != nil {
// handle error
return
}
bodyLength := buf.Len()

// this aproximates to the nearest hundreds so that you will not duplicate the outputs
bodyLength = ((bodyLength + 50) / 100) * 100

if resp.StatusCode != 404 {
fmt.Printf("%s [sc:%d] [al:%d]\n", url, resp.StatusCode, bodyLength)
}
resp.Body.Close()
}(target, item)
}
wg.Wait()
}

}
33 changes: 33 additions & 0 deletions edirb/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

# edirb

## Why?

Economic Directory Buster (edirb) for when you need to diretory bruteforce more then 10k hosts but without making too many requests on each host.

```
sc = status code
al = aproximated content length
```

### Helper

```
Usage of edirb
-t int
Number of threads for requests (default 100)
-w string
Wordlist file path for bruteforce
```

* You can `anew` and `grep` for what you need and it is easy to use while piping.

## Install

You can install using go:

```
go install -v github.com/NitescuLucian/hacks/edirb@latest
```

Contact me at [@LucianNitescu](https://twitter.com/LucianNitescu)

0 comments on commit ece24d1

Please sign in to comment.