mirror of
https://github.com/shadow1ng/fscan.git
synced 2026-09-25 20:51:52 +08:00
move plugin safety metadata to registry
This commit is contained in:
+1
-30
@@ -50,29 +50,6 @@ var defaultSafePlugins = []string{
|
|||||||
"webtitle",
|
"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.
|
// Scanner runs fscan from another Go process.
|
||||||
type Scanner struct {
|
type Scanner struct {
|
||||||
config Config
|
config Config
|
||||||
@@ -134,13 +111,7 @@ func IsSafePlugin(name string) bool {
|
|||||||
if name == "" || !plugins.Exists(name) {
|
if name == "" || !plugins.Exists(name) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if plugins.HasType(name, plugins.PluginTypeLocal) {
|
return plugins.IsSafe(name)
|
||||||
return false
|
|
||||||
}
|
|
||||||
if _, bad := unsafePlugins[name]; bad {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan runs the scanner for the provided targets and returns structured
|
// Scan runs the scanner for the provided targets and returns structured
|
||||||
|
|||||||
@@ -111,6 +111,16 @@ func TestListPlugins(t *testing.T) {
|
|||||||
if _, ok := GetPlugin("definitely-missing"); ok {
|
if _, ok := GetPlugin("definitely-missing"); ok {
|
||||||
t.Fatal("unknown plugin should not exist")
|
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) {
|
func TestScanHonorsCanceledContext(t *testing.T) {
|
||||||
|
|||||||
+33
-1
@@ -43,7 +43,7 @@ const (
|
|||||||
type Result struct {
|
type Result struct {
|
||||||
Type ResultType
|
Type ResultType
|
||||||
Success bool
|
Success bool
|
||||||
Skipped bool // 扫描被跳过,不应输出结果
|
Skipped bool // 扫描被跳过,不应输出结果
|
||||||
Service string
|
Service string
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
@@ -84,6 +84,7 @@ type PluginInfo struct {
|
|||||||
factory func() Plugin
|
factory func() Plugin
|
||||||
ports []int
|
ports []int
|
||||||
types []string // 插件类型标签
|
types []string // 插件类型标签
|
||||||
|
safe bool // 是否适合默认嵌入式扫描
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插件类型常量
|
// 插件类型常量
|
||||||
@@ -123,12 +124,23 @@ func RegisterWithPorts(name string, factory func() Plugin, ports []int) {
|
|||||||
|
|
||||||
// RegisterWithTypes 注册带类型标签的插件
|
// RegisterWithTypes 注册带类型标签的插件
|
||||||
func RegisterWithTypes(name string, factory func() Plugin, ports []int, types []string) {
|
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()
|
mutex.Lock()
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
plugins[name] = &PluginInfo{
|
plugins[name] = &PluginInfo{
|
||||||
factory: factory,
|
factory: factory,
|
||||||
ports: ports,
|
ports: ports,
|
||||||
types: types,
|
types: types,
|
||||||
|
safe: safe,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +159,17 @@ func HasType(pluginName string, typeName string) bool {
|
|||||||
return false
|
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 获取插件实例
|
// Get 获取插件实例
|
||||||
func Get(name string) Plugin {
|
func Get(name string) Plugin {
|
||||||
mutex.RLock()
|
mutex.RLock()
|
||||||
@@ -190,6 +213,15 @@ func GetPluginPorts(name string) []int {
|
|||||||
return []int{} // 返回空列表表示适用于所有端口
|
return []int{} // 返回空列表表示适用于所有端口
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hasPluginType(types []string, typeName string) bool {
|
||||||
|
for _, t := range types {
|
||||||
|
if t == typeName {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// GenerateCredentials 生成测试凭据
|
// GenerateCredentials 生成测试凭据
|
||||||
func GenerateCredentials(service string, config *common.Config) []Credential {
|
func GenerateCredentials(service string, config *common.Config) []Credential {
|
||||||
var credentials []Credential
|
var credentials []Credential
|
||||||
|
|||||||
@@ -22,3 +22,10 @@ func RegisterWebPlugin(name string, creator func() WebPlugin) {
|
|||||||
return creator()
|
return creator()
|
||||||
}, []int{}, []string{plugins.PluginTypeWeb})
|
}, []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})
|
||||||
|
}
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ func matchCDNorWAF(fingerprints []string) string {
|
|||||||
|
|
||||||
// init 自动注册插件
|
// init 自动注册插件
|
||||||
func init() {
|
func init() {
|
||||||
RegisterWebPlugin("webpoc", func() WebPlugin {
|
RegisterUnsafeWebPlugin("webpoc", func() WebPlugin {
|
||||||
return NewWebPocPlugin()
|
return NewWebPocPlugin()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user