package adapters import ( "context" "fmt" "github.com/shadow1ng/fscan/common" "github.com/shadow1ng/fscan/plugins/base" ) // LegacyPluginFunc 老版本插件的函数签名 type LegacyPluginFunc func(*common.HostInfo) error // LegacyPlugin 老版本插件适配器 type LegacyPlugin struct { metadata *base.PluginMetadata legacyFunc LegacyPluginFunc options *LegacyPluginOptions } // LegacyPluginOptions 老版本插件选项 type LegacyPluginOptions struct { // 是否需要检查暴力破解开关 CheckBruteFlag bool // 是否为漏洞检测类插件 IsVulnPlugin bool // 是否为信息收集类插件 IsInfoPlugin bool // 自定义端口(如果不使用metadata中的端口) CustomPorts []int } // NewLegacyPlugin 创建老版本插件适配器 func NewLegacyPlugin(metadata *base.PluginMetadata, legacyFunc LegacyPluginFunc, options *LegacyPluginOptions) *LegacyPlugin { if options == nil { options = &LegacyPluginOptions{ CheckBruteFlag: true, IsVulnPlugin: true, } } return &LegacyPlugin{ metadata: metadata, legacyFunc: legacyFunc, options: options, } } // GetMetadata 实现Plugin接口 func (p *LegacyPlugin) GetMetadata() *base.PluginMetadata { return p.metadata } // GetName 实现Scanner接口 func (p *LegacyPlugin) GetName() string { return p.metadata.Name } // Initialize 实现Plugin接口 func (p *LegacyPlugin) Initialize() error { return nil } // Scan 实现Plugin接口 - 适配老版本插件调用 func (p *LegacyPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) { // 检查上下文是否取消 select { case <-ctx.Done(): return nil, ctx.Err() default: } // 如果需要检查暴力破解标志且已禁用暴力破解 if p.options.CheckBruteFlag && common.DisableBrute { if p.options.IsVulnPlugin { // 漏洞检测类插件在禁用暴力破解时仍然运行 // 这里不返回,继续执行 } else { // 非漏洞检测类插件在禁用暴力破解时跳过 return &base.ScanResult{ Success: false, Service: p.metadata.Name, Error: fmt.Errorf("brute force disabled"), }, nil } } // 调用老版本插件函数 err := p.legacyFunc(info) if err != nil { // 插件执行失败 return &base.ScanResult{ Success: false, Service: p.metadata.Name, Error: err, }, nil } // 插件执行成功 // 老版本插件通常自己处理日志和结果输出,所以这里返回基本成功信息 return &base.ScanResult{ Success: true, Service: p.metadata.Name, Banner: fmt.Sprintf("%s scan completed", p.metadata.Name), Extra: map[string]interface{}{ "plugin_type": "legacy", "category": p.metadata.Category, }, }, nil } // ScanCredential 实现Plugin接口 - 老版本插件不支持单独的凭据测试 func (p *LegacyPlugin) ScanCredential(ctx context.Context, info *common.HostInfo, cred *base.Credential) (*base.ScanResult, error) { // 老版本插件通常内部处理凭据,所以这里直接调用Scan return p.Scan(ctx, info) } // ============================================================================= // Exploiter接口实现 - 老版本插件通常不支持独立的利用功能 // ============================================================================= // Exploit 实现Exploiter接口 - 老版本插件通常不支持单独利用 func (p *LegacyPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { // 老版本插件通常在Scan中完成所有操作,不支持独立利用 return nil, fmt.Errorf("legacy plugin does not support separate exploitation") } // GetExploitMethods 实现Exploiter接口 - 返回空的利用方法列表 func (p *LegacyPlugin) GetExploitMethods() []base.ExploitMethod { // 老版本插件不支持独立的利用方法 return []base.ExploitMethod{} } // IsExploitSupported 实现Exploiter接口 - 老版本插件不支持独立利用 func (p *LegacyPlugin) IsExploitSupported(method base.ExploitType) bool { // 老版本插件不支持独立的利用方法 return false } // GetCapabilities 实现Plugin接口 func (p *LegacyPlugin) GetCapabilities() []base.Capability { capabilities := []base.Capability{} // 根据插件类型分配合适的能力 if p.options.IsVulnPlugin { // 漏洞检测插件通常涉及信息泄露检测 capabilities = append(capabilities, base.CapInformationLeak) } if p.options.IsInfoPlugin { // 信息收集插件 capabilities = append(capabilities, base.CapInformationLeak) } // 大多数老版本插件都支持弱密码检测 if p.options.CheckBruteFlag { capabilities = append(capabilities, base.CapWeakPassword) } return capabilities } // SetCapabilities 实现Plugin接口 - 老版本插件不支持动态设置能力 func (p *LegacyPlugin) SetCapabilities(capabilities []base.Capability) { // 老版本插件的能力是固定的,这里不做任何操作 } // GetDefaultPorts 获取默认端口 func (p *LegacyPlugin) GetDefaultPorts() []int { if len(p.options.CustomPorts) > 0 { return p.options.CustomPorts } return p.metadata.Ports } // Cleanup 清理资源 func (p *LegacyPlugin) Cleanup() error { // 老版本插件通常没有需要清理的资源 return nil }