Skip to content

Commit 180bff3

Browse files
committed
feat: support multiple embedded plugins and update goreleaser
- add path traversal guards for safer file operations - tighten file permission defaults on managed outputs - migrate Goreleaser pre-hook logic from shell scripts to Go - support multi embedded plugins
1 parent 4686aca commit 180bff3

File tree

31 files changed

+735
-156
lines changed

31 files changed

+735
-156
lines changed

.gitignore

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ bin/
33
dist/
44
.malice/
55
go.sum
6-
helper/intl/professional/
7-
helper/intl/custom/
6+
helper/intl/professional/*
7+
!helper/intl/professional/.gitkeep
8+
helper/intl/custom/*
9+
!helper/intl/custom/.gitkeep
810
*.bin
911
*.so
1012
.gomodcache/

.goreleaser.yml

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ git:
88
before:
99
hooks:
1010
- go mod tidy
11-
- curl -L https://github.com/EgeBalci/sgn/releases/download/v2.0.1/sgn_linux_amd64_2.0.1.zip -o sgn_linux.zip
12-
- unzip -o sgn_linux.zip -d server/assets/linux
13-
- curl -L https://github.com/EgeBalci/sgn/releases/download/v2.0.1/sgn_windows_amd64_2.0.1.zip -o sgn_windows.zip
14-
- unzip -o sgn_windows.zip -d server/assets/windows
15-
- curl -L https://github.com/chainreactors/malefic/releases/latest/download/malefic-mutant-x86_64-pc-windows-gnu.exe -o server/assets/windows/malefic-mutant.exe
16-
- curl -L https://github.com/chainreactors/malefic/releases/latest/download/malefic-mutant-x86_64-unknown-linux-musl -o server/assets/linux/malefic-mutant
11+
- go run scripts/pre_install.go
1712

1813

1914
builds:
@@ -46,15 +41,15 @@ builds:
4641
goos:
4742
- windows
4843
- linux
49-
# - darwin
44+
- darwin
5045
goarch:
5146
- amd64
5247
- arm64
5348
ldflags: |
54-
-s -w
55-
-X github.com/chainreactors/malice-network/helper/consts.Ver={{.Env.VERSION}}
56-
-X github.com/chainreactors/malice-network/helper/consts.Commit={{.Env.COMMIT}}
57-
-X github.com/chainreactors/malice-network/helper/consts.Buildstamp={{.Timestamp}}"
49+
-s -w
50+
-X github.com/chainreactors/malice-network/helper/consts.Ver={{.Env.VERSION}}
51+
-X github.com/chainreactors/malice-network/helper/consts.Commit={{.Env.COMMIT}}
52+
-X github.com/chainreactors/malice-network/helper/consts.Buildstamp={{.Timestamp}}
5853
asmflags:
5954
- all=-trimpath={{.Env.GOPATH}}
6055
gcflags:
@@ -73,7 +68,7 @@ upx:
7368
archives:
7469
-
7570
name_template: "{{ .Binary }}"
76-
format: binary
71+
formats: [binary]
7772

7873
checksum:
7974
name_template: "{{ .ProjectName }}_checksums.txt"
@@ -90,4 +85,3 @@ release:
9085
owner: chainreactors
9186
name: malice-network
9287
draft: true
93-

.professional.yml

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@ git:
88
before:
99
hooks:
1010
- go mod tidy
11-
- curl -L https://github.com/EgeBalci/sgn/releases/download/v2.0.1/sgn_linux_amd64_2.0.1.zip -o sgn_linux.zip
12-
- unzip -o sgn_linux.zip -d server/assets/linux
13-
- curl -L https://github.com/EgeBalci/sgn/releases/download/v2.0.1/sgn_windows_amd64_2.0.1.zip -o sgn_windows.zip
14-
- unzip -o sgn_windows.zip -d server/assets/windows
15-
- cp helper/consts/professional/malefic-mutant server/assets/linux/
16-
- cp helper/consts/professional/malefic-mutant.exe server/assets/windows/
11+
- go run scripts/pre_install.go --professional
1712

1813
builds:
1914
-
@@ -54,10 +49,10 @@ builds:
5449
- amd64
5550
- arm64
5651
ldflags: |
57-
-s -w
58-
-X github.com/chainreactors/malice-network/helper/consts.Ver={{.Env.VERSION}}
59-
-X github.com/chainreactors/malice-network/helper/consts.Commit={{.Env.COMMIT}}.{{.Env.LICENSE_ID}}
60-
-X github.com/chainreactors/malice-network/helper/consts.Buildstamp={{.Timestamp}}"
52+
-s -w
53+
-X github.com/chainreactors/malice-network/helper/consts.Ver={{.Env.VERSION}}
54+
-X github.com/chainreactors/malice-network/helper/consts.Commit={{.Env.COMMIT}}.{{.Env.LICENSE_ID}}
55+
-X github.com/chainreactors/malice-network/helper/consts.Buildstamp={{.Timestamp}}
6156
asmflags:
6257
- all=-trimpath={{.Env.GOPATH}}
6358
gcflags:
@@ -76,7 +71,7 @@ upx:
7671
archives:
7772
-
7873
name_template: "{{ .Binary }}"
79-
format: binary
74+
formats: [binary]
8075

8176
checksum:
8277
name_template: "{{ .ProjectName }}_checksums.txt"
@@ -93,4 +88,3 @@ release:
9388
owner: chainreactors
9489
name: malice-network
9590
draft: true
96-

client/assets/asset.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func GetConfigDir() string {
3535
if _, err := os.Stat(dir); os.IsNotExist(err) {
3636
err = os.MkdirAll(dir, 0700)
3737
if err != nil {
38-
logs.Log.Errorf(err.Error())
38+
logs.Log.Errorf("%v", err)
3939
}
4040
}
4141
return dir

client/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
func main() {
99
err := cli.Start()
1010
if err != nil {
11-
logs.Log.Errorf(err.Error())
11+
logs.Log.Errorf("%v", err)
1212
return
1313
}
1414
}

client/command/implant.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ func makeRunners(implantCmd *cobra.Command, con *core.Console) (pre, post func(c
111111
}
112112

113113
var session *client.Session
114-
var ok bool
115-
116-
if session, ok = con.GetLocalSession(sid); !ok {
114+
var err error
115+
session, err = con.GetOrUpdateSession(sid)
116+
if err != nil || session == nil {
117117
if con.ActiveTarget != nil && con.ActiveTarget.Get() != nil && con.ActiveTarget.Get().SessionId == sid {
118118
session = con.ActiveTarget.Get()
119119
} else {
@@ -287,8 +287,19 @@ func BindImplantCommands(con *core.Console) console.Commands {
287287

288288
// 注册嵌入式插件命令
289289
embeddedBind := MakeBind(implant, con, "mal")
290-
for _, plug := range con.MalManager.GetAllEmbeddedPlugins() {
291-
embeddedBind(plug.Name, BindCommand(plug.Commands().Commands()))
290+
customCommands := con.MalManager.GetEmbeddedCommandsByLevel(plugin.CustomLevel)
291+
if len(customCommands) > 0 {
292+
embeddedBind(plugin.CustomLevel.String(), BindCommand(customCommands))
293+
}
294+
295+
communityCommands := con.MalManager.GetEmbeddedCommandsByLevel(plugin.CommunityLevel)
296+
if len(communityCommands) > 0 {
297+
embeddedBind(plugin.CommunityLevel.String(), BindCommand(communityCommands))
298+
}
299+
300+
professionalCommands := con.MalManager.GetEmbeddedCommandsByLevel(plugin.ProfessionalLevel)
301+
if len(professionalCommands) > 0 {
302+
embeddedBind(plugin.ProfessionalLevel.String(), BindCommand(professionalCommands))
292303
}
293304

294305
// 注册外部插件命令

client/plugin/embed.go

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ func (l MalLevel) String() string {
2525
return "community"
2626
case ProfessionalLevel:
2727
return "professional"
28+
case CustomLevel:
29+
return "custom"
2830
default:
2931
return "unknown"
3032
}
@@ -37,7 +39,7 @@ const (
3739
)
3840

3941
var (
40-
levelOrder = []MalLevel{CommunityLevel, ProfessionalLevel, CustomLevel}
42+
levelOrder = []MalLevel{CustomLevel, ProfessionalLevel, CommunityLevel}
4143
)
4244

4345
// EmbedPlugin 嵌入式Lua插件,直接实现Plugin接口
@@ -51,9 +53,10 @@ type EmbedPlugin struct {
5153

5254
// NewEmbedPlugin 创建嵌入式插件
5355
func NewEmbedPlugin(malPath, malName string, level MalLevel) (*EmbedPlugin, error) {
56+
pluginFS := intl.UnifiedFS
5457
// 读取manifest文件
5558
manifestPath := malPath + "/mal.yaml"
56-
manifestData, err := intl.UnifiedFS.ReadFile(manifestPath)
59+
manifestData, err := pluginFS.ReadFile(manifestPath)
5760
if err != nil {
5861
return nil, fmt.Errorf("failed to read manifest: %w", err)
5962
}
@@ -71,7 +74,7 @@ func NewEmbedPlugin(malPath, malName string, level MalLevel) (*EmbedPlugin, erro
7174
var content []byte
7275
if manifest.EntryFile != "" {
7376
entryPath := malPath + "/" + manifest.EntryFile
74-
content, err = intl.UnifiedFS.ReadFile(entryPath)
77+
content, err = pluginFS.ReadFile(entryPath)
7578
if err != nil {
7679
return nil, fmt.Errorf("failed to read entry file %s: %w", manifest.EntryFile, err)
7780
}
@@ -96,7 +99,7 @@ func NewEmbedPlugin(malPath, malName string, level MalLevel) (*EmbedPlugin, erro
9699
embedPlugin := &EmbedPlugin{
97100
LuaPlugin: luaPlugin,
98101
Level: level,
99-
FS: intl.UnifiedFS,
102+
FS: pluginFS,
100103
RootPath: malPath,
101104
}
102105

@@ -168,13 +171,11 @@ func (plug *EmbedPlugin) registerEmbedResourceFunctions() {
168171
plug.registerFunction("global_resource", func(filename string) (string, error) {
169172
// 从全局管理器查找
170173
if globalManager := GetGlobalMalManager(); globalManager != nil {
171-
reverseLevelOrder := []string{"custom", "professional", "community"}
172-
173-
for _, levelName := range reverseLevelOrder {
174-
if plugin, exists := globalManager.GetEmbedPlugin(levelName); exists {
174+
for _, level := range []MalLevel{CustomLevel, ProfessionalLevel, CommunityLevel} {
175+
for _, levelPlugin := range globalManager.GetEmbeddedPluginsByLevel(level) {
175176
resourcePath := "resources/" + filename
176-
if _, fileExists := plugin.GetFileContent(resourcePath); fileExists {
177-
return fmt.Sprintf("embed://%s/%s", levelName, resourcePath), nil
177+
if _, fileExists := levelPlugin.GetFileContent(resourcePath); fileExists {
178+
return fmt.Sprintf("embed://%s/%s", levelPlugin.Name, resourcePath), nil
178179
}
179180
}
180181
}
@@ -203,13 +204,11 @@ func (plug *EmbedPlugin) registerEmbedResourceFunctions() {
203204
filename := fmt.Sprintf("%s.%s.%s", base, sess.Os.Arch, ext)
204205

205206
if globalManager := GetGlobalMalManager(); globalManager != nil {
206-
reverseLevelOrder := []string{"custom", "professional", "community"}
207-
208-
for _, levelName := range reverseLevelOrder {
209-
if plugin, exists := globalManager.GetEmbedPlugin(levelName); exists {
207+
for _, level := range []MalLevel{CustomLevel, ProfessionalLevel, CommunityLevel} {
208+
for _, levelPlugin := range globalManager.GetEmbeddedPluginsByLevel(level) {
210209
resourcePath := "resources/" + filename
211-
if _, fileExists := plugin.GetFileContent(resourcePath); fileExists {
212-
return fmt.Sprintf("embed://%s/%s", levelName, resourcePath), nil
210+
if _, fileExists := levelPlugin.GetFileContent(resourcePath); fileExists {
211+
return fmt.Sprintf("embed://%s/%s", levelPlugin.Name, resourcePath), nil
213212
}
214213
}
215214
}
@@ -241,13 +240,10 @@ func (plug *EmbedPlugin) registerEmbedResourceFunctions() {
241240
plug.registerFunction("read_global_resource", func(filename string) (string, error) {
242241
// 从plugin包获取全局嵌入式mal管理器
243242
if globalManager := GetGlobalMalManager(); globalManager != nil {
244-
// 按优先级顺序查找:custom -> professional -> community
245-
reverseLevelOrder := []string{"custom", "professional", "community"}
246-
247-
for _, levelName := range reverseLevelOrder {
248-
if plugin, exists := globalManager.GetEmbedPlugin(levelName); exists {
243+
for _, level := range []MalLevel{CustomLevel, ProfessionalLevel, CommunityLevel} {
244+
for _, levelPlugin := range globalManager.GetEmbeddedPluginsByLevel(level) {
249245
resourcePath := "resources/" + filename
250-
if content, fileExists := plugin.GetFileContent(resourcePath); fileExists {
246+
if content, fileExists := levelPlugin.GetFileContent(resourcePath); fileExists {
251247
return string(content), nil
252248
}
253249
}

0 commit comments

Comments
 (0)