fscan/Plugins/services/mysql/mysql_test.go
ZacharyZcR 43f210ffc6 feat: 实现新一代插件注册系统完全替代传统手动注册模式
- 重构插件注册架构采用现代工厂模式和自动发现机制
- 新增完整的插件元数据管理系统支持版本能力标签等信息
- 实现智能插件适配器提供向后兼容的桥接功能
- 建立MySQL Redis SSH三个标准插件作为新架构参考实现
- 优化插件扫描逻辑支持按端口按类型的智能查询和过滤
- 添加国际化支持和完善的文档体系
- 代码量减少67%维护成本大幅降低扩展性显著提升

新架构特点:
- 零配置插件注册import即用
- 工厂模式延迟初始化和依赖注入
- 丰富元数据系统和能力声明
- 完全解耦的模块化设计
- 面向未来的可扩展架构

测试验证: MySQL和Redis插件功能完整包括弱密码检测未授权访问检测和自动利用攻击
2025-08-07 11:28:34 +08:00

146 lines
3.6 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 mysql
import (
"context"
"fmt"
"testing"
"time"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/plugins/base"
)
func TestMySQLPlugin(t *testing.T) {
// 初始化基本配置(超时时间以秒为单位)
common.Timeout = 3 // 3秒超时不是3000秒
common.MaxRetries = 2
common.ModuleThreadNum = 5
common.DisableBrute = false
// 创建插件
plugin := NewMySQLPlugin()
// 测试插件元数据
metadata := plugin.GetMetadata()
if metadata.Name != "mysql" {
t.Errorf("期望插件名为 'mysql',实际为 '%s'", metadata.Name)
}
// 测试能力
capabilities := plugin.GetCapabilities()
if len(capabilities) == 0 {
t.Error("插件应该有能力定义")
}
// 测试利用方法
exploitMethods := plugin.GetExploitMethods()
if len(exploitMethods) == 0 {
t.Error("插件应该有利用方法定义")
}
t.Logf("MySQL插件测试通过能力数量: %d利用方法数量: %d",
len(capabilities), len(exploitMethods))
}
func TestMySQLConnector(t *testing.T) {
connector := NewMySQLConnector()
// 创建测试主机信息
hostInfo := &common.HostInfo{
Host: "127.0.0.1",
Ports: "3306",
}
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 测试连接(这会失败,但我们测试的是接口)
_, err := connector.Connect(ctx, hostInfo)
// 我们期望这里出错因为没有实际的MySQL服务器
// 但接口应该正常工作
if err == nil {
t.Log("连接器接口正常工作")
} else {
t.Logf("连接器测试完成,错误(预期): %v", err)
}
}
func TestCredentialGeneration(t *testing.T) {
// 测试凭据生成
usernames := []string{"root", "mysql", "admin"}
passwords := []string{"password", "123456", "{user}"}
credentials := base.GenerateCredentials(usernames, passwords)
expectedCount := len(usernames) * len(passwords)
if len(credentials) != expectedCount {
t.Errorf("期望生成 %d 个凭据,实际生成 %d 个", expectedCount, len(credentials))
}
// 检查 {user} 占位符替换
found := false
for _, cred := range credentials {
if cred.Username == "root" && cred.Password == "root" {
found = true
break
}
}
if !found {
t.Error("没有找到 {user} 占位符替换的凭据")
}
t.Logf("凭据生成测试通过,生成 %d 个凭据", len(credentials))
}
func TestExploitMethods(t *testing.T) {
exploiter := NewMySQLExploiter()
methods := exploiter.GetExploitMethods()
// 检查是否有信息收集方法
hasInfoGathering := false
for _, method := range methods {
if method.Name == "information_gathering" {
hasInfoGathering = true
break
}
}
if !hasInfoGathering {
t.Error("应该包含信息收集利用方法")
}
// 检查利用类型支持
if !exploiter.IsExploitSupported(base.ExploitDataExtraction) {
t.Error("应该支持数据提取利用")
}
if !exploiter.IsExploitSupported(base.ExploitFileWrite) {
t.Error("应该支持文件写入利用")
}
t.Logf("利用方法测试通过,方法数量: %d", len(methods))
}
// 基准测试:插件创建性能
func BenchmarkPluginCreation(b *testing.B) {
for i := 0; i < b.N; i++ {
plugin := NewMySQLPlugin()
_ = plugin
}
}
// 基准测试:凭据生成性能
func BenchmarkCredentialGeneration(b *testing.B) {
usernames := []string{"root", "mysql", "admin", "test", "user"}
passwords := make([]string, 100) // 模拟100个密码
for i := range passwords {
passwords[i] = fmt.Sprintf("password%d", i)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
credentials := base.GenerateCredentials(usernames, passwords)
_ = credentials
}
}