Skip to content

Commit

Permalink
fixed GhostTroops#165 and fuzz bug 2023-12-21
Browse files Browse the repository at this point in the history
  • Loading branch information
hktalent committed Dec 21, 2023
1 parent 096ef3d commit be8422e
Show file tree
Hide file tree
Showing 698 changed files with 5,848 additions and 5,969 deletions.
3 changes: 3 additions & 0 deletions brute/admin_brute.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/url"
"regexp"
"strings"
"time"
)

var SkipAdminBrute bool
Expand Down Expand Up @@ -122,6 +123,7 @@ func Admin_brute(u string) (username string, password string, loginurl string) {
adminfalseContentlen = adminfalseurl.ContentLength
default:
falseis500 = true
time.Sleep(3 * time.Millisecond)
}
} else {
falseis500 = true
Expand All @@ -146,6 +148,7 @@ func Admin_brute(u string) (username string, password string, loginurl string) {
testfalseContentlen = testfalseurl.ContentLength
default:
falseis500 = true
time.Sleep(3 * time.Millisecond)
}
} else {
falseis500 = true
Expand Down
1 change: 0 additions & 1 deletion brute/bypass403.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ BreakAll:
break BreakAll
}
}
time.Sleep(33 * time.Second)
}
return aR
}
227 changes: 119 additions & 108 deletions brute/filefuzz.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
"github.com/GhostTroops/scan4all/lib/util"
"github.com/GhostTroops/scan4all/pkg/fingerprint"
"github.com/antlabs/strsim"
"io/ioutil"
"log"
"mime"
"net/url"
"os"
"path/filepath"
"regexp"
"strings"
Expand Down Expand Up @@ -123,14 +123,14 @@ var regs []string
var (
regsMap = make(map[string]*regexp.Regexp) // fuzz 正则库
disabledFileFuzz = false // 是否开启fuzz
NoDoPath = sync.Map{}
NoDoPath sync.Map
NoDoPathInit = false
)

