mirror of
https://github.com/chainreactors/spray.git
synced 2025-07-12 17:33:26 +00:00
misc update, 初步可用
This commit is contained in:
parent
637eb21377
commit
ea3ea58dd2
@ -15,7 +15,6 @@ func NewBaseline(u *fasthttp.URI, resp *fasthttp.Response) *baseline {
|
|||||||
UrlString: u.String(),
|
UrlString: u.String(),
|
||||||
Status: resp.StatusCode(),
|
Status: resp.StatusCode(),
|
||||||
IsValid: true,
|
IsValid: true,
|
||||||
Body: make([]byte, 20480),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bl.Body = resp.Body()
|
bl.Body = resp.Body()
|
||||||
@ -31,9 +30,8 @@ func NewInvalidBaseline(u *fasthttp.URI, resp *fasthttp.Response) *baseline {
|
|||||||
bl := &baseline{
|
bl := &baseline{
|
||||||
Url: u,
|
Url: u,
|
||||||
UrlString: u.String(),
|
UrlString: u.String(),
|
||||||
//BodyLength: resp.ContentLength,
|
Status: resp.StatusCode(),
|
||||||
Status: resp.StatusCode(),
|
IsValid: false,
|
||||||
IsValid: false,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bl.RedirectURL = string(resp.Header.Peek("Location"))
|
bl.RedirectURL = string(resp.Header.Peek("Location"))
|
||||||
@ -95,7 +93,7 @@ func (bl *baseline) FuzzyEqual(other *baseline) bool {
|
|||||||
|
|
||||||
func (bl *baseline) String() string {
|
func (bl *baseline) String() string {
|
||||||
var line strings.Builder
|
var line strings.Builder
|
||||||
line.WriteString("[+] ")
|
//line.WriteString("[+] ")
|
||||||
line.WriteString(bl.UrlString)
|
line.WriteString(bl.UrlString)
|
||||||
line.WriteString(fmt.Sprintf(" - %d - %d ", bl.Status, bl.BodyLength))
|
line.WriteString(fmt.Sprintf(" - %d - %d ", bl.Status, bl.BodyLength))
|
||||||
if bl.RedirectURL != "" {
|
if bl.RedirectURL != "" {
|
||||||
@ -104,7 +102,11 @@ func (bl *baseline) String() string {
|
|||||||
}
|
}
|
||||||
line.WriteString(bl.Frameworks.ToString())
|
line.WriteString(bl.Frameworks.ToString())
|
||||||
//line.WriteString(bl.Extracteds)
|
//line.WriteString(bl.Extracteds)
|
||||||
line.WriteString("\n")
|
//line.WriteString("\n")
|
||||||
|
if bl.Err != nil {
|
||||||
|
line.WriteString("err: ")
|
||||||
|
line.WriteString(bl.Err.Error())
|
||||||
|
}
|
||||||
return line.String()
|
return line.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,19 +30,21 @@ func NewPool(ctx context.Context, config *pkg.Config, outputCh chan *baseline) (
|
|||||||
worder: words.NewWorder(config.Wordlist),
|
worder: words.NewWorder(config.Wordlist),
|
||||||
outputCh: outputCh,
|
outputCh: outputCh,
|
||||||
tempCh: make(chan *baseline, config.Thread),
|
tempCh: make(chan *baseline, config.Thread),
|
||||||
wg: &sync.WaitGroup{},
|
wg: sync.WaitGroup{},
|
||||||
|
initwg: sync.WaitGroup{},
|
||||||
checkPeriod: 100,
|
checkPeriod: 100,
|
||||||
errPeriod: 10,
|
errPeriod: 10,
|
||||||
|
//reqCount: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch config.Mod {
|
switch config.Mod {
|
||||||
case pkg.PathSpray:
|
case pkg.PathSpray:
|
||||||
pool.genReq = func(s string) (*fasthttp.Request, error) {
|
pool.genReq = func(s string) (*fasthttp.Request, error) {
|
||||||
return pool.BuildPathRequest(s)
|
return pool.buildPathRequest(s)
|
||||||
}
|
}
|
||||||
case pkg.HostSpray:
|
case pkg.HostSpray:
|
||||||
pool.genReq = func(s string) (*fasthttp.Request, error) {
|
pool.genReq = func(s string) (*fasthttp.Request, error) {
|
||||||
return pool.BuildHostRequest(s)
|
return pool.buildHostRequest(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,12 +57,11 @@ func NewPool(ctx context.Context, config *pkg.Config, outputCh chan *baseline) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
var bl *baseline
|
var bl *baseline
|
||||||
resp, err := pool.client.Do(pctx, req)
|
resp, reqerr := pool.client.Do(pctx, req)
|
||||||
if err != nil {
|
if reqerr != nil && reqerr != fasthttp.ErrBodyTooLarge {
|
||||||
//logs.Log.Debugf("%s request error, %s", strurl, err.Error())
|
//logs.Log.Debugf("%s request error, %s", strurl, err.Error())
|
||||||
pool.errorCount++
|
pool.errorCount++
|
||||||
bl = &baseline{Err: err}
|
bl = &baseline{UrlString: pool.BaseURL + unit.path, Err: reqerr}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
defer fasthttp.ReleaseResponse(resp)
|
defer fasthttp.ReleaseResponse(resp)
|
||||||
defer fasthttp.ReleaseRequest(req)
|
defer fasthttp.ReleaseRequest(req)
|
||||||
@ -71,22 +72,32 @@ func NewPool(ctx context.Context, config *pkg.Config, outputCh chan *baseline) (
|
|||||||
} else {
|
} else {
|
||||||
bl = NewInvalidBaseline(req.URI(), resp)
|
bl = NewInvalidBaseline(req.URI(), resp)
|
||||||
}
|
}
|
||||||
|
bl.Err = reqerr
|
||||||
}
|
}
|
||||||
|
|
||||||
switch unit.source {
|
switch unit.source {
|
||||||
case CheckSource:
|
case CheckSource:
|
||||||
if pool.baseline == nil {
|
logs.Log.Debugf("check: " + bl.String())
|
||||||
|
if pool.base == nil {
|
||||||
//初次check覆盖baseline
|
//初次check覆盖baseline
|
||||||
pool.baseline = bl
|
pool.base = bl
|
||||||
|
pool.initwg.Done()
|
||||||
} else if bl.Err != nil {
|
} else if bl.Err != nil {
|
||||||
logs.Log.Warn("maybe ip banned by waf")
|
logs.Log.Warn("maybe ip banned by waf")
|
||||||
} else if !pool.baseline.Equal(bl) {
|
} else if !pool.base.Equal(bl) {
|
||||||
logs.Log.Warn("maybe trigger risk control")
|
logs.Log.Warn("maybe trigger risk control")
|
||||||
}
|
}
|
||||||
|
|
||||||
case WordSource:
|
case WordSource:
|
||||||
// 异步进行性能消耗较大的深度对比
|
// 异步进行性能消耗较大的深度对比
|
||||||
|
pool.reqCount++
|
||||||
pool.tempCh <- bl
|
pool.tempCh <- bl
|
||||||
|
|
||||||
|
if pool.reqCount%pool.checkPeriod == 0 {
|
||||||
|
go pool.check()
|
||||||
|
} else if pool.reqCount%pool.errPeriod == 0 {
|
||||||
|
go pool.check()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//todo connectivity check
|
//todo connectivity check
|
||||||
pool.bar.Done()
|
pool.bar.Done()
|
||||||
@ -108,7 +119,7 @@ type Pool struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
//baseReq *http.Request
|
//baseReq *http.Request
|
||||||
baseline *baseline
|
base *baseline
|
||||||
outputCh chan *baseline
|
outputCh chan *baseline
|
||||||
tempCh chan *baseline
|
tempCh chan *baseline
|
||||||
reqCount int
|
reqCount int
|
||||||
@ -116,18 +127,16 @@ type Pool struct {
|
|||||||
failedCount int
|
failedCount int
|
||||||
checkPeriod int
|
checkPeriod int
|
||||||
errPeriod int
|
errPeriod int
|
||||||
|
analyzeDone bool
|
||||||
genReq func(s string) (*fasthttp.Request, error)
|
genReq func(s string) (*fasthttp.Request, error)
|
||||||
//wordlist []string
|
worder *words.Worder
|
||||||
worder *words.Worder
|
wg sync.WaitGroup
|
||||||
wg *sync.WaitGroup
|
initwg sync.WaitGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool) check() {
|
func (p *Pool) check() {
|
||||||
var wg sync.WaitGroup
|
p.wg.Add(1)
|
||||||
wg.Add(1)
|
|
||||||
_ = p.pool.Invoke(newUnit(pkg.RandPath(), CheckSource))
|
_ = p.pool.Invoke(newUnit(pkg.RandPath(), CheckSource))
|
||||||
//}
|
|
||||||
wg.Wait()
|
|
||||||
|
|
||||||
if p.failedCount > breakThreshold {
|
if p.failedCount > breakThreshold {
|
||||||
p.cancel()
|
p.cancel()
|
||||||
@ -135,20 +144,21 @@ func (p *Pool) check() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool) Init() error {
|
func (p *Pool) Init() error {
|
||||||
|
p.initwg.Add(1)
|
||||||
p.check()
|
p.check()
|
||||||
|
p.initwg.Wait()
|
||||||
// todo 分析baseline
|
// todo 分析baseline
|
||||||
// 检测基本访问能力
|
// 检测基本访问能力
|
||||||
|
|
||||||
if p.baseline != nil && p.baseline.Err != nil {
|
if p.base != nil && p.base.Err != nil {
|
||||||
p.cancel()
|
p.cancel()
|
||||||
return p.baseline.Err
|
return p.base.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
p.baseline.Collect()
|
p.base.Collect()
|
||||||
|
if p.base.RedirectURL != "" {
|
||||||
if p.baseline.RedirectURL != "" {
|
|
||||||
CheckRedirect = func(redirectURL string) bool {
|
CheckRedirect = func(redirectURL string) bool {
|
||||||
if redirectURL == p.baseline.RedirectURL {
|
if redirectURL == p.base.RedirectURL {
|
||||||
// 相同的RedirectURL将被认为是无效数据
|
// 相同的RedirectURL将被认为是无效数据
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
@ -170,13 +180,7 @@ Loop:
|
|||||||
if !ok {
|
if !ok {
|
||||||
break Loop
|
break Loop
|
||||||
}
|
}
|
||||||
p.reqCount++
|
|
||||||
p.wg.Add(1)
|
p.wg.Add(1)
|
||||||
if p.reqCount%p.checkPeriod == 0 {
|
|
||||||
go p.check()
|
|
||||||
} else if p.reqCount%p.errPeriod == 0 {
|
|
||||||
go p.check()
|
|
||||||
}
|
|
||||||
_ = p.pool.Invoke(newUnit(u, WordSource))
|
_ = p.pool.Invoke(newUnit(u, WordSource))
|
||||||
case <-time.NewTimer(time.Duration(p.DeadlineTime) * time.Second).C:
|
case <-time.NewTimer(time.Duration(p.DeadlineTime) * time.Second).C:
|
||||||
break Loop
|
break Loop
|
||||||
@ -186,8 +190,8 @@ Loop:
|
|||||||
break Loop
|
break Loop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.bar.Close()
|
|
||||||
p.wg.Wait()
|
p.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool) PreCompare(resp *fasthttp.Response) error {
|
func (p *Pool) PreCompare(resp *fasthttp.Response) error {
|
||||||
@ -212,7 +216,7 @@ func (p *Pool) RunWithWord(words []string) {
|
|||||||
|
|
||||||
func (p *Pool) Comparing() {
|
func (p *Pool) Comparing() {
|
||||||
for bl := range p.tempCh {
|
for bl := range p.tempCh {
|
||||||
if p.baseline.Equal(bl) {
|
if p.base.Equal(bl) {
|
||||||
// 如果是同一个包则设置为无效包
|
// 如果是同一个包则设置为无效包
|
||||||
bl.IsValid = false
|
bl.IsValid = false
|
||||||
p.outputCh <- bl
|
p.outputCh <- bl
|
||||||
@ -220,7 +224,7 @@ func (p *Pool) Comparing() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bl.Collect()
|
bl.Collect()
|
||||||
if p.EnableFuzzy && p.baseline.FuzzyEqual(bl) {
|
if p.EnableFuzzy && p.base.FuzzyEqual(bl) {
|
||||||
bl.IsValid = false
|
bl.IsValid = false
|
||||||
p.outputCh <- bl
|
p.outputCh <- bl
|
||||||
continue
|
continue
|
||||||
@ -228,15 +232,25 @@ func (p *Pool) Comparing() {
|
|||||||
|
|
||||||
p.outputCh <- bl
|
p.outputCh <- bl
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Pool) BuildPathRequest(path string) (*fasthttp.Request, error) {
|
p.analyzeDone = true
|
||||||
|
}
|
||||||
|
func (p *Pool) Close() {
|
||||||
|
p.wg.Wait()
|
||||||
|
p.bar.Close()
|
||||||
|
|
||||||
|
close(p.tempCh)
|
||||||
|
for !p.analyzeDone {
|
||||||
|
time.Sleep(time.Duration(100) * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (p *Pool) buildPathRequest(path string) (*fasthttp.Request, error) {
|
||||||
req := fasthttp.AcquireRequest()
|
req := fasthttp.AcquireRequest()
|
||||||
req.SetRequestURI(p.BaseURL + path)
|
req.SetRequestURI(p.BaseURL + path)
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Pool) BuildHostRequest(host string) (*fasthttp.Request, error) {
|
func (p *Pool) buildHostRequest(host string) (*fasthttp.Request, error) {
|
||||||
req := fasthttp.AcquireRequest()
|
req := fasthttp.AcquireRequest()
|
||||||
req.SetRequestURI(p.BaseURL)
|
req.SetRequestURI(p.BaseURL)
|
||||||
req.SetHost(host)
|
req.SetHost(host)
|
||||||
|
@ -161,7 +161,7 @@ func (r *Runner) Outputting() {
|
|||||||
select {
|
select {
|
||||||
case bl := <-r.OutputCh:
|
case bl := <-r.OutputCh:
|
||||||
if bl.IsValid {
|
if bl.IsValid {
|
||||||
logs.Log.Console(bl.String())
|
logs.Log.Console("[+] " + bl.String() + "\n")
|
||||||
} else {
|
} else {
|
||||||
logs.Log.Debug(bl.String())
|
logs.Log.Debug(bl.String())
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
DefaultMaxBodySize = 1024 * 100 // 100k
|
||||||
|
)
|
||||||
|
|
||||||
func NewClient(thread int, timeout int) *Client {
|
func NewClient(thread int, timeout int) *Client {
|
||||||
//tr := &http.Transport{
|
//tr := &http.Transport{
|
||||||
// //Proxy: Proxy,
|
// //Proxy: Proxy,
|
||||||
@ -31,7 +35,7 @@ func NewClient(thread int, timeout int) *Client {
|
|||||||
MaxConnWaitTimeout: time.Duration(timeout) * time.Second,
|
MaxConnWaitTimeout: time.Duration(timeout) * time.Second,
|
||||||
ReadTimeout: time.Duration(timeout) * time.Second,
|
ReadTimeout: time.Duration(timeout) * time.Second,
|
||||||
WriteTimeout: time.Duration(timeout) * time.Second,
|
WriteTimeout: time.Duration(timeout) * time.Second,
|
||||||
MaxResponseBodySize: 20480,
|
MaxResponseBodySize: DefaultMaxBodySize,
|
||||||
},
|
},
|
||||||
timeout: time.Duration(timeout) * time.Second,
|
timeout: time.Duration(timeout) * time.Second,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user