fix: restore ci release builds

This commit is contained in:
M09Ic committed 2026-06-23 22:39:23 +08:00
1 parent da2bc71a13
commit 58d4343998
10 files changed
+183 -30

No files matched your search

+3 -3
View File
@@ -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
+7 -5
View File
@@ -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
View File
@@ -1,3 +1,3 @@
[submodule "templates"]
path = templates
url = https://github.com/chainreactors/gogo-templates
url = https://github.com/chainreactors/templates
+5 -2
View File
@@ -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"
+75
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
}
}
+1
View File
@@ -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
}
+15
View File
@@ -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)