diff --git a/pkg/fscan/scanner.go b/pkg/fscan/scanner.go index b9f2bb4..c3e2ecf 100644 --- a/pkg/fscan/scanner.go +++ b/pkg/fscan/scanner.go @@ -50,29 +50,6 @@ var defaultSafePlugins = []string{ "webtitle", } -var unsafePlugins = map[string]struct{}{ - "cleaner": {}, - "crontask": {}, - "download": {}, - "forwardshell": {}, - "keylogger": {}, - "ldpreload": {}, - "minidump": {}, - "reverseshell": {}, - "socks5proxy": {}, - "sshkey": {}, - "systemdservice": {}, - "winbits": {}, - "winifeo": {}, - "winlogon": {}, - "winregistry": {}, - "winschtask": {}, - "winservice": {}, - "winstartup": {}, - "winwmi": {}, - "webpoc": {}, -} - // Scanner runs fscan from another Go process. type Scanner struct { config Config @@ -134,13 +111,7 @@ func IsSafePlugin(name string) bool { if name == "" || !plugins.Exists(name) { return false } - if plugins.HasType(name, plugins.PluginTypeLocal) { - return false - } - if _, bad := unsafePlugins[name]; bad { - return false - } - return true + return plugins.IsSafe(name) } // Scan runs the scanner for the provided targets and returns structured diff --git a/pkg/fscan/scanner_test.go b/pkg/fscan/scanner_test.go index d4fcd47..09b7e09 100644 --- a/pkg/fscan/scanner_test.go +++ b/pkg/fscan/scanner_test.go @@ -111,6 +111,16 @@ func TestListPlugins(t *testing.T) { if _, ok := GetPlugin("definitely-missing"); ok { t.Fatal("unknown plugin should not exist") } + webpoc, ok := GetPlugin("webpoc") + if !ok { + t.Fatal("missing webpoc plugin") + } + if webpoc.Safe { + t.Fatal("webpoc should be marked unsafe") + } + if !containsString(webpoc.Types, PluginTypeWeb) { + t.Fatalf("webpoc types = %#v, want web", webpoc.Types) + } } func TestScanHonorsCanceledContext(t *testing.T) { diff --git a/plugins/init.go b/plugins/init.go index c6987ff..7978af1 100644 --- a/plugins/init.go +++ b/plugins/init.go @@ -43,7 +43,7 @@ const ( type Result struct { Type ResultType Success bool - Skipped bool // 扫描被跳过,不应输出结果 + Skipped bool // 扫描被跳过,不应输出结果 Service string Username string Password string @@ -84,6 +84,7 @@ type PluginInfo struct { factory func() Plugin ports []int types []string // 插件类型标签 + safe bool // 是否适合默认嵌入式扫描 } // 插件类型常量 @@ -123,12 +124,23 @@ func RegisterWithPorts(name string, factory func() Plugin, ports []int) { // RegisterWithTypes 注册带类型标签的插件 func RegisterWithTypes(name string, factory func() Plugin, ports []int, types []string) { + RegisterWithOptions(name, factory, ports, types, !hasPluginType(types, PluginTypeLocal)) +} + +// RegisterUnsafeWithTypes 注册不适合默认嵌入式扫描的插件。 +func RegisterUnsafeWithTypes(name string, factory func() Plugin, ports []int, types []string) { + RegisterWithOptions(name, factory, ports, types, false) +} + +// RegisterWithOptions 注册带完整元数据的插件。 +func RegisterWithOptions(name string, factory func() Plugin, ports []int, types []string, safe bool) { mutex.Lock() defer mutex.Unlock() plugins[name] = &PluginInfo{ factory: factory, ports: ports, types: types, + safe: safe, } } @@ -147,6 +159,17 @@ func HasType(pluginName string, typeName string) bool { return false } +// IsSafe 检查插件是否适合默认嵌入式扫描。 +func IsSafe(pluginName string) bool { + mutex.RLock() + defer mutex.RUnlock() + + if info, exists := plugins[pluginName]; exists { + return info.safe + } + return false +} + // Get 获取插件实例 func Get(name string) Plugin { mutex.RLock() @@ -190,6 +213,15 @@ func GetPluginPorts(name string) []int { return []int{} // 返回空列表表示适用于所有端口 } +func hasPluginType(types []string, typeName string) bool { + for _, t := range types { + if t == typeName { + return true + } + } + return false +} + // GenerateCredentials 生成测试凭据 func GenerateCredentials(service string, config *common.Config) []Credential { var credentials []Credential diff --git a/plugins/web/types.go b/plugins/web/types.go index 7882ec4..483743b 100644 --- a/plugins/web/types.go +++ b/plugins/web/types.go @@ -22,3 +22,10 @@ func RegisterWebPlugin(name string, creator func() WebPlugin) { return creator() }, []int{}, []string{plugins.PluginTypeWeb}) } + +// RegisterUnsafeWebPlugin 注册需要显式授权的主动Web插件。 +func RegisterUnsafeWebPlugin(name string, creator func() WebPlugin) { + plugins.RegisterUnsafeWithTypes(name, func() plugins.Plugin { + return creator() + }, []int{}, []string{plugins.PluginTypeWeb}) +} diff --git a/plugins/web/webpoc.go b/plugins/web/webpoc.go index 3b43e0b..e09e0c5 100644 --- a/plugins/web/webpoc.go +++ b/plugins/web/webpoc.go @@ -130,7 +130,7 @@ func matchCDNorWAF(fingerprints []string) string { // init 自动注册插件 func init() { - RegisterWebPlugin("webpoc", func() WebPlugin { + RegisterUnsafeWebPlugin("webpoc", func() WebPlugin { return NewWebPocPlugin() }) }