mirror of
https://github.com/shadow1ng/fscan.git
synced 2025-09-14 05:56:46 +08:00

- 新建本地插件统一架构,包含接口定义和基础类 - 实现三个本地插件:fileinfo(文件信息收集)、dcinfo(域控信息收集)、minidump(内存转储) - 添加-localplugin参数,支持指定单个本地插件执行 - 完善参数验证机制,本地模式必须指定插件 - 集成新插件系统到核心扫描策略 - 修复Go方法调用机制导致的插件执行问题 - 支持跨平台和权限检查功能 支持的本地插件: - fileinfo: 敏感文件扫描 - dcinfo: Windows域控信息收集 - minidump: lsass进程内存转储 使用方式: fscan -local -localplugin <plugin_name>
140 lines
3.5 KiB
Go
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")
|
|
} |