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

- 删除整个legacy插件系统(7794行代码) - 完成所有插件向单文件架构迁移 - 移除19个插件的虚假Exploit功能,只保留真实利用: * Redis: 文件写入、SSH密钥注入、计划任务 * SSH: 命令执行 * MS17010: EternalBlue漏洞利用 - 统一插件接口,简化架构复杂度 - 清理临时文件和备份文件 重构效果: - 代码行数: -7794行 - 插件文件数: 从3文件架构→单文件架构 - 真实利用插件: 从22个→3个 - 架构复杂度: 大幅简化
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/services"
|
||
"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 services.GetPlugin(name) != nil {
|
||
validPlugins = append(validPlugins, name)
|
||
}
|
||
}
|
||
|
||
return validPlugins, true
|
||
}
|
||
|
||
// 未指定或使用"all":获取所有插件
|
||
return services.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 := services.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
|
||
} |