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

- 重构插件注册架构采用现代工厂模式和自动发现机制 - 新增完整的插件元数据管理系统支持版本能力标签等信息 - 实现智能插件适配器提供向后兼容的桥接功能 - 建立MySQL Redis SSH三个标准插件作为新架构参考实现 - 优化插件扫描逻辑支持按端口按类型的智能查询和过滤 - 添加国际化支持和完善的文档体系 - 代码量减少67%维护成本大幅降低扩展性显著提升 新架构特点: - 零配置插件注册import即用 - 工厂模式延迟初始化和依赖注入 - 丰富元数据系统和能力声明 - 完全解耦的模块化设计 - 面向未来的可扩展架构 测试验证: MySQL和Redis插件功能完整包括弱密码检测未授权访问检测和自动利用攻击
246 lines
7.1 KiB
Go
246 lines
7.1 KiB
Go
package base
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/shadow1ng/fscan/common"
|
|
"sort"
|
|
)
|
|
|
|
// =============================================================================
|
|
// 通用利用器基础实现
|
|
// =============================================================================
|
|
|
|
// BaseExploiter 基础利用器,提供通用的利用逻辑
|
|
type BaseExploiter struct {
|
|
Name string
|
|
exploitMethods []ExploitMethod
|
|
}
|
|
|
|
// NewBaseExploiter 创建基础利用器
|
|
func NewBaseExploiter(name string) *BaseExploiter {
|
|
return &BaseExploiter{
|
|
Name: name,
|
|
exploitMethods: make([]ExploitMethod, 0),
|
|
}
|
|
}
|
|
|
|
// AddExploitMethod 添加利用方法
|
|
func (e *BaseExploiter) AddExploitMethod(method ExploitMethod) {
|
|
e.exploitMethods = append(e.exploitMethods, method)
|
|
|
|
// 按优先级排序
|
|
sort.Slice(e.exploitMethods, func(i, j int) bool {
|
|
return e.exploitMethods[i].Priority > e.exploitMethods[j].Priority
|
|
})
|
|
}
|
|
|
|
// GetExploitMethods 获取支持的利用方法
|
|
func (e *BaseExploiter) GetExploitMethods() []ExploitMethod {
|
|
return e.exploitMethods
|
|
}
|
|
|
|
// IsExploitSupported 检查是否支持指定的利用方法
|
|
func (e *BaseExploiter) IsExploitSupported(exploitType ExploitType) bool {
|
|
for _, method := range e.exploitMethods {
|
|
if method.Type == exploitType {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// Exploit 执行利用操作
|
|
func (e *BaseExploiter) Exploit(ctx context.Context, info *common.HostInfo, creds *Credential) (*ExploitResult, error) {
|
|
// 按优先级尝试不同的利用方法
|
|
for _, method := range e.exploitMethods {
|
|
// 检查前置条件
|
|
if !e.checkConditions(method.Conditions, info, creds) {
|
|
common.LogDebug(fmt.Sprintf("利用方法 %s 前置条件不满足,跳过", method.Name))
|
|
continue
|
|
}
|
|
|
|
common.LogDebug(fmt.Sprintf("尝试利用方法: %s", method.Name))
|
|
|
|
// 执行利用
|
|
result, err := method.Handler(ctx, info, creds)
|
|
if err != nil {
|
|
common.LogError(fmt.Sprintf("利用方法 %s 执行失败: %v", method.Name, err))
|
|
continue
|
|
}
|
|
|
|
if result != nil && result.Success {
|
|
common.LogSuccess(fmt.Sprintf("利用方法 %s 执行成功", method.Name))
|
|
result.Type = method.Type
|
|
result.Method = method.Name
|
|
return result, nil
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("所有利用方法都失败")
|
|
}
|
|
|
|
// checkConditions 检查前置条件
|
|
func (e *BaseExploiter) checkConditions(conditions []string, info *common.HostInfo, creds *Credential) bool {
|
|
for _, condition := range conditions {
|
|
if !e.evaluateCondition(condition, info, creds) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// evaluateCondition 评估单个条件
|
|
func (e *BaseExploiter) evaluateCondition(condition string, info *common.HostInfo, creds *Credential) bool {
|
|
switch condition {
|
|
case "has_credentials":
|
|
return creds != nil && (creds.Username != "" || creds.Password != "")
|
|
case "has_username_password":
|
|
return creds != nil && creds.Username != "" && creds.Password != ""
|
|
case "has_password_only":
|
|
return creds != nil && creds.Password != "" && creds.Username == ""
|
|
case "unauthorized_access":
|
|
return creds == nil || (creds.Username == "" && creds.Password == "")
|
|
default:
|
|
// 默认条件满足
|
|
return true
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// 常用利用方法实现
|
|
// =============================================================================
|
|
|
|
// ExploitMethodBuilder 利用方法构建器
|
|
type ExploitMethodBuilder struct {
|
|
method ExploitMethod
|
|
}
|
|
|
|
// NewExploitMethod 创建利用方法构建器
|
|
func NewExploitMethod(exploitType ExploitType, name string) *ExploitMethodBuilder {
|
|
return &ExploitMethodBuilder{
|
|
method: ExploitMethod{
|
|
Type: exploitType,
|
|
Name: name,
|
|
Priority: 5, // 默认优先级
|
|
Conditions: make([]string, 0),
|
|
},
|
|
}
|
|
}
|
|
|
|
// WithDescription 设置描述
|
|
func (b *ExploitMethodBuilder) WithDescription(desc string) *ExploitMethodBuilder {
|
|
b.method.Description = desc
|
|
return b
|
|
}
|
|
|
|
// WithPriority 设置优先级
|
|
func (b *ExploitMethodBuilder) WithPriority(priority int) *ExploitMethodBuilder {
|
|
b.method.Priority = priority
|
|
return b
|
|
}
|
|
|
|
// WithConditions 设置前置条件
|
|
func (b *ExploitMethodBuilder) WithConditions(conditions ...string) *ExploitMethodBuilder {
|
|
b.method.Conditions = conditions
|
|
return b
|
|
}
|
|
|
|
// WithHandler 设置处理函数
|
|
func (b *ExploitMethodBuilder) WithHandler(handler ExploitHandler) *ExploitMethodBuilder {
|
|
b.method.Handler = handler
|
|
return b
|
|
}
|
|
|
|
// Build 构建利用方法
|
|
func (b *ExploitMethodBuilder) Build() ExploitMethod {
|
|
return b.method
|
|
}
|
|
|
|
// =============================================================================
|
|
// 利用结果处理工具
|
|
// =============================================================================
|
|
|
|
// SaveExploitResult 保存利用结果
|
|
func SaveExploitResult(info *common.HostInfo, result *ExploitResult, pluginName string) {
|
|
if result == nil || !result.Success {
|
|
return
|
|
}
|
|
|
|
target := fmt.Sprintf("%s:%d", info.Host, info.Ports)
|
|
|
|
var message string
|
|
switch result.Type {
|
|
case ExploitWeakPassword:
|
|
message = fmt.Sprintf("%s %s 弱密码利用成功", pluginName, target)
|
|
case ExploitUnauthorized:
|
|
message = fmt.Sprintf("%s %s 未授权访问利用成功", pluginName, target)
|
|
case ExploitCommandExec:
|
|
message = fmt.Sprintf("%s %s 命令执行利用成功", pluginName, target)
|
|
case ExploitFileWrite:
|
|
message = fmt.Sprintf("%s %s 文件写入利用成功", pluginName, target)
|
|
case ExploitSQLInjection:
|
|
message = fmt.Sprintf("%s %s SQL注入利用成功", pluginName, target)
|
|
default:
|
|
message = fmt.Sprintf("%s %s %s 利用成功", pluginName, target, result.Type)
|
|
}
|
|
|
|
if result.Output != "" {
|
|
message += fmt.Sprintf(" 输出: %s", result.Output)
|
|
}
|
|
|
|
common.LogSuccess(message)
|
|
|
|
// 保存文件信息
|
|
if len(result.Files) > 0 {
|
|
common.LogSuccess(fmt.Sprintf("创建/修改的文件: %v", result.Files))
|
|
}
|
|
|
|
// 保存Shell信息
|
|
if result.Shell != nil {
|
|
common.LogSuccess(fmt.Sprintf("获得Shell: %s %s:%d 用户:%s",
|
|
result.Shell.Type, result.Shell.Host, result.Shell.Port, result.Shell.User))
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// 常用利用工具函数
|
|
// =============================================================================
|
|
|
|
// CreateSuccessExploitResult 创建成功的利用结果
|
|
func CreateSuccessExploitResult(exploitType ExploitType, method string) *ExploitResult {
|
|
return &ExploitResult{
|
|
Success: true,
|
|
Type: exploitType,
|
|
Method: method,
|
|
Extra: make(map[string]interface{}),
|
|
}
|
|
}
|
|
|
|
// CreateFailedExploitResult 创建失败的利用结果
|
|
func CreateFailedExploitResult(exploitType ExploitType, method string, err error) *ExploitResult {
|
|
return &ExploitResult{
|
|
Success: false,
|
|
Type: exploitType,
|
|
Method: method,
|
|
Error: err,
|
|
Extra: make(map[string]interface{}),
|
|
}
|
|
}
|
|
|
|
// AddOutputToResult 向结果添加输出
|
|
func AddOutputToResult(result *ExploitResult, output string) {
|
|
if result.Output == "" {
|
|
result.Output = output
|
|
} else {
|
|
result.Output += "\n" + output
|
|
}
|
|
}
|
|
|
|
// AddFileToResult 向结果添加文件
|
|
func AddFileToResult(result *ExploitResult, filename string) {
|
|
if result.Files == nil {
|
|
result.Files = make([]string, 0)
|
|
}
|
|
result.Files = append(result.Files, filename)
|
|
} |