fscan/plugins/init.go
ZacharyZcR 95497da8ca refactor: 优化插件系统设计,消除代码重复
主要改进:
1. 修复Services插件端口数据重复问题
   - 删除插件结构体中的ports字段和GetPorts()方法
   - 系统统一使用注册时的端口信息

2. 引入BasePlugin基础结构体
   - 消除51个插件中重复的name字段和Name()方法
   - 统一插件基础功能,简化代码维护

3. 统一插件接口设计
   - 保持向后兼容,功能完全不变
   - 代码更简洁,符合工程最佳实践

影响范围:
- services插件:29个文件简化
- web插件:2个文件简化
- local插件:21个文件简化
- 总计删除约150行重复代码
2025-09-02 05:36:12 +08:00

168 lines
3.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package plugins
import (
"context"
"strings"
"sync"
"github.com/shadow1ng/fscan/common"
)
// Plugin 统一插件接口 - 消除过度设计
//
// 统一插件系统设计原则:
// 之前3个不同的接口做同样的事情
// 现在1个接口统治所有插件
type Plugin interface {
Name() string
Scan(ctx context.Context, info *common.HostInfo) *Result
}
// BasePlugin 基础插件结构 - 消除插件name字段重复
//
// 所有插件都需要name字段通过基础结构体统一提供
type BasePlugin struct {
name string
}
// NewBasePlugin 创建基础插件
func NewBasePlugin(name string) BasePlugin {
return BasePlugin{name: name}
}
// Name 实现Plugin接口
func (b BasePlugin) Name() string {
return b.name
}
// Result 统一结果结构 - 合并所有类型
type Result struct {
Success bool
Service string
Username string
Password string
Banner string
Output string // web/local插件使用
Error error
// Web插件字段
Title string // 网页标题
Status int // HTTP状态码
Server string // 服务器信息
Length int // 响应长度
VulInfo string // 漏洞信息
}
// Exploiter 利用接口 - 保持向后兼容
type Exploiter interface {
Exploit(ctx context.Context, info *common.HostInfo, creds Credential) *ExploitResult
}
// ExploitResult 利用结果
type ExploitResult struct {
Success bool
Output string
Error error
}
// Credential 认证凭据
type Credential struct {
Username string
Password string
KeyData []byte
}
// PluginInfo 插件信息结构 - 合并工厂和端口信息
type PluginInfo struct {
factory func() Plugin
ports []int
}
// 全局插件注册表 - 一个数据结构解决所有问题
var (
plugins = make(map[string]*PluginInfo)
mutex sync.RWMutex
)
// Register 注册插件 - 一个函数统治所有注册
func Register(name string, factory func() Plugin) {
RegisterWithPorts(name, factory, []int{})
}
// RegisterWithPorts 注册带端口信息的插件
func RegisterWithPorts(name string, factory func() Plugin, ports []int) {
mutex.Lock()
defer mutex.Unlock()
plugins[name] = &PluginInfo{
factory: factory,
ports: ports,
}
}
// Get 获取插件实例
func Get(name string) Plugin {
mutex.RLock()
defer mutex.RUnlock()
if info, exists := plugins[name]; exists {
return info.factory()
}
return nil
}
// All 获取所有插件名称
func All() []string {
mutex.RLock()
defer mutex.RUnlock()
names := make([]string, 0, len(plugins))
for name := range plugins {
names = append(names, name)
}
return names
}
// Exists 检查插件是否存在,不创建实例 - 解决性能问题
func Exists(name string) bool {
mutex.RLock()
defer mutex.RUnlock()
_, exists := plugins[name]
return exists
}
// GetPluginPorts 获取插件端口列表
func GetPluginPorts(name string) []int {
mutex.RLock()
defer mutex.RUnlock()
if info, exists := plugins[name]; exists {
return info.ports
}
return []int{} // 返回空列表表示适用于所有端口
}
// GenerateCredentials 生成测试凭据 - 从services包移到这里统一管理
func GenerateCredentials(service string) []Credential {
users := common.Userdict[service]
if len(users) == 0 {
users = []string{"admin", "root", "administrator", "user", "guest", ""}
}
passwords := common.Passwords
if len(passwords) == 0 {
passwords = []string{"", "admin", "root", "password", "123456"}
}
var credentials []Credential
for _, user := range users {
for _, pass := range passwords {
actualPass := strings.Replace(pass, "{user}", user, -1)
credentials = append(credentials, Credential{
Username: user,
Password: actualPass,
})
}
}
return credentials
}