mirror of
https://github.com/chainreactors/spray.git
synced 2026-10-24 08:54:30 +00:00
fix: restore ci release builds
This commit is contained in:
1 parent
da2bc71a13
commit
58d4343998
10 files changed
+183
-30
No files matched your search
@@ -24,14 +24,14 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: '1.24.x'
|
||||
go-version-file: go.mod
|
||||
cache: true
|
||||
|
||||
- name: Download dependencies
|
||||
|
||||
@@ -6,16 +6,18 @@ on:
|
||||
- 'v*.*.*'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
submodules: recursive
|
||||
|
||||
- name: Install upx
|
||||
@@ -24,12 +26,12 @@ jobs:
|
||||
|
||||
-
|
||||
name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.25"
|
||||
go-version-file: go.mod
|
||||
-
|
||||
name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
uses: goreleaser/goreleaser-action@v7
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
[submodule "templates"]
|
||||
path = templates
|
||||
url = https://github.com/chainreactors/gogo-templates
|
||||
url = https://github.com/chainreactors/templates
|
||||
+5
-2
@@ -1,3 +1,5 @@
|
||||
version: 2
|
||||
|
||||
project_name: spray
|
||||
|
||||
before:
|
||||
@@ -22,7 +24,7 @@ builds:
|
||||
goarch: arm64
|
||||
- goos: darwin
|
||||
goarch: "386"
|
||||
ldflags: "-s -w -X 'github.com/chainreactors/spray/cmd.ver=={{ .Tag }}'"
|
||||
ldflags: "-s -w -X 'github.com/chainreactors/spray/cmd.ver={{ .Tag }}'"
|
||||
flags:
|
||||
- -trimpath
|
||||
asmflags:
|
||||
@@ -48,7 +50,8 @@ upx:
|
||||
archives:
|
||||
-
|
||||
name_template: "{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}"
|
||||
format: binary
|
||||
formats:
|
||||
- binary
|
||||
|
||||
checksum:
|
||||
name_template: "{{ .ProjectName }}_checksums.txt"
|
||||
|
||||
@@ -112,6 +112,81 @@ func NewInvalidBaseline(u, host string, resp *ihttp.Response, reason string) *Ba
|
||||
return bl
|
||||
}
|
||||
|
||||
func (bl *Baseline) Snapshot() *Baseline {
|
||||
if bl == nil {
|
||||
return nil
|
||||
}
|
||||
cp := *bl
|
||||
if bl.SprayResult != nil {
|
||||
sr := *bl.SprayResult
|
||||
sr.Frameworks = cloneFrameworks(bl.Frameworks)
|
||||
sr.Extracteds = cloneExtracteds(bl.Extracteds)
|
||||
if bl.Hashes != nil {
|
||||
hashes := *bl.Hashes
|
||||
sr.Hashes = &hashes
|
||||
}
|
||||
cp.SprayResult = &sr
|
||||
}
|
||||
if bl.URLs != nil {
|
||||
cp.URLs = append([]string(nil), bl.URLs...)
|
||||
}
|
||||
return &cp
|
||||
}
|
||||
|
||||
func cloneFrameworks(frames common.Frameworks) common.Frameworks {
|
||||
if frames == nil {
|
||||
return nil
|
||||
}
|
||||
cp := make(common.Frameworks, len(frames))
|
||||
for name, frame := range frames {
|
||||
if frame == nil {
|
||||
cp[name] = nil
|
||||
continue
|
||||
}
|
||||
frameCopy := *frame
|
||||
if frame.Froms != nil {
|
||||
frameCopy.Froms = make(map[common.From]bool, len(frame.Froms))
|
||||
for from, ok := range frame.Froms {
|
||||
frameCopy.Froms[from] = ok
|
||||
}
|
||||
}
|
||||
if frame.Tags != nil {
|
||||
frameCopy.Tags = append([]string(nil), frame.Tags...)
|
||||
}
|
||||
if frame.MatchDetail != nil {
|
||||
matchDetail := *frame.MatchDetail
|
||||
frameCopy.MatchDetail = &matchDetail
|
||||
}
|
||||
if frame.Attributes != nil {
|
||||
attrs := *frame.Attributes
|
||||
frameCopy.Attributes = &attrs
|
||||
}
|
||||
cp[name] = &frameCopy
|
||||
}
|
||||
return cp
|
||||
}
|
||||
|
||||
func cloneExtracteds(extracteds parsers.Extracteds) parsers.Extracteds {
|
||||
if extracteds == nil {
|
||||
return nil
|
||||
}
|
||||
cp := make(parsers.Extracteds, len(extracteds))
|
||||
for i, extracted := range extracteds {
|
||||
if extracted == nil {
|
||||
continue
|
||||
}
|
||||
extractedCopy := *extracted
|
||||
if extracted.ExtractResult != nil {
|
||||
extractedCopy.ExtractResult = append([]string(nil), extracted.ExtractResult...)
|
||||
}
|
||||
if extracted.Items != nil {
|
||||
extractedCopy.Items = append([]parsers.ExtractItem(nil), extracted.Items...)
|
||||
}
|
||||
cp[i] = &extractedCopy
|
||||
}
|
||||
return cp
|
||||
}
|
||||
|
||||
type Baseline struct {
|
||||
*parsers.SprayResult
|
||||
Url *url.URL `json:"-"`
|
||||
|
||||
+19
-14
@@ -109,23 +109,23 @@ type RequestOptions struct {
|
||||
}
|
||||
|
||||
type PluginOptions struct {
|
||||
Advance bool `short:"a" long:"advance" description:"Bool, enable all plugin" config:"all" `
|
||||
Advance bool `short:"a" long:"advance" description:"Bool, enable all plugin" config:"all" `
|
||||
Extracts []string `long:"extract" description:"Strings, extract response, e.g.: --extract js --extract ip --extract version:(.*?)" config:"extract"`
|
||||
ExtractConfig string `long:"extract-config" description:"String, extract config filename" config:"extract-config"`
|
||||
ExtractContext int `long:"extract-context" default:"0" description:"Int, chars of context around extracted values, e.g.: --extract-context 50" config:"extract-context"`
|
||||
ActivePlugin bool `long:"active" description:"Bool, enable active finger path"`
|
||||
ReconPlugin bool `long:"recon" description:"Bool, enable recon" config:"recon"`
|
||||
KeysPlugin bool `long:"keys" description:"Bool, enable credential/keys detection (found templates)" config:"keys"`
|
||||
BakPlugin bool `long:"bak" description:"Bool, enable bak found" config:"bak"`
|
||||
FuzzuliPlugin bool `long:"fuzzuli" description:"Bool, enable fuzzuli plugin" config:"fuzzuli"`
|
||||
CommonPlugin bool `long:"common" description:"Bool, enable common file found" config:"common"`
|
||||
CrawlPlugin bool `long:"crawl" description:"Bool, enable crawl" config:"crawl"`
|
||||
CrawlDepth int `long:"crawl-depth" default:"3" description:"Int, crawl depth" config:"crawl-depth"`
|
||||
AppendDepth int `long:"append-depth" default:"2" description:"Int, append depth" config:"append-depth"`
|
||||
Finger bool `long:"finger" description:"Bool, enable active finger detect" config:"finger"`
|
||||
FingerEngines string `long:"finger-engine" default:"all" description:"String, custom finger engine, e.g. --finger-engine ehole,goby" config:"finger-engine"`
|
||||
PocPlugin bool `long:"poc" description:"Bool, enable neutron poc verify after finger detect" config:"poc"`
|
||||
PocConfig string `long:"poc-config" description:"String, custom poc template directory" config:"poc-config"`
|
||||
ActivePlugin bool `long:"active" description:"Bool, enable active finger path"`
|
||||
ReconPlugin bool `long:"recon" description:"Bool, enable recon" config:"recon"`
|
||||
KeysPlugin bool `long:"keys" description:"Bool, enable credential/keys detection (found templates)" config:"keys"`
|
||||
BakPlugin bool `long:"bak" description:"Bool, enable bak found" config:"bak"`
|
||||
FuzzuliPlugin bool `long:"fuzzuli" description:"Bool, enable fuzzuli plugin" config:"fuzzuli"`
|
||||
CommonPlugin bool `long:"common" description:"Bool, enable common file found" config:"common"`
|
||||
CrawlPlugin bool `long:"crawl" description:"Bool, enable crawl" config:"crawl"`
|
||||
CrawlDepth int `long:"crawl-depth" default:"3" description:"Int, crawl depth" config:"crawl-depth"`
|
||||
AppendDepth int `long:"append-depth" default:"2" description:"Int, append depth" config:"append-depth"`
|
||||
Finger bool `long:"finger" description:"Bool, enable active finger detect" config:"finger"`
|
||||
FingerEngines string `long:"finger-engine" default:"all" description:"String, custom finger engine, e.g. --finger-engine ehole,goby" config:"finger-engine"`
|
||||
PocPlugin bool `long:"poc" description:"Bool, enable neutron poc verify after finger detect" config:"poc"`
|
||||
PocConfig string `long:"poc-config" description:"String, custom poc template directory" config:"poc-config"`
|
||||
}
|
||||
|
||||
type ModeOptions struct {
|
||||
@@ -1219,6 +1219,11 @@ func (opt *Option) BuildTasks(r *Runner) (*TaskGenerator, error) {
|
||||
}
|
||||
if file != nil {
|
||||
content, err := ioutil.ReadAll(file)
|
||||
if file != os.Stdin {
|
||||
if closeErr := file.Close(); err == nil && closeErr != nil {
|
||||
err = closeErr
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+6
-4
@@ -86,15 +86,16 @@ func (pool *BasePool) putToOutput(bl *baseline.Baseline) {
|
||||
} else if !bl.Collected && len(bl.Raw) > 0 {
|
||||
bl.Extracteds.Merge(pkg.ProtonExtract(bl.Raw))
|
||||
}
|
||||
out := bl.Snapshot()
|
||||
pool.Outwg.Add(1)
|
||||
select {
|
||||
case pool.OutputCh <- bl:
|
||||
case pool.OutputCh <- out:
|
||||
case <-pool.ctx.Done():
|
||||
// Close cancels the pool context before draining processCh. If OutputCh
|
||||
// still has room, keep the already-produced result instead of dropping it
|
||||
// because the local pool is shutting down.
|
||||
select {
|
||||
case pool.OutputCh <- bl:
|
||||
case pool.OutputCh <- out:
|
||||
default:
|
||||
pool.Outwg.Done()
|
||||
}
|
||||
@@ -116,11 +117,12 @@ func (pool *BasePool) doPoc(bl *baseline.Baseline) {
|
||||
func (pool *BasePool) putToFuzzy(bl *baseline.Baseline) {
|
||||
pool.Outwg.Add(1)
|
||||
bl.IsFuzzy = true
|
||||
out := bl.Snapshot()
|
||||
select {
|
||||
case pool.FuzzyCh <- bl:
|
||||
case pool.FuzzyCh <- out:
|
||||
case <-pool.ctx.Done():
|
||||
select {
|
||||
case pool.FuzzyCh <- bl:
|
||||
case pool.FuzzyCh <- out:
|
||||
default:
|
||||
pool.Outwg.Done()
|
||||
}
|
||||
|
||||
+51
-1
@@ -10,6 +10,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/chainreactors/fingers/common"
|
||||
"github.com/chainreactors/parsers"
|
||||
"github.com/chainreactors/spray/core/baseline"
|
||||
"github.com/chainreactors/spray/core/ihttp"
|
||||
@@ -473,6 +474,31 @@ func TestPutToOutput_Normal(t *testing.T) {
|
||||
pool.Outwg.Wait()
|
||||
}
|
||||
|
||||
func TestPutToOutputSnapshotsBaseline(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
pool := newTestBasePool(ctx, cancel)
|
||||
|
||||
bl := newTestBaseline()
|
||||
bl.Frameworks = common.Frameworks{
|
||||
"nginx": common.NewFramework("nginx", common.FrameFromFingers),
|
||||
}
|
||||
bl.Title = "before"
|
||||
pool.putToOutput(bl)
|
||||
|
||||
got := <-pool.OutputCh
|
||||
pool.Outwg.Done()
|
||||
bl.Title = "after"
|
||||
bl.Frameworks["apache"] = common.NewFramework("apache", common.FrameFromFingers)
|
||||
|
||||
if got.Title != "before" {
|
||||
t.Fatalf("snapshot title = %q, want before", got.Title)
|
||||
}
|
||||
if _, ok := got.Frameworks["apache"]; ok {
|
||||
t.Fatal("output snapshot shares Frameworks map with original baseline")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPutToOutput_AfterCancel(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
pool := newTestBasePool(ctx, cancel)
|
||||
@@ -540,6 +566,31 @@ func TestPutToFuzzy_Normal(t *testing.T) {
|
||||
pool.Outwg.Wait()
|
||||
}
|
||||
|
||||
func TestPutToFuzzySnapshotsBaseline(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
pool := newTestBasePool(ctx, cancel)
|
||||
|
||||
bl := newTestBaseline()
|
||||
bl.Frameworks = common.Frameworks{
|
||||
"nginx": common.NewFramework("nginx", common.FrameFromFingers),
|
||||
}
|
||||
bl.Title = "before"
|
||||
pool.putToFuzzy(bl)
|
||||
|
||||
got := <-pool.FuzzyCh
|
||||
pool.Outwg.Done()
|
||||
bl.Title = "after"
|
||||
bl.Frameworks["apache"] = common.NewFramework("apache", common.FrameFromFingers)
|
||||
|
||||
if got.Title != "before" {
|
||||
t.Fatalf("snapshot title = %q, want before", got.Title)
|
||||
}
|
||||
if _, ok := got.Frameworks["apache"]; ok {
|
||||
t.Fatal("fuzzy snapshot shares Frameworks map with original baseline")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPutToFuzzy_AfterCancel(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
pool := newTestBasePool(ctx, cancel)
|
||||
@@ -849,4 +900,3 @@ func TestHandleBaseline_MapAccessSingleThreaded(t *testing.T) {
|
||||
t.Fatalf("ReqTotal = %d, want 50", pool.Statistor.ReqTotal)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +156,7 @@ func RunWithArgs(ctx context.Context, args []string, opts RunOptions) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer runner.CloseFiles()
|
||||
if option.ReadAll || runner.CrawlPlugin {
|
||||
ihttp.DefaultMaxBodySize = -1
|
||||
}
|
||||
|
||||
@@ -185,6 +185,21 @@ func (r *Runner) Prepare(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Runner) CloseFiles() {
|
||||
if r.OutputFile != nil {
|
||||
r.OutputFile.Close()
|
||||
r.OutputFile = nil
|
||||
}
|
||||
if r.DumpFile != nil {
|
||||
r.DumpFile.Close()
|
||||
r.DumpFile = nil
|
||||
}
|
||||
if r.StatFile != nil {
|
||||
r.StatFile.Close()
|
||||
r.StatFile = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runner) RunWithBrute(ctx context.Context) {
|
||||
go func() {
|
||||
defer close(r.taskCh)
|
||||
|
||||
Reference in new issue
Block a user