package base import ( "context" "fmt" "time" "github.com/shadow1ng/fscan/common" "github.com/shadow1ng/fscan/common/i18n" ) // ============================================================================= // 完整插件基础实现 // ============================================================================= // BasePlugin 基础插件实现,组合扫描和利用功能 type BasePlugin struct { *BaseScanner *BaseExploiter metadata *PluginMetadata initialized bool } // NewBasePlugin 创建基础插件 func NewBasePlugin(metadata *PluginMetadata) *BasePlugin { return &BasePlugin{ BaseScanner: NewBaseScanner(metadata.Name, metadata), BaseExploiter: NewBaseExploiter(metadata.Name), metadata: metadata, initialized: false, } } // Initialize 初始化插件 func (p *BasePlugin) Initialize() error { if p.initialized { return nil } // 执行插件特定的初始化逻辑 common.LogDebug(i18n.GetText("plugin_init", p.metadata.Name)) p.initialized = true return nil } // GetMetadata 获取插件元数据 func (p *BasePlugin) GetMetadata() *PluginMetadata { return p.metadata } // ============================================================================= // 通用插件实现模板 // ============================================================================= // ServicePlugin 服务插件模板 - 提供常见的服务扫描模式 type ServicePlugin struct { *BasePlugin credentialScanner CredentialScanner serviceConnector ServiceConnector } // ServiceConnector 服务连接器接口 type ServiceConnector interface { // Connect 连接到服务 Connect(ctx context.Context, info *common.HostInfo) (interface{}, error) // Authenticate 认证 Authenticate(ctx context.Context, conn interface{}, cred *Credential) error // Close 关闭连接 Close(conn interface{}) error } // NewServicePlugin 创建服务插件 func NewServicePlugin(metadata *PluginMetadata, connector ServiceConnector) *ServicePlugin { plugin := &ServicePlugin{ BasePlugin: NewBasePlugin(metadata), serviceConnector: connector, } // 设置自己为凭据扫描器 plugin.credentialScanner = plugin return plugin } // Scan 服务扫描实现 func (p *ServicePlugin) Scan(ctx context.Context, info *common.HostInfo) (*ScanResult, error) { // 检查是否禁用暴力破解 if common.DisableBrute { return &ScanResult{ Success: false, Error: fmt.Errorf(i18n.GetText("plugin_brute_disabled")), }, nil } // 生成凭据列表 credentials := p.generateCredentials() if len(credentials) == 0 { return &ScanResult{ Success: false, Error: fmt.Errorf(i18n.GetText("plugin_no_credentials")), }, nil } // 执行并发扫描 config := &ConcurrentScanConfig{ MaxConcurrent: common.ModuleThreadNum, Timeout: time.Duration(common.Timeout) * time.Second, MaxRetries: common.MaxRetries, } return ConcurrentCredentialScan(ctx, p.credentialScanner, info, credentials, config) } // ScanCredential 实现CredentialScanner接口 func (p *ServicePlugin) ScanCredential(ctx context.Context, info *common.HostInfo, cred *Credential) (*ScanResult, error) { // 连接到服务 conn, err := p.serviceConnector.Connect(ctx, info) if err != nil { return &ScanResult{ Success: false, Error: fmt.Errorf("连接失败: %v", err), }, nil } defer p.serviceConnector.Close(conn) // 尝试认证 err = p.serviceConnector.Authenticate(ctx, conn, cred) if err != nil { return &ScanResult{ Success: false, Error: fmt.Errorf("认证失败: %v", err), }, nil } // 认证成功 result := &ScanResult{ Success: true, Service: p.metadata.Name, Credentials: []*Credential{cred}, Extra: make(map[string]interface{}), } return result, nil } // generateCredentials 生成凭据列表(需要子类重写) func (p *ServicePlugin) generateCredentials() []*Credential { // 默认实现:从通用字典生成 serviceName := p.metadata.Name usernames := common.Userdict[serviceName] if len(usernames) == 0 { usernames = []string{"admin", "root", serviceName} } return GenerateCredentials(usernames, common.Passwords) } // GetServiceConnector 获取服务连接器(提供给子插件访问) func (p *ServicePlugin) GetServiceConnector() ServiceConnector { return p.serviceConnector } // ============================================================================= // 插件工厂 // ============================================================================= // PluginFactory 插件工厂接口 type PluginFactory interface { CreatePlugin() Plugin GetMetadata() *PluginMetadata } // SimplePluginFactory 简单插件工厂 type SimplePluginFactory struct { metadata *PluginMetadata creator func() Plugin } // NewSimplePluginFactory 创建简单插件工厂 func NewSimplePluginFactory(metadata *PluginMetadata, creator func() Plugin) *SimplePluginFactory { return &SimplePluginFactory{ metadata: metadata, creator: creator, } } // CreatePlugin 创建插件实例 func (f *SimplePluginFactory) CreatePlugin() Plugin { return f.creator() } // GetMetadata 获取插件元数据 func (f *SimplePluginFactory) GetMetadata() *PluginMetadata { return f.metadata } // ============================================================================= // 插件注册管理器 // ============================================================================= // PluginRegistry 插件注册表 type PluginRegistry struct { factories map[string]PluginFactory } // NewPluginRegistry 创建插件注册表 func NewPluginRegistry() *PluginRegistry { return &PluginRegistry{ factories: make(map[string]PluginFactory), } } // Register 注册插件工厂 func (r *PluginRegistry) Register(name string, factory PluginFactory) { r.factories[name] = factory } // Create 创建插件实例 func (r *PluginRegistry) Create(name string) (Plugin, error) { factory, exists := r.factories[name] if !exists { return nil, fmt.Errorf("插件 %s 未注册", name) } plugin := factory.CreatePlugin() if err := plugin.Initialize(); err != nil { return nil, fmt.Errorf("插件初始化失败: %v", err) } return plugin, nil } // GetAll 获取所有注册的插件名称 func (r *PluginRegistry) GetAll() []string { names := make([]string, 0, len(r.factories)) for name := range r.factories { names = append(names, name) } return names } // GetMetadata 获取插件元数据 func (r *PluginRegistry) GetMetadata(name string) *PluginMetadata { factory, exists := r.factories[name] if !exists { return nil } return factory.GetMetadata() } // GetFactory 获取插件工厂 func (r *PluginRegistry) GetFactory(name string) PluginFactory { return r.factories[name] } // 全局插件注册表 var GlobalPluginRegistry = NewPluginRegistry()