Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e55cb1c
test(audit): add vulnerability reproduction coverage
h3zh1 Jul 10, 2026
30767dd
fix(parser): harden untrusted payload reads
h3zh1 Jul 10, 2026
46281be
fix(listener): linearize pipeline lifecycle
h3zh1 Jul 10, 2026
60b37f7
fix(core): synchronize session sysinfo state
h3zh1 Jul 10, 2026
4fc1427
ci: align workflows with Go 1.25
h3zh1 Jul 10, 2026
055d82d
fix(rpc): wait for forward listener shutdown
h3zh1 Jul 11, 2026
d4ba4ef
fix(runtime): close event and artifact consistency gaps
h3zh1 Jul 11, 2026
05047fe
fix(parser): cap snappy decoded payloads
h3zh1 Jul 12, 2026
f6224cd
fix(client): synchronize shared runtime state
h3zh1 Jul 13, 2026
3bafe46
fix(core): synchronize session state snapshots
h3zh1 Jul 13, 2026
9512851
fix(parser): reject unsafe encoded payloads
h3zh1 Jul 13, 2026
a206fc8
fix(events): make stream shutdown explicit
h3zh1 Jul 13, 2026
b86a685
fix(listener): harden forward lifecycle cleanup
h3zh1 Jul 13, 2026
c1cd467
fix(events): make startup replay atomic
h3zh1 Jul 13, 2026
a6b6413
fix(transport): bound payload read duration
h3zh1 Jul 13, 2026
3815162
test(ci): expand concurrency and fuzz coverage
h3zh1 Jul 13, 2026
385622c
merge: integrate latest dev hardening
h3zh1 Jul 13, 2026
47c837f
fix(session): synchronize mutable runtime state
h3zh1 Jul 13, 2026
1d0b9f9
fix(transport): bound initial protocol reads
h3zh1 Jul 13, 2026
257e7ed
fix(forward): enforce single active task stream
h3zh1 Jul 13, 2026
97b7fe2
fix(rem): harden runtime cancellation and cleanup
h3zh1 Jul 13, 2026
6beacf2
fix(listener): linearize pipeline serving startup
h3zh1 Jul 13, 2026
42e094c
fix(listener): replace failed pipeline runtimes
h3zh1 Jul 13, 2026
5f1bc10
fix(parser): validate snappy blocks before allocation
h3zh1 Jul 13, 2026
d2e36d7
fix(core): make session keypair update atomic
h3zh1 Jul 13, 2026
2ede218
fix(listener): bound rem close wait for in-flight start
h3zh1 Jul 13, 2026
94a3cca
test(listener): stabilize flaky rem accept-backoff test
h3zh1 Jul 13, 2026
844875c
docs: document event queue-full and forward slot trade-offs
h3zh1 Jul 13, 2026
1a7448b
fix(core): keep session keypairs synchronized
h3zh1 Jul 13, 2026
1f8e5e4
test(integration): expect stopped pipelines to remain cached
h3zh1 Jul 13, 2026
989ef8c
Merge remote-tracking branch 'origin/dev' into HEAD
h3zh1 Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 45 additions & 17 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,16 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.13"
go-version: "1.25.0"
cache: false

- name: Show Go version
run: go version

- name: Go mod tidy
run: go mod tidy
- name: Verify Go module files
run: |
go mod tidy
git diff --exit-code -- go.mod go.sum

- name: Install embedded build assets
run: go run ./scripts/pre_install.go
Expand All @@ -50,21 +55,34 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.13"
go-version: "1.25.0"
cache: false

- name: Show Go version
run: go version

- name: Go mod tidy
run: go mod tidy
- name: Verify Go module files
run: |
go mod tidy
git diff --exit-code -- go.mod go.sum

- name: Install embedded build assets
run: go run ./scripts/pre_install.go

- name: Race detection — core, parser, stream
- name: Race detection — client, core, parser, RPC, listener, stream
run: >-
go test -race -count=1 -timeout 300s
./server/internal/core
./server/internal/parser/...
./server/internal/stream
go test -race -count=1 -timeout 300s
./client/core/...
./server/internal/core
./server/internal/parser/...
./server/internal/stream
./server/listener
./server/rpc

