fscan/Plugins/local/plugin.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

155 lines
4.1 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 local
import (
"context"
"errors"
"fmt"
"runtime"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/plugins/base"
)
// BaseLocalPlugin 本地插件基础实现
type BaseLocalPlugin struct {
*base.BasePlugin
connector LocalConnector
platforms []string
requiresPrivileges bool
}
// NewBaseLocalPlugin 创建基础本地插件
func NewBaseLocalPlugin(metadata *base.PluginMetadata, connector LocalConnector) *BaseLocalPlugin {
basePlugin := base.NewBasePlugin(metadata)
return &BaseLocalPlugin{
BasePlugin: basePlugin,
connector: connector,
platforms: []string{"windows", "linux", "darwin"},
requiresPrivileges: false,
}
}
// Initialize 初始化插件
func (p *BaseLocalPlugin) Initialize() error {
// 检查平台支持
if !p.isPlatformSupported() {
return fmt.Errorf("当前平台 %s 不支持此插件", runtime.GOOS)
}
return p.BasePlugin.Initialize()
}
// Scan 执行扫描
func (p *BaseLocalPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
// 检查权限要求
if p.requiresPrivileges && !p.hasRequiredPrivileges() {
return &base.ScanResult{
Success: false,
Error: errors.New("需要管理员/root权限才能执行此扫描"),
}, nil
}
return p.ScanLocal(ctx, info)
}
// ScanLocal 默认本地扫描实现(子类应重写)
func (p *BaseLocalPlugin) ScanLocal(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
return &base.ScanResult{
Success: false,
Error: errors.New("ScanLocal方法需要在子类中实现"),
}, nil
}
// Exploit 执行利用
func (p *BaseLocalPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) {
// 获取本地数据
data, err := p.GetLocalData(ctx)
if err != nil {
return &base.ExploitResult{
Success: false,
Error: fmt.Errorf("获取本地数据失败: %v", err),
}, nil
}
return p.ExtractData(ctx, info, data)
}
// GetLocalData 默认获取本地数据实现(子类应重写)
func (p *BaseLocalPlugin) GetLocalData(ctx context.Context) (map[string]interface{}, error) {
return nil, fmt.Errorf("GetLocalData方法需要在子类中实现")
}
// ExtractData 默认数据提取实现(子类应重写)
func (p *BaseLocalPlugin) ExtractData(ctx context.Context, info *common.HostInfo, data map[string]interface{}) (*base.ExploitResult, error) {
return &base.ExploitResult{
Success: false,
Error: errors.New("ExtractData方法需要在子类中实现"),
}, nil
}
// GetLocalConnector 获取本地连接器
func (p *BaseLocalPlugin) GetLocalConnector() LocalConnector {
return p.connector
}
// GetPlatformSupport 获取支持的平台
func (p *BaseLocalPlugin) GetPlatformSupport() []string {
return p.platforms
}
// SetPlatformSupport 设置支持的平台
func (p *BaseLocalPlugin) SetPlatformSupport(platforms []string) {
p.platforms = platforms
}
// RequiresPrivileges 是否需要特殊权限
func (p *BaseLocalPlugin) RequiresPrivileges() bool {
return p.requiresPrivileges
}
// SetRequiresPrivileges 设置是否需要特殊权限
func (p *BaseLocalPlugin) SetRequiresPrivileges(required bool) {
p.requiresPrivileges = required
}
// isPlatformSupported 检查当前平台是否支持
func (p *BaseLocalPlugin) isPlatformSupported() bool {
currentOS := runtime.GOOS
for _, platform := range p.platforms {
if platform == currentOS {
return true
}
}
return false
}
// hasRequiredPrivileges 检查是否具有所需权限
func (p *BaseLocalPlugin) hasRequiredPrivileges() bool {
if !p.requiresPrivileges {
return true
}
// 这里可以根据平台实现权限检查
// Windows: 检查是否为管理员
// Linux/macOS: 检查是否为root或有sudo权限
switch runtime.GOOS {
case "windows":
return isWindowsAdmin()
case "linux", "darwin":
return isUnixRoot()
default:
return false
}
}
// 平台特定的权限检查函数
func isWindowsAdmin() bool {
// 这里可以调用Windows API检查管理员权限
// 简化实现实际应该使用Windows API
return false
}
func isUnixRoot() bool {
// 检查是否为root用户
return false
}