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

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