func DoInitMap() {
if NoDoPathInit == false && "" != fingerprint.FgDictFile {
NoDoPathInit = true
if data, err := ioutil.ReadFile(fingerprint.FgDictFile); nil == err {
if data, err := os.ReadFile(fingerprint.FgDictFile); nil == err {
a := strings.Split(strings.TrimSpace(string(data)), "\n")
for _, k := range a {
NoDoPath.Store(k, true)
Expand Down Expand Up @@ -181,13 +181,23 @@ type FuzzData struct {
}

// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
var r001 = regexp.MustCompile(`\.(aac)|(abw)|(arc)|(avif)|(avi)|(azw)|(bin)|(bmp)|(bz)|(bz2)|(cda)|(csh)|(css)|(csv)|(doc)|(docx)|(eot)|(epub)|(gz)|(gif)|(ico)|(ics)|(jar)|(jpeg)|(jpg)|(js)|(json)|(jsonld)|(mid)|(midi)|(mjs)|(mp3)|(mp4)|(mpeg)|(mpkg)|(odp)|(ods)|(odt)|(oga)|(ogv)|(ogx)|(opus)|(otf)|(png)|(pdf)|(php)|(ppt)|(pptx)|(rar)|(rtf)|(sh)|(svg)|(tar)|(tif)|(tiff)|(ts)|(ttf)|(txt)|(vsd)|(wav)|(weba)|(webm)|(webp)|(woff)|(woff2)|(xhtml)|(xls)|(xlsx)|(xml)|(xul)|(zip)|(3gp)|(3g2)|(7z)$`)
var (
r001 = regexp.MustCompile(`\.(aac)|(abw)|(arc)|(avif)|(avi)|(azw)|(bin)|(bmp)|(bz)|(bz2)|(cda)|(csh)|(css)|(csv)|(doc)|(docx)|(eot)|(epub)|(gz)|(gif)|(ico)|(ics)|(jar)|(jpeg)|(jpg)|(js)|(json)|(jsonld)|(mid)|(midi)|(mjs)|(mp3)|(mp4)|(mpeg)|(mpkg)|(odp)|(ods)|(odt)|(oga)|(ogv)|(ogx)|(opus)|(otf)|(png)|(pdf)|(php)|(ppt)|(pptx)|(rar)|(rtf)|(sh)|(svg)|(tar)|(tif)|(tiff)|(ts)|(ttf)|(txt)|(vsd)|(wav)|(weba)|(webm)|(webp)|(woff)|(woff2)|(xhtml)|(xls)|(xlsx)|(xml)|(xul)|(zip)|(3gp)|(3g2)|(7z)$`)
cT1 = make(chan struct{}, 1) // 每次只允许1个url fuzz
)

// 重写了fuzz:优化流程、优化算法、修复线程安全bug、增加智能功能
//
// 两次 ioutil.ReadAll(resp.Body),第二次就会 Read返回EOF error
// 去除指纹请求的路径,避免重复
func FileFuzz(u string, indexStatusCode int, indexContentLength int, indexbody string) ([]string, []string) {
if util.TestRepeat(u) {
return []string{}, []string{}
}
cT1 <- struct{}{}
defer func() {
<-cT1
}()
if disabledFileFuzz {
return []string{}, []string{}
}
Expand Down Expand Up @@ -233,7 +243,9 @@ func FileFuzz(u string, indexStatusCode int, indexContentLength int, indexbody s
}
var wg sync.WaitGroup
// 中途控制关闭当前目标所有fuzz
// 终止fuzz任务
ctx, stop := context.WithCancel(util.Ctx_global)
// 终止 接收结果任务
ctx2, stop2 := context.WithCancel(util.Ctx_global)
// 控制 fuzz 线程数
var ch = make(chan struct{}, util.Fuzzthreads)
Expand All @@ -245,6 +257,7 @@ func FileFuzz(u string, indexStatusCode int, indexContentLength int, indexbody s
if strings.HasPrefix(url404req.Protocol, "HTTP/2") || strings.HasPrefix(url404req.Protocol, "HTTP/3") {
MaxErrorTimes = int32(len(filedic))
}
//var MaxErrorTimes int32 = 100
if c1 := util.GetClient(u, map[string]interface{}{"Timeout": 15 * time.Second, "ErrLimit": MaxErrorTimes}); nil != c1 {
util.PutClientCc(u, c1)
}
Expand All @@ -258,7 +271,9 @@ func FileFuzz(u string, indexStatusCode int, indexContentLength int, indexbody s
var lst200 *util.Response
t001 := time.NewTicker(3 * time.Second)
var nCnt int32 = 0
// 异步 接收 fuzz 结果
go func() {
defer stop()
for {
select {
case <-ctx2.Done():
Expand Down Expand Up @@ -288,8 +303,6 @@ func FileFuzz(u string, indexStatusCode int, indexContentLength int, indexbody s
} else {
return
}
default:
time.Sleep(33 * time.Second)
// <-time.After(time.Duration(100) * time.Millisecond)
}
}
Expand All @@ -304,135 +317,133 @@ BreakAll:
continue
}
// 接收到停止信号
if atomic.LoadInt32(&errorTimes) >= MaxErrorTimes {
if errorTimes >= MaxErrorTimes {
stop()
break
}
select {
case <-ctx.Done():
break BreakAll
default:
{
//log.Println(u, " ", payload)
endP := u[len(u)-1:] == "/"
ch <- struct{}{}
wg.Add(1)
go func(payload string) {
payload = strings.TrimSpace(payload)
defer func() {
wg.Done() // 控制所有线程结束
<-ch // 并发控制
<-ch // 并发控制
wg.Done()
}()
atomic.AddInt32(&nCnt, 1)
for {
select {
case <-ctx.Done(): // 00-捕获所有线程关闭信号,并退出,close for all
atomic.AddInt32(&errorTimes, MaxErrorTimes)
select {
case <-ctx.Done(): // 00-捕获所有线程关闭信号,并退出,close for all
atomic.AddInt32(&errorTimes, MaxErrorTimes)
return
default:
//if _, ok := noRpt.Load(szKey001Over); ok {
// stop()
// return
//}
// 01-异常>20关闭所有fuzz
if errorTimes >= MaxErrorTimes {
stop() //发停止指令
return
default:
//if _, ok := noRpt.Load(szKey001Over); ok {
// stop()
// return
}
// 修复url,默认 认为 payload 不包含/
szUrl := u + payload
if strings.HasPrefix(payload, "/") && endP {
szUrl = u + payload[1:]
}
//log.Printf("start fuzz: [%s]", szUrl)
if fuzzPage, req, err := reqPage(szUrl); err == nil && nil != req && 0 < len(req.Body) {
if 200 == req.StatusCode {
if nil == lst200 {
lst200 = req
} else if lst200.Body == req.Body { // 无意义的 200
return
}
if oU1, err := url.Parse(szUrl); nil == err {
a50 := r001.FindStringSubmatch(oU1.Path)
if 0 < len(a50) {
s2 := mime.TypeByExtension(filepath.Ext(a50[0]))
ct := (*req).Header.Get("Content-Type")
if "" != ct && "" != s2 && strings.Contains(ct, s2) {
return
}
}
}
//log.Printf("%d : %s \n", req.StatusCode, szUrl)
if IsLoginPage(szUrl, req.Body, req.StatusCode) {
technologies = append(technologies, "loginpage")
}
}
go util.CheckHeader(req.Header, u)
// 02-状态码和req1相同,且与req1相似度>9.5,关闭所有fuzz
fXsd := strsim.Compare(url404req.Body, req.Body)
bBig95 := 0.95 < fXsd
//if "/bea_wls_internal/classes/mejb@/org/omg/stub/javax/management/j2ee/_ManagementHome_Stub.class" == payload {
// log.Println("start debug")
//}
// 01-异常>20关闭所有fuzz
if atomic.LoadInt32(&errorTimes) >= MaxErrorTimes {
if url404.StatusCode == fuzzPage.StatusCode && bBig95 {
stop() //发停止指令
atomic.AddInt32(&errorTimes, MaxErrorTimes)
return
}
// 修复url,默认 认为 payload 不包含/
szUrl := u + payload
if strings.HasPrefix(payload, "/") && endP {
szUrl = u + payload[1:]
}
//log.Printf("start fuzz: [%s]", szUrl)
if fuzzPage, req, err := reqPage(szUrl); err == nil && nil != req && 0 < len(req.Body) {
if 200 == req.StatusCode {
if nil == lst200 {
lst200 = req
} else if lst200.Body == req.Body { // 无意义的 200
continue
}
if oU1, err := url.Parse(szUrl); nil == err {
a50 := r001.FindStringSubmatch(oU1.Path)
if 0 < len(a50) {
s2 := mime.TypeByExtension(filepath.Ext(a50[0]))
ct := (*req).Header.Get("Content-Type")
if "" != ct && "" != s2 && strings.Contains(ct, s2) {
continue
}
}
}
//log.Printf("%d : %s \n", req.StatusCode, szUrl)
if IsLoginPage(szUrl, req.Body, req.StatusCode) {
technologies = append(technologies, "loginpage")
}
var path1, technologies1 = []string{}, []string{}
// 03-异常页面(>400),或相似度与404匹配
if fuzzPage.StatusCode >= 400 || bBig95 || fuzzPage.StatusCode != 200 {
// 03.01-异常页面指纹匹配
technologies = Addfingerprints404(technologies, req, fuzzPage) //基于404页面文件扫描指纹添加
// 03.02-与绝对404相似度低于0.8,添加body 404 body list
// 03.03-添加404titlelist
if 0.8 > fXsd && fuzzPage.StatusCode != 200 && fuzzPage.StatusCode != url404.StatusCode {
StudyErrPageAI(req, fuzzPage, "") // 异常页面学习
}
go util.CheckHeader(req.Header, u)
// 02-状态码和req1相同,且与req1相似度>9.5,关闭所有fuzz
fXsd := strsim.Compare(url404req.Body, req.Body)
bBig95 := 9.5 < fXsd
//if "/bea_wls_internal/classes/mejb@/org/omg/stub/javax/management/j2ee/_ManagementHome_Stub.class" == payload {
// log.Println("start debug")
//}
if url404.StatusCode == fuzzPage.StatusCode && bBig95 {
stop() //发停止指令
atomic.AddInt32(&errorTimes, MaxErrorTimes)
return
}
var path1, technologies1 = []string{}, []string{}
// 03-异常页面(>400),或相似度与404匹配
if fuzzPage.StatusCode >= 400 || bBig95 || fuzzPage.StatusCode != 200 {
// 03.01-异常页面指纹匹配
technologies = Addfingerprints404(technologies, req, fuzzPage) //基于404页面文件扫描指纹添加
// 03.02-与绝对404相似度低于0.8,添加body 404 body list
// 03.03-添加404titlelist
if 0.8 > fXsd && fuzzPage.StatusCode != 200 && fuzzPage.StatusCode != url404.StatusCode {
StudyErrPageAI(req, fuzzPage, "") // 异常页面学习
}
// 04-403: 403 by pass
if fuzzPage.Is403 && !url404.Is403 {
a11 := ByPass403(&u, &payload, &wg)
// 表示 ByPass403 成功了, 结果、控制台输出点什么?
if 0 < len(a11) {
async_data <- &FuzzData{Path: &a11, Req: fuzzPage}
}
// 04-403: 403 by pass
if fuzzPage.Is403 && !url404.Is403 {
a11 := ByPass403(&u, &payload, &wg)
// 表示 ByPass403 成功了, 结果、控制台输出点什么?
if 0 < len(a11) {
async_data <- &FuzzData{Path: &a11, Req: fuzzPage}
}
return
}
// 当前和绝对404不等于404,后续的比较也没有意义了,都等于[200,301,302]都没有意义了,都说明没有fuzz成功
if url404.StatusCode != 404 && url404.StatusCode == fuzzPage.StatusCode {
return
}
return
}
// 当前和绝对404不等于404,后续的比较也没有意义了,都等于[200,301,302]都没有意义了,都说明没有fuzz成功
if url404.StatusCode != 404 && url404.StatusCode == fuzzPage.StatusCode {
return
}

// 05-跳转检测,即便是跳转,如果和绝对404不一样,说明检测成功
//if CheckDirckt(fuzzPage, req) && url404.StatusCode != fuzzPage.StatusCode {
// return
// 05-跳转检测,即便是跳转,如果和绝对404不一样,说明检测成功
//if CheckDirckt(fuzzPage, req) && url404.StatusCode != fuzzPage.StatusCode {
// return
//}
// 1、状态码和绝对404一样 2、智能识别算出来
is404Page := url404.StatusCode == fuzzPage.StatusCode || CheckIsErrPageAI(req, fuzzPage)
// 06-成功页面, 非异常页面
if !is404Page || 200 == fuzzPage.StatusCode && url404.StatusCode != fuzzPage.StatusCode {
// 1、指纹匹配
technologies1 = Addfingerprintsnormal(payload, technologies1, req, fuzzPage) // 基于200页面文件扫描指纹添加
// 2、成功fuzz路径结果添加
path1 = append(path1, *fuzzPage.Url)
}
if 0 < len(path1) {
async_data <- &FuzzData{Path: &path1, Req: fuzzPage}
}
if 0 < len(technologies1) {
async_technologies <- technologies1
}
} else { // 这里应该元子操作
if nil != err {
//if nil != client && strings.Contains(err.Error(), " connect: connection reset by peer") {
// client.Client = client.GetClient(nil)
//}
// 1、状态码和绝对404一样 2、智能识别算出来
is404Page := url404.StatusCode == fuzzPage.StatusCode || CheckIsErrPageAI(req, fuzzPage)
// 06-成功页面, 非异常页面
if !is404Page || 200 == fuzzPage.StatusCode && url404.StatusCode != fuzzPage.StatusCode {
// 1、指纹匹配
technologies1 = Addfingerprintsnormal(payload, technologies1, req, fuzzPage) // 基于200页面文件扫描指纹添加
// 2、成功fuzz路径结果添加
path1 = append(path1, *fuzzPage.Url)
}
if 0 < len(path1) {
async_data <- &FuzzData{Path: &path1, Req: fuzzPage}
}
if 0 < len(technologies1) {
async_technologies <- technologies1
}
} else { // 这里应该元子操作
if nil != err {
//if nil != client && strings.Contains(err.Error(), " connect: connection reset by peer") {
// client.Client = client.GetClient(nil)
//}
//log.Printf("file fuzz %s is err %v\n", szUrl, err)
}
atomic.AddInt32(&errorTimes, 1)
//log.Printf("file fuzz %s is err %v\n", szUrl, err)
}
return
atomic.AddInt32(&errorTimes, 1)
}
return
}
}(payload)
}
Expand Down
9 changes: 5 additions & 4 deletions config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"LimitReader": 819200,
"OnClient": true,
"ScanPoolSize":5000,
"MaxErrorTimes": 100,
"JndiAddress": "docker.for.mac.localhost:1389",
"CeyeDomain": "scan4all.51pwn.com",
"CacheName": ".DbCache",
Expand Down Expand Up @@ -78,9 +79,9 @@
"enableMultNuclei": false,
"enableNuclei": true,
"enableByWaf": true,
"enableDevDebug": false,
"enableDevDebug": true,
"enableEmbedYaml": true,
"enableFileFuzz": false,
"enableFileFuzz": true,
"httpx": {
"Pipeline": false,
"HTTP2Probe": false,
Expand All @@ -95,13 +96,13 @@
"CheckWeakPassword": true,
"esthread": 8,
"hydrathread": 64,
"Fuzzthreads": 16,
"Fuzzthreads": 8,
"enableFingerTitleHeaderMd5Hex": false,
"Cookie": "",
"esUrl": "https://127.0.0.1:8081/%s_index/_doc/%s",
"Exploit":{
"Path": "./config/poc/",
"Logs": "./logs/errror.log"
},
"enableWebScan": true
"enableWebScan": false
}
Loading

0 comments on commit be8422e

Please sign in to comment.