- name: Parser fuzz smoke tests
run: |
go test ./server/internal/parser/malefic -run=^$ -fuzz=^FuzzMaleficParserReadHeader$ -fuzztime=5s
go test ./server/internal/parser/malefic -run=^$ -fuzz=^FuzzMaleficParserParse$ -fuzztime=5s

mock_implant:
runs-on: ubuntu-22.04
Expand All @@ -77,11 +95,16 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.13"
go-version: "1.25.0"
cache: false

- name: Show Go version
run: go version

- name: Go mod tidy
run: go mod tidy
- name: Verify Go module files
run: |
go mod tidy
git diff --exit-code -- go.mod go.sum

- name: Install embedded build assets
run: go run ./scripts/pre_install.go
Expand All @@ -107,11 +130,16 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.13"
go-version: "1.25.0"
cache: false

- name: Show Go version
run: go version

- name: Go mod tidy
run: go mod tidy
- name: Verify Go module files
run: |
go mod tidy
git diff --exit-code -- go.mod go.sum

- name: Install embedded build assets
run: go run ./scripts/pre_install.go
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.13"
go-version: "1.25.0"

- name: Show Go version
run: go version

- name: Configure Git
run: |
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/realimplant.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.13"
go-version: "1.25.0"
cache: false

- name: Show Go version
run: go version

- name: Validate real implant environment
shell: pwsh
run: |
Expand All @@ -38,6 +41,9 @@ jobs:
- name: Go mod tidy
run: go mod tidy

- name: Verify Go module files
run: git diff --exit-code -- go.mod go.sum

- name: Real implant E2E tests
shell: pwsh
run: |
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/releaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.13"
- run: go version
go-version: "1.25.0"

- name: Show Go version
run: go version

- name: Configure Git
run: |
Expand Down Expand Up @@ -75,4 +77,3 @@ jobs:
dist/vsix/iom.vsix
env:
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}

5 changes: 4 additions & 1 deletion .github/workflows/update-search-index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,12 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.13"
go-version: "1.25.0"
cache: false

- name: Show Go version
run: go version

- name: Update community submodule to latest
run: |
git config --global url."https://${{ secrets.PAT_TOKEN }}@github.com/".insteadOf "https://github.com/"
Expand Down
10 changes: 7 additions & 3 deletions client/command/build/artifact_command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,16 @@ func TestArtifactPublishAddsWebsiteContent(t *testing.T) {
}

