fscan/Core/PluginAdapter.go
ZacharyZcR eeaa4c3b3a feat: 实现本地插件架构迁移与统一管理
- 新建本地插件统一架构,包含接口定义和基础类
- 实现三个本地插件:fileinfo(文件信息收集)、dcinfo(域控信息收集)、minidump(内存转储)
- 添加-localplugin参数,支持指定单个本地插件执行
- 完善参数验证机制,本地模式必须指定插件
- 集成新插件系统到核心扫描策略
- 修复Go方法调用机制导致的插件执行问题
- 支持跨平台和权限检查功能

支持的本地插件:
- fileinfo: 敏感文件扫描
- dcinfo: Windows域控信息收集
- minidump: lsass进程内存转储

使用方式: fscan -local -localplugin <plugin_name>
2025-08-09 22:43:28 +08:00

140 lines
3.5 KiB
Go

package core
import (
"context"
"fmt"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/plugins/base"
)
// PluginAdapter 插件适配器
// 提供从新插件系统到旧扫描接口的适配
type PluginAdapter struct {
registry *base.PluginRegistry
}
// NewPluginAdapter 创建插件适配器
func NewPluginAdapter() *PluginAdapter {
return &PluginAdapter{
registry: base.GlobalPluginRegistry,
}
}
// 全局插件适配器实例
var GlobalPluginAdapter = NewPluginAdapter()
// GetAllPluginNames 获取所有插件名称
func (pa *PluginAdapter) GetAllPluginNames() []string {
return pa.registry.GetAll()
}
// PluginExists 检查插件是否存在
func (pa *PluginAdapter) PluginExists(name string) bool {
metadata := pa.registry.GetMetadata(name)
return metadata != nil
}
// GetPluginPorts 获取插件支持的端口
func (pa *PluginAdapter) GetPluginPorts(name string) []int {
metadata := pa.registry.GetMetadata(name)
if metadata != nil {
return metadata.Ports
}
return []int{}
}
// GetPluginsByPort 根据端口获取支持的插件
func (pa *PluginAdapter) GetPluginsByPort(port int) []string {
var plugins []string
for _, name := range pa.registry.GetAll() {
metadata := pa.registry.GetMetadata(name)
if metadata != nil {
for _, p := range metadata.Ports {
if p == port {
plugins = append(plugins, name)
break
}
}
}
}
return plugins
}
// GetPluginsByType 根据类型获取插件
func (pa *PluginAdapter) GetPluginsByType(pluginType string) []string {
var plugins []string
for _, name := range pa.registry.GetAll() {
metadata := pa.registry.GetMetadata(name)
if metadata != nil {
if metadata.Category == pluginType {
plugins = append(plugins, name)
}
}
}
return plugins
}
// ScanWithPlugin 使用插件进行扫描
func (pa *PluginAdapter) ScanWithPlugin(pluginName string, info *common.HostInfo) error {
common.LogDebug(fmt.Sprintf("使用新插件架构扫描: %s", pluginName))
// 创建插件实例
plugin, err := pa.registry.Create(pluginName)
if err != nil {
return fmt.Errorf("创建插件 %s 失败: %v", pluginName, err)
}
// 执行扫描
result, err := plugin.Scan(context.Background(), info)
if err != nil {
return fmt.Errorf("插件 %s 扫描失败: %v", pluginName, err)
}
// 处理扫描结果
if result == nil {
common.LogDebug(fmt.Sprintf("插件 %s 返回了空结果", pluginName))
} else if result.Success {
common.LogDebug(fmt.Sprintf("插件 %s 扫描成功", pluginName))
// TODO: 输出扫描结果
} else {
common.LogDebug(fmt.Sprintf("插件 %s 扫描失败: %v", pluginName, result.Error))
}
return nil
}
// FilterPluginsByType 按类型过滤插件名称
func FilterPluginsByType(pluginType string) func(name string) bool {
return func(name string) bool {
metadata := GlobalPluginAdapter.registry.GetMetadata(name)
if metadata == nil {
return false
}
switch pluginType {
case common.PluginTypeService:
return metadata.Category == "service"
case common.PluginTypeWeb:
return metadata.Category == "web"
case common.PluginTypeLocal:
return metadata.Category == "local"
default:
return true
}
}
}
// GetServicePlugins 获取所有服务插件
func GetServicePlugins() []string {
return GlobalPluginAdapter.GetPluginsByType("service")
}
// GetWebPlugins 获取所有Web插件
func GetWebPlugins() []string {
return GlobalPluginAdapter.GetPluginsByType("web")
}
// GetLocalPlugins 获取所有本地插件
func GetLocalPlugins() []string {
return GlobalPluginAdapter.GetPluginsByType("local")
}