From 255bbacb644776eec270563652a8cb9ca0b1b996 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Fri, 23 Feb 2024 11:00:57 -0800 Subject: [PATCH 01/14] update output --- modules/output.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/output.go b/modules/output.go index a843138..7d70ebb 100644 --- a/modules/output.go +++ b/modules/output.go @@ -25,16 +25,16 @@ func getConResultString(con_result bool, retrying bool) string { } } -func WriteToFile(filename string, content string) error { +func WriteToFile(filename string, service string, content string) error { timestamp := time.Now().Format("2006010215") - dir := "output" + dir := "brutespray-output" if _, err := os.Stat(dir); os.IsNotExist(err) { err := os.Mkdir(dir, 0755) if err != nil { return err } } - filename = filepath.Join(dir, filename+"_"+timestamp) + filename = filepath.Join(dir, filename+"_"+service+"_"+timestamp+".txt") file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err @@ -55,7 +55,7 @@ func PrintResult(service string, host string, port int, user string, pass string pterm.Success.Println("Attempt", service, "SUCCESS on host", host, "port", port, "with password", pass, getResultString(result)) content := fmt.Sprintf("Attempt %s SUCCESS on host %s port %d with password %s %s\n", service, host, port, pass, getResultString(result)) filename := filepath.Base(host) - err := WriteToFile(filename, content) + err := WriteToFile(filename, service, content) if err != nil { fmt.Println("write file error:", err) } @@ -63,7 +63,7 @@ func PrintResult(service string, host string, port int, user string, pass string pterm.Success.Println("Attempt", service, "SUCCESS on host", host, "port", port, "with username", user, "and password", pass, getResultString(result)) content := fmt.Sprintf("Attempt %s SUCCESS on host %s port %d with username %s and password %s %s\n", service, host, port, user, pass, getResultString(result)) filename := filepath.Base(host) - err := WriteToFile(filename, content) + err := WriteToFile(filename, service, content) if err != nil { fmt.Println("write file error:", err) } From 03409590b2b60c7331a3e642bf05b8bee5d43a9f Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Fri, 23 Feb 2024 11:12:06 -0800 Subject: [PATCH 02/14] fixed bar accuracy when provided cidr --- brutespray/brutespray.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/brutespray/brutespray.go b/brutespray/brutespray.go index 353c289..28bc4f2 100644 --- a/brutespray/brutespray.go +++ b/brutespray/brutespray.go @@ -85,6 +85,7 @@ func Execute() { } hostsList = append(hostsList, host...) } + fmt.Println(hostsList) supportedServices := getSupportedServices(*serviceType) @@ -95,6 +96,7 @@ func Execute() { if h.Service == service { users, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) totalCombinations += modules.CalcCombinations(users, passwords) + fmt.Println(totalCombinations) if service == "vnc" || service == "snmp" { _, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) totalCombinations += modules.CalcCombinationsPass(passwords) @@ -103,7 +105,7 @@ func Execute() { } } - bar, _ := pterm.DefaultProgressbar.WithTotal(len(hostsList)*(totalCombinations) - nopassServices).WithTitle("Bruteforcing...").Start() + bar, _ := pterm.DefaultProgressbar.WithTotal((totalCombinations) - nopassServices).WithTitle("Bruteforcing...").Start() var wg sync.WaitGroup var bruteForceWg sync.WaitGroup sem := make(chan struct{}, *threads) From 65104a451bc0e7e3d52692aba07bf92903c011e0 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Fri, 23 Feb 2024 11:29:48 -0800 Subject: [PATCH 03/14] remove println statements --- brutespray/brutespray.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/brutespray/brutespray.go b/brutespray/brutespray.go index 28bc4f2..7e6a2a3 100644 --- a/brutespray/brutespray.go +++ b/brutespray/brutespray.go @@ -85,7 +85,6 @@ func Execute() { } hostsList = append(hostsList, host...) } - fmt.Println(hostsList) supportedServices := getSupportedServices(*serviceType) @@ -96,7 +95,6 @@ func Execute() { if h.Service == service { users, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) totalCombinations += modules.CalcCombinations(users, passwords) - fmt.Println(totalCombinations) if service == "vnc" || service == "snmp" { _, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) totalCombinations += modules.CalcCombinationsPass(passwords) @@ -104,7 +102,6 @@ func Execute() { } } } - bar, _ := pterm.DefaultProgressbar.WithTotal((totalCombinations) - nopassServices).WithTitle("Bruteforcing...").Start() var wg sync.WaitGroup var bruteForceWg sync.WaitGroup From 4968db8ed5905af4867f6bde0661834c3da6c711 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Fri, 23 Feb 2024 12:06:35 -0800 Subject: [PATCH 04/14] added unix /usr/share/ wordlist path --- README.md | 2 +- modules/wordlist.go | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 85b4332..f7b8d21 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # BruteSpray -![Version](https://img.shields.io/badge/Version-2.1.5-red)[![goreleaser](https://github.com/x90skysn3k/brutespray/actions/workflows/release.yml/badge.svg)](https://github.com/x90skysn3k/brutespray/actions/workflows/release.yml) +![Version](https://img.shields.io/badge/Version-2.1.6-red)[![goreleaser](https://github.com/x90skysn3k/brutespray/actions/workflows/release.yml/badge.svg)](https://github.com/x90skysn3k/brutespray/actions/workflows/release.yml) Created by: Shane Young/@t1d3nio && Jacob Robles/@shellfail diff --git a/modules/wordlist.go b/modules/wordlist.go index ac1adb0..eb21296 100644 --- a/modules/wordlist.go +++ b/modules/wordlist.go @@ -91,6 +91,13 @@ func ReadPasswordsFromFile(filename string) ([]string, error) { func GetUsersFromDefaultWordlist(version string, serviceType string) []string { wordlistPath := filepath.Join("wordlist", serviceType, "user") url := fmt.Sprintf("https://raw.githubusercontent.com/x90skysn3k/brutespray/%s/wordlist/%s/user", version, serviceType) + + globalWordlistPath := filepath.Join("/usr/share/brutespray/wordlist", serviceType, "user") + + if _, err := os.Stat(globalWordlistPath); !os.IsNotExist(err) { + wordlistPath = globalWordlistPath + } + wordlistDir := filepath.Dir(wordlistPath) if _, err := os.Stat(wordlistDir); os.IsNotExist(err) { err := os.MkdirAll(wordlistDir, 0755) @@ -132,6 +139,12 @@ func GetPasswordsFromDefaultWordlist(version string, serviceType string) []strin wordlistPath := filepath.Join("wordlist", serviceType, "password") url := fmt.Sprintf("https://raw.githubusercontent.com/x90skysn3k/brutespray/%s/wordlist/%s/password", version, serviceType) + globalWordlistPath := filepath.Join("/usr/share/brutespray/wordlist", serviceType, "password") + + if _, err := os.Stat(globalWordlistPath); !os.IsNotExist(err) { + wordlistPath = globalWordlistPath + } + wordlistDir := filepath.Dir(wordlistPath) if _, err := os.Stat(wordlistDir); os.IsNotExist(err) { err := os.MkdirAll(wordlistDir, 0755) From dbc86157ccdcd4d99ae4ace637989880edfe6712 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Fri, 23 Feb 2024 12:10:01 -0800 Subject: [PATCH 05/14] added wordlist windows support --- modules/wordlist.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/wordlist.go b/modules/wordlist.go index eb21296..7c58601 100644 --- a/modules/wordlist.go +++ b/modules/wordlist.go @@ -6,7 +6,9 @@ import ( "io" "net/http" "os" + "os/user" "path/filepath" + "runtime" "github.com/pterm/pterm" ) @@ -98,6 +100,12 @@ func GetUsersFromDefaultWordlist(version string, serviceType string) []string { wordlistPath = globalWordlistPath } + if runtime.GOOS == "windows" { + currentUser, _ := user.Current() + appDataPath := filepath.Join(currentUser.HomeDir, "AppData", "Roaming") + wordlistPath = filepath.Join(appDataPath, "brutespray", "wordlist", serviceType, "user") + } + wordlistDir := filepath.Dir(wordlistPath) if _, err := os.Stat(wordlistDir); os.IsNotExist(err) { err := os.MkdirAll(wordlistDir, 0755) @@ -145,6 +153,12 @@ func GetPasswordsFromDefaultWordlist(version string, serviceType string) []strin wordlistPath = globalWordlistPath } + if runtime.GOOS == "windows" { + currentUser, _ := user.Current() + appDataPath := filepath.Join(currentUser.HomeDir, "AppData", "Roaming") + wordlistPath = filepath.Join(appDataPath, "brutespray", "wordlist", serviceType, "password") + } + wordlistDir := filepath.Dir(wordlistPath) if _, err := os.Stat(wordlistDir); os.IsNotExist(err) { err := os.MkdirAll(wordlistDir, 0755) From 72c4a616b830c0ba797710bfe168c38369969f6b Mon Sep 17 00:00:00 2001 From: t1d3nio <22178125+x90skysn3k@users.noreply.github.com> Date: Fri, 23 Feb 2024 14:23:26 -0800 Subject: [PATCH 06/14] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f7b8d21..1589e6b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # BruteSpray -![Version](https://img.shields.io/badge/Version-2.1.6-red)[![goreleaser](https://github.com/x90skysn3k/brutespray/actions/workflows/release.yml/badge.svg)](https://github.com/x90skysn3k/brutespray/actions/workflows/release.yml) +![Version](https://img.shields.io/badge/Version-2.1.6-red)[![goreleaser](https://github.com/x90skysn3k/brutespray/actions/workflows/release.yml/badge.svg)](https://github.com/x90skysn3k/brutespray/actions/workflows/release.yml)[![Go Report Card](https://goreportcard.com/badge/github.com/x90skysn3k/brutespray)](https://goreportcard.com/report/github.com/x90skysn3k/brutespray) Created by: Shane Young/@t1d3nio && Jacob Robles/@shellfail From 8cfbb0a358777d8266b5ef9d2d69fefcfa14d5d8 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Sat, 24 Feb 2024 10:06:08 -0800 Subject: [PATCH 07/14] testing parallelism --- brutespray/brutespray.go | 121 ++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 47 deletions(-) diff --git a/brutespray/brutespray.go b/brutespray/brutespray.go index 7e6a2a3..390a7c4 100644 --- a/brutespray/brutespray.go +++ b/brutespray/brutespray.go @@ -26,6 +26,7 @@ func Execute() { user := flag.String("u", "", "Username or user list to bruteforce") password := flag.String("p", "", "Password or password file to use for bruteforce") threads := flag.Int("t", 10, "Number of threads to use") + parallelhosts := flag.Int("T", 10, "Number of hosts to bruteforce at the same time") serviceType := flag.String("s", "all", "Service type: ssh, ftp, smtp, etc; Default all") listServices := flag.Bool("S", false, "List all supported services") file := flag.String("f", "", "File to parse; Supported: Nmap, Nessus, Nexpose, Lists, etc") @@ -105,7 +106,9 @@ func Execute() { bar, _ := pterm.DefaultProgressbar.WithTotal((totalCombinations) - nopassServices).WithTitle("Bruteforcing...").Start() var wg sync.WaitGroup var bruteForceWg sync.WaitGroup - sem := make(chan struct{}, *threads) + var parallelWg sync.WaitGroup + parallelCh := make(chan struct{}, *parallelhosts) + sem := make(chan struct{}, *threads**parallelhosts) sigs := make(chan os.Signal, 1) progressCh := make(chan int, totalCombinations) @@ -129,71 +132,95 @@ func Execute() { wg.Add(1) go func(service string) { defer wg.Done() + if *parallelhosts > 0 { + parallelWg.Add(len(hostsList)) + } if service == "vnc" || service == "snmp" { u := "" for _, h := range hostsList { + h := h if h.Service == service { - _, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) - stopChan := make(chan struct{}) - for _, p := range passwords { - wg.Add(1) - sem <- struct{}{} - go func(h modules.Host, p string) { - defer func() { - <-sem - wg.Done() - bruteForceWg.Done() - }() - - select { - case <-stopChan: - default: - brute.RunBrute(h, u, p, progressCh, *timeout, *retry) - bruteForceWg.Add(1) + if *parallelhosts > 0 { + parallelWg.Add(1) + go func(h modules.Host) { + _, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) + stopChan := make(chan struct{}) + for _, p := range passwords { + wg.Add(1) + sem <- struct{}{} + go func(h modules.Host, p string) { + defer func() { + <-sem + wg.Done() + bruteForceWg.Done() + }() + + select { + case <-stopChan: + default: + brute.RunBrute(h, u, p, progressCh, *timeout, *retry) + bruteForceWg.Add(1) + } + progressCh <- 1 + }(h, p) } - progressCh <- 1 - }(h, p) + parallelCh <- struct{}{} + }(h) } } + } } else { for _, h := range hostsList { + h := h if h.Service == service { - for _, alpha := range alphaServiceList { - if alpha == h.Service { - modules.PrintWarningAlpha(h.Service) - } - } - users, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) - stopChan := make(chan struct{}) - for _, u := range users { - for _, p := range passwords { - wg.Add(1) - sem <- struct{}{} - go func(h modules.Host, u, p string) { - defer func() { - <-sem - wg.Done() - bruteForceWg.Done() - }() - - select { - case <-stopChan: - return - default: - brute.RunBrute(h, u, p, progressCh, *timeout, *retry) - bruteForceWg.Add(1) + if *parallelhosts > 0 { + parallelWg.Add(1) + go func(h modules.Host) { + for _, alpha := range alphaServiceList { + if alpha == h.Service { + modules.PrintWarningAlpha(h.Service) + } + } + users, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) + stopChan := make(chan struct{}) + for _, u := range users { + for _, p := range passwords { + wg.Add(1) + sem <- struct{}{} + go func(h modules.Host, u, p string) { + defer func() { + <-sem + wg.Done() + bruteForceWg.Done() + }() + + select { + case <-stopChan: + return + default: + brute.RunBrute(h, u, p, progressCh, *timeout, *retry) + bruteForceWg.Add(1) + } + progressCh <- 1 + }(h, u, p) } - progressCh <- 1 - }(h, u, p) - } + } + parallelCh <- struct{}{} + }(h) } } } } + for i := 0; i < cap(parallelCh); i++ { + <-parallelCh + } }(service) } + if *parallelhosts > 0 { + parallelWg.Wait() + } wg.Wait() for i := 0; i < cap(sem); i++ { sem <- struct{}{} From a999f5de0bc793600de1d4d3668f488e93dd4597 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Sat, 24 Feb 2024 16:09:39 -0800 Subject: [PATCH 08/14] adding parallelism --- brutespray/brutespray.go | 129 +++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 67 deletions(-) diff --git a/brutespray/brutespray.go b/brutespray/brutespray.go index 390a7c4..5cf3d2d 100644 --- a/brutespray/brutespray.go +++ b/brutespray/brutespray.go @@ -20,13 +20,13 @@ var masterServiceList = []string{"ssh", "ftp", "smtp", "mssql", "telnet", "smbnt var alphaServiceList = []string{"asterisk"} -var version = "v2.1.5" +var version = "v2.1.6" func Execute() { user := flag.String("u", "", "Username or user list to bruteforce") password := flag.String("p", "", "Password or password file to use for bruteforce") threads := flag.Int("t", 10, "Number of threads to use") - parallelhosts := flag.Int("T", 10, "Number of hosts to bruteforce at the same time") + hostParallelism := flag.Int("T", 5, "Number of hosts to bruteforce at the same time") serviceType := flag.String("s", "all", "Service type: ssh, ftp, smtp, etc; Default all") listServices := flag.Bool("S", false, "List all supported services") file := flag.String("f", "", "File to parse; Supported: Nmap, Nessus, Nexpose, Lists, etc") @@ -106,9 +106,8 @@ func Execute() { bar, _ := pterm.DefaultProgressbar.WithTotal((totalCombinations) - nopassServices).WithTitle("Bruteforcing...").Start() var wg sync.WaitGroup var bruteForceWg sync.WaitGroup - var parallelWg sync.WaitGroup - parallelCh := make(chan struct{}, *parallelhosts) - sem := make(chan struct{}, *threads**parallelhosts) + sem := make(chan struct{}, *threads**hostParallelism) + hostSem := make(chan struct{}, *hostParallelism) sigs := make(chan os.Signal, 1) progressCh := make(chan int, totalCombinations) @@ -132,23 +131,65 @@ func Execute() { wg.Add(1) go func(service string) { defer wg.Done() - if *parallelhosts > 0 { - parallelWg.Add(len(hostsList)) - } if service == "vnc" || service == "snmp" { u := "" for _, h := range hostsList { h := h if h.Service == service { - if *parallelhosts > 0 { - parallelWg.Add(1) - go func(h modules.Host) { - _, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) - stopChan := make(chan struct{}) + _, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) + stopChan := make(chan struct{}) + hostSem <- struct{}{} + + go func() { + defer func() { <-hostSem }() + for _, p := range passwords { + p := p + wg.Add(1) + sem <- struct{}{} + + go func(h modules.Host, p string) { + defer func() { + <-sem + wg.Done() + bruteForceWg.Done() + }() + + select { + case <-stopChan: + default: + brute.RunBrute(h, u, p, progressCh, *timeout, *retry) + bruteForceWg.Add(1) + } + progressCh <- 1 + }(h, p) + } + }() + } + } + } else { + for _, h := range hostsList { + h := h + if h.Service == service { + for _, alpha := range alphaServiceList { + if alpha == h.Service { + modules.PrintWarningAlpha(h.Service) + } + } + + users, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) + stopChan := make(chan struct{}) + hostSem <- struct{}{} + + go func() { + defer func() { <-hostSem }() + for _, u := range users { + u := u for _, p := range passwords { + p := p wg.Add(1) sem <- struct{}{} - go func(h modules.Host, p string) { + + go func(h modules.Host, u, p string) { defer func() { <-sem wg.Done() @@ -157,71 +198,25 @@ func Execute() { select { case <-stopChan: + return default: brute.RunBrute(h, u, p, progressCh, *timeout, *retry) bruteForceWg.Add(1) } progressCh <- 1 - }(h, p) + }(h, u, p) } - parallelCh <- struct{}{} - }(h) - } + } + }() } - } - } else { - for _, h := range hostsList { - h := h - if h.Service == service { - if *parallelhosts > 0 { - parallelWg.Add(1) - go func(h modules.Host) { - for _, alpha := range alphaServiceList { - if alpha == h.Service { - modules.PrintWarningAlpha(h.Service) - } - } - users, passwords := modules.GetUsersAndPasswords(&h, *user, *password, version) - stopChan := make(chan struct{}) - for _, u := range users { - for _, p := range passwords { - wg.Add(1) - sem <- struct{}{} - go func(h modules.Host, u, p string) { - defer func() { - <-sem - wg.Done() - bruteForceWg.Done() - }() - - select { - case <-stopChan: - return - default: - brute.RunBrute(h, u, p, progressCh, *timeout, *retry) - bruteForceWg.Add(1) - } - progressCh <- 1 - }(h, u, p) - } - } - parallelCh <- struct{}{} - }(h) - } - } - } - } - for i := 0; i < cap(parallelCh); i++ { - <-parallelCh } }(service) } - - if *parallelhosts > 0 { - parallelWg.Wait() - } wg.Wait() + for i := 0; i < cap(hostSem); i++ { + hostSem <- struct{}{} + } for i := 0; i < cap(sem); i++ { sem <- struct{}{} } From 716726ad9f0d2856fad9b7d40b43013ecd9aea62 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Sat, 24 Feb 2024 16:34:26 -0800 Subject: [PATCH 09/14] added output flag --- brute/run.go | 6 +++--- brutespray/brutespray.go | 5 +++-- modules/output.go | 23 +++++++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/brute/run.go b/brute/run.go index 2667f6b..0eef47e 100644 --- a/brute/run.go +++ b/brute/run.go @@ -29,7 +29,7 @@ func MapService(service string) string { return service } -func RunBrute(h modules.Host, u string, p string, progressCh chan<- int, timeout time.Duration, retry int) bool { +func RunBrute(h modules.Host, u string, p string, progressCh chan<- int, timeout time.Duration, retry int, output string) bool { service := MapService(h.Service) var result bool var con_result bool @@ -75,9 +75,9 @@ func RunBrute(h modules.Host, u string, p string, progressCh chan<- int, timeout break } else { retrying := true - modules.PrintResult(service, h.Host, h.Port, u, p, result, con_result, progressCh, retrying) + modules.PrintResult(service, h.Host, h.Port, u, p, result, con_result, progressCh, retrying, output) } } - modules.PrintResult(service, h.Host, h.Port, u, p, result, con_result, progressCh, retrying) + modules.PrintResult(service, h.Host, h.Port, u, p, result, con_result, progressCh, retrying, output) return con_result } diff --git a/brutespray/brutespray.go b/brutespray/brutespray.go index 5cf3d2d..74759e6 100644 --- a/brutespray/brutespray.go +++ b/brutespray/brutespray.go @@ -25,6 +25,7 @@ var version = "v2.1.6" func Execute() { user := flag.String("u", "", "Username or user list to bruteforce") password := flag.String("p", "", "Password or password file to use for bruteforce") + output := flag.String("o", "brutespray-output", "Directory containing successful attempts") threads := flag.Int("t", 10, "Number of threads to use") hostParallelism := flag.Int("T", 5, "Number of hosts to bruteforce at the same time") serviceType := flag.String("s", "all", "Service type: ssh, ftp, smtp, etc; Default all") @@ -157,7 +158,7 @@ func Execute() { select { case <-stopChan: default: - brute.RunBrute(h, u, p, progressCh, *timeout, *retry) + brute.RunBrute(h, u, p, progressCh, *timeout, *retry, *output) bruteForceWg.Add(1) } progressCh <- 1 @@ -200,7 +201,7 @@ func Execute() { case <-stopChan: return default: - brute.RunBrute(h, u, p, progressCh, *timeout, *retry) + brute.RunBrute(h, u, p, progressCh, *timeout, *retry, *output) bruteForceWg.Add(1) } progressCh <- 1 diff --git a/modules/output.go b/modules/output.go index 7d70ebb..e647f54 100644 --- a/modules/output.go +++ b/modules/output.go @@ -4,7 +4,6 @@ import ( "fmt" "os" "path/filepath" - "time" "github.com/pterm/pterm" ) @@ -25,16 +24,22 @@ func getConResultString(con_result bool, retrying bool) string { } } -func WriteToFile(filename string, service string, content string) error { - timestamp := time.Now().Format("2006010215") - dir := "brutespray-output" +func WriteToFile(service string, content string, port int, output string) error { + var dir string = "./" + if output != "brutespray-output" { + dir = output + } else { + dir = output + } + if _, err := os.Stat(dir); os.IsNotExist(err) { err := os.Mkdir(dir, 0755) if err != nil { return err } } - filename = filepath.Join(dir, filename+"_"+service+"_"+timestamp+".txt") + + filename := filepath.Join(dir, fmt.Sprintf("%d-%s-success.txt", port, service)) file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return err @@ -48,22 +53,20 @@ func WriteToFile(filename string, service string, content string) error { return nil } -func PrintResult(service string, host string, port int, user string, pass string, result bool, con_result bool, progressCh chan<- int, retrying bool) { +func PrintResult(service string, host string, port int, user string, pass string, result bool, con_result bool, progressCh chan<- int, retrying bool, output string) { if result && con_result { if service == "vnc" { pterm.Success.Println("Attempt", service, "SUCCESS on host", host, "port", port, "with password", pass, getResultString(result)) content := fmt.Sprintf("Attempt %s SUCCESS on host %s port %d with password %s %s\n", service, host, port, pass, getResultString(result)) - filename := filepath.Base(host) - err := WriteToFile(filename, service, content) + err := WriteToFile(service, content, port, output) if err != nil { fmt.Println("write file error:", err) } } else { pterm.Success.Println("Attempt", service, "SUCCESS on host", host, "port", port, "with username", user, "and password", pass, getResultString(result)) content := fmt.Sprintf("Attempt %s SUCCESS on host %s port %d with username %s and password %s %s\n", service, host, port, user, pass, getResultString(result)) - filename := filepath.Base(host) - err := WriteToFile(filename, service, content) + err := WriteToFile(service, content, port, output) if err != nil { fmt.Println("write file error:", err) } From 51f0171882bd43464f30c12a7e3b9a051cd85499 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Sat, 24 Feb 2024 16:52:20 -0800 Subject: [PATCH 10/14] added connection fail delay --- brute/run.go | 8 ++++++-- modules/output.go | 15 +++++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/brute/run.go b/brute/run.go index 0eef47e..11528b5 100644 --- a/brute/run.go +++ b/brute/run.go @@ -1,6 +1,7 @@ package brute import ( + "math" "time" "github.com/x90skysn3k/brutespray/modules" @@ -34,6 +35,7 @@ func RunBrute(h modules.Host, u string, p string, progressCh chan<- int, timeout var result bool var con_result bool var retrying bool = false + var delayTime time.Duration = 1 * time.Second for i := 0; i < retry; i++ { switch service { @@ -74,10 +76,12 @@ func RunBrute(h modules.Host, u string, p string, progressCh chan<- int, timeout if con_result { break } else { + delayTime = time.Duration(int64(time.Second) * int64(math.Min(10, float64(i+2)))) retrying := true - modules.PrintResult(service, h.Host, h.Port, u, p, result, con_result, progressCh, retrying, output) + modules.PrintResult(service, h.Host, h.Port, u, p, result, con_result, progressCh, retrying, output, delayTime) + time.Sleep(delayTime) } } - modules.PrintResult(service, h.Host, h.Port, u, p, result, con_result, progressCh, retrying, output) + modules.PrintResult(service, h.Host, h.Port, u, p, result, con_result, progressCh, retrying, output, delayTime) return con_result } diff --git a/modules/output.go b/modules/output.go index e647f54..1038b26 100644 --- a/modules/output.go +++ b/modules/output.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "time" "github.com/pterm/pterm" ) @@ -16,9 +17,15 @@ func getResultString(result bool) string { } } -func getConResultString(con_result bool, retrying bool) string { +func getConResultString(con_result bool, retrying bool, delayTime time.Duration) string { + var delaying bool + if delayTime > 2 { + delaying = true + } if !retrying { return "connection failed, giving up..." + } else if retrying && delaying { + return fmt.Sprintf("connection failed, retrying... delayed %s", delayTime) } else { return "connection failed, retrying..." } @@ -53,7 +60,7 @@ func WriteToFile(service string, content string, port int, output string) error return nil } -func PrintResult(service string, host string, port int, user string, pass string, result bool, con_result bool, progressCh chan<- int, retrying bool, output string) { +func PrintResult(service string, host string, port int, user string, pass string, result bool, con_result bool, progressCh chan<- int, retrying bool, output string, delayTime time.Duration) { if result && con_result { if service == "vnc" { @@ -79,9 +86,9 @@ func PrintResult(service string, host string, port int, user string, pass string } } else if !result && !con_result { if service == "vnc" { - pterm.Color(pterm.FgRed).Println("Attempt", service, "on host", host, "port", port, "with password", pass, getConResultString(con_result, retrying)) + pterm.Color(pterm.FgRed).Println("Attempt", service, "on host", host, "port", port, "with password", pass, getConResultString(con_result, retrying, delayTime)) } else { - pterm.Color(pterm.FgRed).Println("Attempt", service, "on host", host, "port", port, "with username", user, "and password", pass, getConResultString(con_result, retrying)) + pterm.Color(pterm.FgRed).Println("Attempt", service, "on host", host, "port", port, "with username", user, "and password", pass, getConResultString(con_result, retrying, delayTime)) } } } From 521ad2b2f7e8b58919583e5d42aa20e0bd0a5799 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Sat, 24 Feb 2024 16:54:48 -0800 Subject: [PATCH 11/14] small readme fix --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 1589e6b..d816d07 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ Command: ```brutespray -f nmap.xml -u userlist -p passlist``` Command: ```brutespray -H ssh://127.0.0.1:22 -u userlist -p passlist``` - ## Examples From 97985a221a5be7f87b9ed393e70c059e841796a4 Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Sat, 24 Feb 2024 16:55:51 -0800 Subject: [PATCH 12/14] lint fix --- modules/output.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/output.go b/modules/output.go index 1038b26..a336baf 100644 --- a/modules/output.go +++ b/modules/output.go @@ -32,7 +32,7 @@ func getConResultString(con_result bool, retrying bool, delayTime time.Duration) } func WriteToFile(service string, content string, port int, output string) error { - var dir string = "./" + var dir string if output != "brutespray-output" { dir = output } else { From 6c09cca51f3cfeb0bcc8fbbebf0a4e615e14b00e Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Sat, 24 Feb 2024 16:57:39 -0800 Subject: [PATCH 13/14] dependabot --- .github/dependabot.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..2483161 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + target-branch: "dev" + schedule: + interval: "weekly" + + - package-ecosystem: "github-actions" + directory: "/" + target-branch: "dev" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" + From b88736229d8665e1ffca84c860389f9faa76386d Mon Sep 17 00:00:00 2001 From: t1d3nio Date: Sat, 24 Feb 2024 17:00:00 -0800 Subject: [PATCH 14/14] docker --- .github/workflows/docker.yml | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..00d901f --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,42 @@ +name: Build Docker Images + +on: + push: + branches: + - main + workflow_dispatch: + schedule: + - cron: "0 0 * * *" + +jobs: + Dockerhub: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: checkout sources + uses: actions/checkout@v3 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v4 + with: + push: true + platforms: linux/amd64,linux/arm/v7,linux/arm64/v8,linux/386,linux/ppc64le + tags: | + ghcr.io/x90skysn3k/brutespray:latest +