calls := h.Recorder.Calls()
if len(calls) != 1 || calls[0].Method != "AddWebsiteContent" {
if len(calls) != 2 || calls[0].Method != "DownloadArtifact" || calls[1].Method != "AddWebsiteContent" {
t.Fatalf("calls = %#v", calls)
}
add := calls[0].Request.(*clientpb.Website)
download := calls[0].Request.(*clientpb.Artifact)
if download.Name != "demo-artifact" {
t.Fatalf("download artifact request = %#v", download)
}
add := calls[1].Request.(*clientpb.Website)
content := add.Contents["/payload.bin"]
if add.Name != "site-a" || content == nil || content.GetType() != consts.ArtifactWebcontent || content.GetFile() != "demo-artifact" {
if add.Name != "site-a" || content == nil || string(content.Content) != "artifact-bin" {
t.Fatalf("add website content request = %#v", add)
}
}
Expand Down
4 changes: 2 additions & 2 deletions client/command/build/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,13 +630,13 @@ artifact prune --failed --older-than 720h
func Register(con *core.Console) {
// EventCallback requires initialized Server; skip in doc-gen mode (genlua)
if con.Server != nil {
con.EventCallback[consts.CtrlArtifactDownload] = func(event *clientpb.Event) {
con.SetEventCallback(consts.CtrlArtifactDownload, func(event *clientpb.Event) {
err := WriteOriginArtifact(con, event.Job.Name)
if err != nil {
con.Log.Errorf("write artifact %s error: %s", event.Job.Name, err)
return
}
}
})
}
con.RegisterServerFunc("search_artifact",
SearchArtifact,
Expand Down
7 changes: 4 additions & 3 deletions client/command/implant.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ func makeRunners(implantCmd *cobra.Command, con *core.Console) (pre, post func(c
return nil
}
sid, _ := cmd.Flags().GetString("use")
if sid == "" && con.ActiveTarget.Session == nil {
activeSession := con.ActiveTarget.Get()
if sid == "" && activeSession == nil {
return fmt.Errorf("no implant to run command on")
} else if sid == "" && con.ActiveTarget.Session != nil {
sid = con.ActiveTarget.Session.SessionId
} else if sid == "" {
sid = activeSession.SessionId
}

var session *client.Session
Expand Down
6 changes: 3 additions & 3 deletions client/command/listener/pipeline_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ func TestStopPipelineCmdUsesDatabaseResolution(t *testing.T) {
}

testsupport.WaitForCondition(t, 5*time.Second, func() bool {
_, ok := clientHarness.Console.Pipelines["tcp-stop"]
return !ok
}, "client pipeline cache to remove stopped pipeline")
pipeline, err := clientHarness.Console.FindCachedPipeline("tcp-stop", nil)
return err == nil && !pipeline.GetEnable()
}, "client pipeline cache to retain stopped pipeline as disabled")

model, err := h.GetPipeline("tcp-stop", h.ListenerID())
if err != nil {
Expand Down
63 changes: 34 additions & 29 deletions client/command/website/webcontent.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package website

import (
"errors"
"github.com/chainreactors/IoM-go/consts"

"github.com/chainreactors/IoM-go/proto/client/clientpb"
"github.com/chainreactors/malice-network/client/core"
"github.com/chainreactors/malice-network/helper/utils/fileutils"
"github.com/chainreactors/malice-network/helper/utils/output"
"github.com/chainreactors/malice-network/helper/utils/pe"
"github.com/chainreactors/tui"
"github.com/evertras/bubble-table/table"
"github.com/spf13/cobra"
"net/url"
"os"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -235,30 +236,24 @@ func AddArtifactContentCmd(cmd *cobra.Command, con *core.Console) error {

func AddArtifactContent(con *core.Console, artifactName, websiteName, format, rdi, webPath, contentType, name, comment, auth string) (*clientpb.WebContent, error) {
rpcFormat := normalizeArtifactContentFormat(format)
artifact, err := con.Rpc.DownloadArtifact(con.Context(), &clientpb.Artifact{
Name: artifactName,
Format: rpcFormat,
Rdi: rdi,
})
if err != nil {
return nil, err
}
if len(artifact.Bin) == 0 {
return nil, errors.New("artifact maybe not download in server")
}
if name == "" {
name = artifactName
}

resolvedWebsite, listenerID, _ := resolveWebsiteTarget(con, websiteName)
website := &clientpb.Website{
Name: resolvedWebsite,
ListenerId: listenerID,
Contents: map[string]*clientpb.WebContent{
webPath: {
WebsiteId: resolvedWebsite,
ListenerId: listenerID,
File: artifactName,
Path: webPath,
Type: consts.ArtifactWebcontent,
Url: artifactContentOptions(rpcFormat, rdi),
ContentType: contentType,
Name: name,
Comment: comment,
Auth: auth,
},
},
if webPath == "" {
webPath = defaultArtifactWebPath(artifact, artifactName, rpcFormat)
}
return con.Rpc.AddWebsiteContent(con.Context(), website)
return AddWebContentData(con, websiteName, artifact.Bin, webPath, contentType, name, comment, auth)
}

func normalizeArtifactContentFormat(format string) string {
Expand All @@ -268,15 +263,25 @@ func normalizeArtifactContentFormat(format string) string {
return format
}

func artifactContentOptions(format, rdi string) string {
values := url.Values{}
if format != "" {
values.Set("format", format)
func defaultArtifactWebPath(artifact *clientpb.Artifact, fallbackName, format string) string {
name := artifact.GetName()
if name == "" {
name = fallbackName
}
ext := artifact.GetFormat()
if f, ok := output.SupportedFormats[strings.ToLower(format)]; ok && f.Extension != "" {
ext = f.Extension
}
if ext == "" {
ext, _ = fileutils.GetExtensionByBytes(artifact.GetBin())
}
if ext != "" && !strings.HasPrefix(ext, ".") {
ext = "." + ext
}
if rdi != "" {
values.Set("rdi", rdi)
if ext != "" && strings.HasSuffix(strings.ToLower(name), strings.ToLower(ext)) {
ext = ""
}
return values.Encode()
return "/" + name + ext
}

// RemoveWebContentCmd - 删除网站内容
Expand Down
Loading
Loading