mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 14:06:44 +08:00

将复杂的三文件插件架构(connector/exploiter/plugin)重构为简化的单文件插件架构, 大幅减少代码重复和维护成本,提升插件开发效率。 主要改进: • 将每个服务插件从3个文件简化为1个文件 • 删除过度设计的工厂模式、适配器模式等抽象层 • 消除plugins/services/、plugins/adapters/、plugins/base/复杂目录结构 • 实现直接的插件注册机制,提升系统简洁性 • 保持完全向后兼容,所有扫描功能和输出格式不变 重构统计: • 删除文件:100+个复杂架构文件 • 新增文件:20个简化的单文件插件 • 代码减少:每个插件减少60-80%代码量 • 功能增强:所有插件包含完整扫描和利用功能 已重构插件: MySQL, SSH, Redis, MongoDB, PostgreSQL, MSSQL, Oracle, Neo4j, Memcached, RabbitMQ, ActiveMQ, Cassandra, FTP, Kafka, LDAP, Rsync, SMTP, SNMP, Telnet, VNC 验证通过: 新系统编译运行正常,所有插件功能验证通过
174 lines
4.2 KiB
Go
174 lines
4.2 KiB
Go
package core
|
||
|
||
import (
|
||
"fmt"
|
||
"github.com/shadow1ng/fscan/common"
|
||
"github.com/shadow1ng/fscan/plugins"
|
||
"strings"
|
||
)
|
||
|
||
// PluginFilterType 插件过滤类型
|
||
type PluginFilterType int
|
||
|
||
const (
|
||
FilterNone PluginFilterType = iota // 不过滤
|
||
FilterLocal // 仅本地插件
|
||
FilterService // 仅服务插件(排除本地)
|
||
FilterWeb // 仅Web插件
|
||
)
|
||
|
||
// BaseScanStrategy 扫描策略基础类
|
||
type BaseScanStrategy struct {
|
||
strategyName string
|
||
filterType PluginFilterType
|
||
}
|
||
|
||
// NewBaseScanStrategy 创建基础扫描策略
|
||
func NewBaseScanStrategy(name string, filterType PluginFilterType) *BaseScanStrategy {
|
||
return &BaseScanStrategy{
|
||
strategyName: name,
|
||
filterType: filterType,
|
||
}
|
||
}
|
||
|
||
// GetPlugins 获取插件列表(简化版)
|
||
func (b *BaseScanStrategy) GetPlugins() ([]string, bool) {
|
||
// 如果指定了特定插件且不是"all"
|
||
if common.ScanMode != "" && common.ScanMode != "all" {
|
||
requestedPlugins := parsePluginList(common.ScanMode)
|
||
if len(requestedPlugins) == 0 {
|
||
requestedPlugins = []string{common.ScanMode}
|
||
}
|
||
|
||
// 验证插件是否存在
|
||
var validPlugins []string
|
||
for _, name := range requestedPlugins {
|
||
if plugins.GetPlugin(name) != nil {
|
||
validPlugins = append(validPlugins, name)
|
||
}
|
||
}
|
||
|
||
return validPlugins, true
|
||
}
|
||
|
||
// 未指定或使用"all":获取所有插件
|
||
return plugins.GetAllPlugins(), false
|
||
}
|
||
|
||
// IsPluginApplicable 判断插件是否适用(传统接口兼容)
|
||
func (b *BaseScanStrategy) IsPluginApplicable(plugin common.ScanPlugin, targetPort int, isCustomMode bool) bool {
|
||
// 自定义模式下运行所有明确指定的插件
|
||
if isCustomMode {
|
||
return true
|
||
}
|
||
|
||
// 检查插件类型过滤
|
||
switch b.filterType {
|
||
case FilterLocal:
|
||
return plugin.HasType(common.PluginTypeLocal)
|
||
case FilterService:
|
||
// 服务扫描排除本地插件,允许服务和Web插件
|
||
return !plugin.HasType(common.PluginTypeLocal)
|
||
case FilterWeb:
|
||
return plugin.HasType(common.PluginTypeWeb)
|
||
default:
|
||
return true
|
||
}
|
||
}
|
||
|
||
// IsPluginApplicableByName 根据插件名称判断是否适用(新接口)
|
||
func (b *BaseScanStrategy) IsPluginApplicableByName(pluginName string, targetHost string, targetPort int, isCustomMode bool) bool {
|
||
// 自定义模式下运行所有明确指定的插件
|
||
if isCustomMode {
|
||
return true
|
||
}
|
||
|
||
// 获取插件实例
|
||
plugin := plugins.GetPlugin(pluginName)
|
||
if plugin == nil {
|
||
return false
|
||
}
|
||
|
||
// 检查端口匹配(如果指定了端口)
|
||
if targetPort > 0 {
|
||
pluginPorts := plugin.GetPorts()
|
||
if len(pluginPorts) > 0 {
|
||
found := false
|
||
for _, port := range pluginPorts {
|
||
if port == targetPort {
|
||
found = true
|
||
break
|
||
}
|
||
}
|
||
if !found {
|
||
return false
|
||
}
|
||
}
|
||
}
|
||
|
||
return true
|
||
}
|
||
|
||
// LogPluginInfo 输出插件信息(简化版)
|
||
func (b *BaseScanStrategy) LogPluginInfo() {
|
||
allPlugins, isCustomMode := b.GetPlugins()
|
||
|
||
var prefix string
|
||
switch b.filterType {
|
||
case FilterLocal:
|
||
prefix = "本地插件"
|
||
case FilterService:
|
||
prefix = "服务插件"
|
||
case FilterWeb:
|
||
prefix = "Web插件"
|
||
default:
|
||
prefix = "插件"
|
||
}
|
||
|
||
if len(allPlugins) > 0 {
|
||
if isCustomMode {
|
||
common.LogBase(fmt.Sprintf("%s: 自定义指定 (%s)", prefix, strings.Join(allPlugins, ", ")))
|
||
} else {
|
||
common.LogBase(fmt.Sprintf("%s: %s", prefix, strings.Join(allPlugins, ", ")))
|
||
}
|
||
} else {
|
||
common.LogBase(fmt.Sprintf("%s: 无可用插件", prefix))
|
||
}
|
||
}
|
||
|
||
// ValidateConfiguration 验证扫描配置
|
||
func (b *BaseScanStrategy) ValidateConfiguration() error {
|
||
return nil
|
||
}
|
||
|
||
// LogScanStart 输出扫描开始信息
|
||
func (b *BaseScanStrategy) LogScanStart() {
|
||
switch b.filterType {
|
||
case FilterLocal:
|
||
common.LogBase("开始本地扫描")
|
||
case FilterService:
|
||
common.LogBase("开始服务扫描")
|
||
case FilterWeb:
|
||
common.LogBase("开始Web扫描")
|
||
default:
|
||
common.LogBase("开始扫描")
|
||
}
|
||
}
|
||
|
||
// parsePluginList 解析插件列表字符串
|
||
func parsePluginList(pluginStr string) []string {
|
||
if pluginStr == "" {
|
||
return []string{}
|
||
}
|
||
|
||
// 支持逗号分隔的插件列表
|
||
plugins := strings.Split(pluginStr, ",")
|
||
var result []string
|
||
for _, plugin := range plugins {
|
||
plugin = strings.TrimSpace(plugin)
|
||
if plugin != "" {
|
||
result = append(result, plugin)
|
||
}
|
||
}
|
||
return result
|
||
} |