diff --git a/README.md b/README.md new file mode 100644 index 0000000..964608b --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# DirDar v1.0 + +
+ 🏴☠️ bypass forbidden directories - find and identify dir listing - you can use it as directory brute-forcer as well
+
+
+
+
+ Share on Twitter!
+
+
+
+
+
+
+
+
+## Install
+
+Run this command if you have Go installed and configured.
+
+```
+go get -u github.com/m4dm0e/dirdar
+```
+
+Or you can [download a release](https://github.com/m4dm0e/dirdar/releases).
+To make it easier to execute you can put the binary in your `$PATH`.
diff --git a/dirs-list.txt b/dirs-list.txt
new file mode 100644
index 0000000..4af5c7a
--- /dev/null
+++ b/dirs-list.txt
@@ -0,0 +1,225 @@
+index
+images
+download
+2006
+news
+crack
+serial
+warez
+full
+12
+contact
+about
+search
+spacer
+privacy
+11
+logo
+blog
+new
+10
+cgi-bin
+faq
+rss
+home
+img
+default
+products
+sitemap
+archives
+links
+login
+articles
+support
+keygen
+article
+help
+events
+archive
+register
+forum
+software
+downloads
+security
+category
+content
+main
+press
+media
+templates
+services
+icons
+resources
+info
+profile
+docs
+contactus
+files
+features
+html
+page
+misc
+partners
+terms
+banners
+xml
+tools
+projects
+user
+feed
+themes
+linux
+forums
+jobs
+business
+video
+email
+books
+banner
+reviews
+view
+graphics
+research
+feedback
+pdf
+print
+ads
+modules
+company
+blank
+pub
+games
+copyright
+common
+site
+comments
+people
+aboutus
+product
+sports
+logos
+buttons
+english
+story
+image
+uploads
+subscribe
+blogs
+atom
+gallery
+newsletter
+stats
+careers
+music
+pages
+publications
+technology
+calendar
+stories
+photos
+papers
+community
+data
+history
+arrow
+submit
+www
+s
+web
+library
+wiki
+header
+education
+internet
+advertise
+spam
+nav
+mail
+users
+members
+topics
+disclaimer
+store
+clear
+feeds
+awards
+general
+pics
+dir
+signup
+solutions
+map
+public
+weblog
+index2
+shop
+contacts
+homepage
+travel
+button
+pixel
+list
+viewtopic
+documents
+overview
+tips
+adclick
+contact_us
+movies
+wp-content
+catalog
+us
+p
+staff
+hardware
+wireless
+global
+screenshots
+apps
+online
+version
+directory
+mobile
+other
+advertising
+tech
+welcome
+admin
+t
+policy
+faqs
+link
+2001
+training
+releases
+space
+member
+static
+join
+health
+weather
+reports
+scripts
+browse
+windows
+firefox_reco
+showallsites
+programs
+ewbutton_guestbook
+ewbutton_community
+menu
+europemirror
+2000
+entertainment
+newsletters
+pr
+32
+categories
+detail
+assets
+js
+admin
+css
+files
+users
+
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..9276451
--- /dev/null
+++ b/main.go
@@ -0,0 +1,393 @@
+package main
+
+import (
+ "bufio"
+ "crypto/tls"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "net"
+ "net/http"
+ "os"
+ "os/exec"
+ "runtime"
+ "strings"
+ "sync"
+ "time"
+)
+
+var SingleScan = false
+
+/*
+This colors code from -> https://github.com/ethicalhackingplayground/Zin/blob/master/zin.go
+*/
+var Reset = "\033[0m"
+var Red = "\033[31m"
+var Green = "\033[32m"
+var Yellow = "\033[33m"
+var Blue = "\033[34m"
+var Purple = "\033[35m"
+var Cyan = "\033[36m"
+var Gray = "\033[37m"
+var White = "\033[97m"
+var Dark = "\033[90m"
+var clear map[string]func() //create a map for storing clear funcs
+
+func init() {
+ clear = make(map[string]func()) //Initialize it
+ clear["linux"] = func() {
+ cmd := exec.Command("clear") //Linux example, its tested
+ cmd.Stdout = os.Stdout
+ cmd.Run()
+ }
+ clear["windows"] = func() {
+ cmd := exec.Command("cmd", "/c", "cls") //Windows example, its tested
+ cmd.Stdout = os.Stdout
+ cmd.Run()
+ }
+ if runtime.GOOS == "windows" {
+ Reset = ""
+ Dark = ""
+ Red = ""
+ Green = ""
+ Yellow = ""
+ Blue = ""
+ Purple = ""
+ Cyan = ""
+ Gray = ""
+ White = ""
+ }
+}
+
+/////////////////////////////////////////////////////////
+
+////| Clear the terminal screen ...
+func scre3n() {
+ /////| This code from :-> https://stackoverflow.com/questions/22891644/how-can-i-clear-the-terminal-screen-in-go
+ value, ok := clear[runtime.GOOS] //runtime.GOOS -> linux, windows, darwin etc.
+ if ok { //if we defined a clear func for that platform:
+ value() //we execute it
+ } else { //unsupported platform
+ panic("Your platform is unsupported! I can't clear terminal screen :(")
+ }
+}
+
+////| Error handling function ...
+func err0r(oNe error, msg string) {
+ if oNe != nil {
+ scre3n()
+ fmt.Println("\n\n [x] - ", Red, msg, White, "\n\n")
+ os.Exit(0)
+ return
+ }
+}
+
+///| This function is to find the forbidden directories .....
+func ForbidFinder(domain string, wl string, nf bool, TimeOut int, OnlyOk bool, isItSingle bool) {
+
+ if isItSingle {
+ fmt.Println(" -[ YOUR TARGET : ", domain, " ]-\n\n")
+ }
+ timeout := time.Duration(TimeOut * 1000000)
+ tr := &http.Transport{
+ MaxIdleConns: 20,
+ MaxIdleConnsPerHost: 20,
+ IdleConnTimeout: time.Second,
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ DialContext: (&net.Dialer{
+ Timeout: timeout,
+ KeepAlive: time.Second,
+ }).DialContext,
+ ResponseHeaderTimeout: 30 * time.Second,
+ }
+
+ client := &http.Client{
+ Transport: tr,
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ Timeout: timeout,
+ }
+
+ ///| IF STATMENT |\\\
+ Door := fmt.Sprintf("%s/%s/", domain, "DirDarWithRandomString")
+ reQ, err := client.Get(Door)
+ if err != nil {
+ return
+ }
+ if reQ.StatusCode == 403 {
+ return
+ }
+
+ if wl != "" {
+ ForbiddenList, err := os.Open(wl)
+ if err != nil {
+ finalErr := fmt.Sprintf("%s [%s]", "There was error opening this file!", wl)
+ err0r(err, finalErr)
+ }
+ defer ForbiddenList.Close()
+ ForbiDDen := bufio.NewScanner(ForbiddenList)
+ for ForbiDDen.Scan() {
+ WordList := ForbiDDen.Text()
+ FullUrl := fmt.Sprintf("%s/%s/", domain, WordList)
+ reQ, err := client.Get(FullUrl)
+ if err != nil {
+ return
+ }
+ defer reQ.Body.Close()
+ if reQ.StatusCode == 403 {
+ do3r(domain, WordList, TimeOut, OnlyOk)
+ } else if reQ.StatusCode == http.StatusOK {
+ bodyBytes, err := ioutil.ReadAll(reQ.Body)
+ if err != nil {
+ return
+ }
+ bodyString := string(bodyBytes)
+ Directory1StCase := "Index of /" + WordList
+ DirectorySecCase := "Directory /" + WordList
+ Directory3RdCase := "Directory listing for /" + WordList
+ if strings.Contains(bodyString, Directory1StCase) || strings.Contains(bodyString, DirectorySecCase) || strings.Contains(bodyString, Directory3RdCase) {
+ fmt.Println(White, " [+] -", Green, " Directory listing ", White, "[", Cyan, FullUrl, White, "]", "Response code ", "[", reQ.StatusCode, "]")
+
+ }
+ } else {
+ if nf {
+ fmt.Println(Purple, " [X] NOT FOUND : ", White, "[", Blue, FullUrl, White, "]", " With code -> ", "[", Red, reQ.StatusCode, White, "]")
+ } else {
+ }
+ }
+ }
+ } else {
+ ForbiddenList := []string{"admin", "test", "img", "inc", "includes", "include", "images", "pictures", "gallery", "css", "js", "asset", "assets", "backup", "static", "cms", "blog", "uploads", "files"}
+ for i := range ForbiddenList {
+ WordList := ForbiddenList[i]
+ FullUrl := fmt.Sprintf("%s/%s/", domain, WordList)
+ reQ, err := client.Get(FullUrl)
+ if err != nil {
+ return
+ }
+ defer reQ.Body.Close()
+ if reQ.StatusCode == 403 {
+ do3r(domain, WordList, TimeOut, OnlyOk)
+ } else if reQ.StatusCode == http.StatusOK {
+ bodyBytes, err := ioutil.ReadAll(reQ.Body)
+ if err != nil {
+ return
+ }
+ bodyString := string(bodyBytes)
+ Directory1StCase := "Index of /" + WordList
+ DirectorySecCase := "Directory /" + WordList
+ Directory3RdCase := " - " + WordList
+ if strings.Contains(bodyString, Directory1StCase) || strings.Contains(bodyString, DirectorySecCase) || strings.Contains(bodyString, Directory3RdCase) {
+ fmt.Println("\n", White, " [+] - ", Green, "Directory listing ", White, "[", Blue, FullUrl, White, "]", "Response code -> ", "[", Green, reQ.StatusCode, White, "]", "\n")
+
+ }
+ } else {
+ if nf {
+ fmt.Println(Purple, " [X] NOT FOUND : ", White, "[", Blue, FullUrl, White, "]", " With code -> ", "[", Red, reQ.StatusCode, White, "]")
+ } else {
+
+ }
+ }
+
+ }
+
+ }
+
+ //wG2.Wait()
+ // return true
+
+}
+
+func do3r(domain string, path string, TimeOut int, OnlyOk bool) {
+ ByPass := []string{"%20" + path + "%20/", "%2e/" + path, "./" + path + "/./", "/" + path + "//", path + "..;/", path + "./", path + "/", path + "/*", path + "/.", path + "//", path + "?", path + "???", path + "%20/", path + "/%25", path + "/.randomstring"}
+ ByPassWithHeader := []string{"X-Custom-IP-Authorization", "X-Originating-IP", "X-Forwarded-For", "X-Remote-IP", "X-Client-IP", "X-Host", "X-Forwarded-Host"}
+ timeout := time.Duration(TimeOut * 1000000)
+ tr := &http.Transport{
+ MaxIdleConns: 20,
+ MaxIdleConnsPerHost: 20,
+ IdleConnTimeout: time.Second,
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ DialContext: (&net.Dialer{
+ Timeout: timeout,
+ KeepAlive: time.Second,
+ }).DialContext,
+ ResponseHeaderTimeout: timeout,
+ }
+
+ client := &http.Client{
+ Transport: tr,
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
+ return http.ErrUseLastResponse
+ },
+ Timeout: timeout,
+ }
+ FinalLook := fmt.Sprintf("%s/%s/", domain, path)
+ FinalLookToReq := fmt.Sprintf("%s/%s/", domain, path)
+ if !OnlyOk {
+ fmt.Println(White, " [+]", Cyan, "- FOUND", White, "[", Blue, FinalLook, White, "]", " With code ->", "[", Yellow, "403", White, "]")
+ }
+
+ for t0Bypass2 := range ByPassWithHeader {
+ //FullUrl := fmt.Sprintf("%s/%s", domain, )
+ //reQ, err := client.Get(FullUrl)
+ reQ, err := http.NewRequest("GET", FinalLookToReq, nil)
+ if err != nil {
+ panic(err)
+ }
+ reQ.Header.Add(ByPassWithHeader[t0Bypass2], "127.0.0.1")
+ resp, err := client.Do(reQ)
+ if err != nil {
+ //panic(err)
+ return
+ }
+ if resp.StatusCode == http.StatusOK {
+ bodyBytes, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return
+ }
+ bodyString := string(bodyBytes)
+ Directory1StCase := "Index of /" + path
+ DirectorySecCase := "Directory /" + path
+ Directory3RdCase := " - " + path
+ if strings.Contains(bodyString, Directory1StCase) || strings.Contains(bodyString, DirectorySecCase) || strings.Contains(bodyString, Directory3RdCase) {
+ fmt.Println("\n", Yellow, " [+] - BYPASSED : payload", White, "[", Green, ByPassWithHeader[t0Bypass2], ": 127.0.0.1", "] :", "] ", Blue, FinalLook, White, " -> Response status code [", Green, resp.StatusCode, White, "]\n")
+
+ }
+ //finalWG.Done()
+ //time.Sleep(10 * time.Second)
+ } else {
+ if !OnlyOk {
+ fmt.Println(White, " [-]", Yellow, " - FAILED : payload", White, "[", Green, ByPassWithHeader[t0Bypass2], ": 127.0.0.1", White, "] ", Blue, FinalLook, White, " -> Response status code [", Red, resp.StatusCode, White, "]")
+ }
+ }
+ }
+ for t0Bypass := range ByPass {
+ // finalWG.Add(1)
+ //qs := url.QueryEscape(ByPass[t0Bypass])
+ FullUrl := fmt.Sprintf("%s/%s", domain, ByPass[t0Bypass])
+ //u, err := url.Parse(qs)
+ reQ, err := client.Get(FullUrl)
+ if err != nil {
+ return
+ //panic(err)
+ }
+ defer reQ.Body.Close()
+ if reQ.StatusCode == http.StatusOK {
+ bodyBytes, err := ioutil.ReadAll(reQ.Body)
+ if err != nil {
+ return
+ }
+ bodyString := string(bodyBytes)
+ Directory1StCase := "Index of /" + path
+ DirectorySecCase := "Directory /" + path
+ Directory3RdCase := " - " + path
+ if strings.Contains(bodyString, Directory1StCase) || strings.Contains(bodyString, DirectorySecCase) || strings.Contains(bodyString, Directory3RdCase) {
+ fmt.Println("\n", Yellow, " [+] - BYPASSED : payload", White, "[", Green, ByPass[t0Bypass], White, "] ", Blue, FinalLook, White, " -> Response status code [", Green, reQ.StatusCode, White, "]\n")
+
+ }
+ //stime.Sleep(10 * time.Second)
+ } else {
+ if !OnlyOk {
+ fmt.Println(White, " [-]", Yellow, " - FAILED : payload", White, "[", Green, ByPass[t0Bypass], White, "] ", Blue, FullUrl, White, " -> Response status code [", Red, reQ.StatusCode, White, "]")
+ }
+ }
+ }
+
+}
+
+func worker(domain chan string, wg *sync.WaitGroup, wl string, nf bool, TimeOut int, OnlyOk bool) {
+ defer wg.Done()
+ for b := range domain {
+ ForbidFinder(b, wl, nf, TimeOut, OnlyOk, SingleScan)
+ }
+}
+
+func bann3r() {
+ scre3n()
+ const banner = `
+______ _ ______
+| _ (_) | _ \
+| | | |_ _ __| | | |__ _ _ __
+| | | | | '__| | | / _ | '__|
+| |/ /| | | | |/ / (_| | |
+|___/ |_|_| |___/ \__,_|_| v1.0
+`
+ const about = `
+ Author : Mohammed Al-Barbari
+ Twitter : @m4dm0e
+ GrodRiket security team
+ Love from :`
+ var from = Red + "Ye" + White + "me" + Dark + "n"
+ fmt.Println(banner, about, from, Reset, "\n\n")
+
+}
+func h3lp() {
+ fmt.Println("\n", White, " [-]", Red, "No input provided ", White, "(Run the tool again with --help flag for more information .)\n\n")
+ os.Exit(0)
+}
+func main() {
+ bann3r()
+ var wg sync.WaitGroup
+ DomainsList := make(chan string)
+
+ ////| Requests TimeOut
+ var TimeOut int
+ flag.IntVar(&TimeOut, "t", 10000, "Set the timeout of the requests")
+ var con int
+ flag.IntVar(&con, "c", 10, "Concurrency - to control the requests make fast or slow ")
+ var wl string
+ flag.StringVar(&wl, "wl", "", "Forbidden directories WordList")
+
+ showErr := flag.Bool("err", false, "If you want to show errors!(Includes 404 errors) [True-False]")
+
+ //var OnlyOK string
+ //flag.StringVar(&OnlyOK, "only-ok", "", "Print out only OK (Bypassed and dir listing) ")
+ OnlyOK := flag.Bool("only-ok", false, "Print out only OK (Bypassed and dir listing) ")
+
+ // var OnlyBypass string
+ // flag.StringVar(&OnlyBypass, "to-bypass", "", "Use this option with sites list [If you already have forbidden dirs] e.x(-to-bypass Forbiddens.txt)")
+
+ var SingleSite string
+ flag.StringVar(&SingleSite, "single", "", "Only scan single target e.g (-single https://example.com/)")
+ flag.Parse()
+ // showErr = strings.ToLower(showErr)
+
+ if wl != "" {
+ ForbiddenList, err := os.Open(wl)
+
+ if err != nil {
+
+ finalErr := fmt.Sprintf("%s [%s]", "There was error opening this file!", wl)
+ err0r(err, finalErr)
+ _ = ForbiddenList
+ }
+ }
+ if SingleSite == "" {
+ for c := 0; c <= con; c++ {
+ wg.Add(1)
+ go worker(DomainsList, &wg, wl, *showErr, TimeOut, *OnlyOK)
+ }
+ sc := bufio.NewScanner(os.Stdin)
+ stat, _ := os.Stdin.Stat()
+ if (stat.Mode() & os.ModeCharDevice) == 0 {
+ go func() {
+ for sc.Scan() {
+ texted := sc.Text()
+ DomainsList <- texted
+ }
+
+ close(DomainsList)
+ }()
+
+ } else {
+ h3lp()
+ }
+
+ wg.Wait()
+
+ } else {
+ ForbidFinder(SingleSite, wl, *showErr, TimeOut, *OnlyOK, true)
+ }
+
+}
diff --git a/statics/img/error.png b/statics/img/error.png
new file mode 100644
index 0000000..a51f19f
Binary files /dev/null and b/statics/img/error.png differ
diff --git a/statics/img/firstScreen.png b/statics/img/firstScreen.png
new file mode 100644
index 0000000..1829d6b
Binary files /dev/null and b/statics/img/firstScreen.png differ
diff --git a/statics/img/help.png b/statics/img/help.png
new file mode 100644
index 0000000..caca3c5
Binary files /dev/null and b/statics/img/help.png differ
diff --git a/statics/img/scanning.png b/statics/img/scanning.png
new file mode 100644
index 0000000..09db80a
Binary files /dev/null and b/statics/img/scanning.png differ
diff --git a/statics/img/windows.JPG b/statics/img/windows.JPG
new file mode 100644
index 0000000..e6f2ad6
Binary files /dev/null and b/statics/img/windows.JPG differ