From f097d2812a85081821362e08b367e6dfbf961304 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Tue, 12 Aug 2025 11:51:36 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=B8=85=E7=90=86=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E6=AD=BB=E4=BB=A3=E7=A0=81=E5=92=8C=E6=9C=AA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除所有未使用的generateCredentials方法 - 删除插件适配器中的过时函数 - 清理MySQL连接器中的无用方法 - 移除Redis利用器中的未调用函数 - 删除遗留加密函数和基础扫描器无用方法 - 完全移除未注册的VNC插件 - 优化代码结构,提升项目可维护性 清理统计: 移除25+个死代码函数,减少400+行无用代码 --- Plugins/adapters/plugin_adapter.go | 168 +--------------------- Plugins/base/scanner.go | 44 +----- Plugins/legacy/Base.go | 33 ----- Plugins/services/activemq/connector.go | 10 +- Plugins/services/activemq/plugin.go | 32 +---- Plugins/services/cassandra/plugin.go | 25 +--- Plugins/services/ftp/plugin.go | 12 +- Plugins/services/imap/plugin.go | 12 +- Plugins/services/kafka/plugin.go | 12 +- Plugins/services/ldap/plugin.go | 12 +- Plugins/services/memcached/plugin.go | 8 +- Plugins/services/modbus/plugin.go | 8 +- Plugins/services/mongodb/plugin.go | 28 +--- Plugins/services/mysql/connector.go | 23 +-- Plugins/services/mysql/plugin.go | 12 +- Plugins/services/redis/exploiter.go | 97 +------------ Plugins/services/redis/plugin.go | 6 +- Plugins/services/ssh/plugin.go | 12 +- Plugins/services/vnc/connector.go | 111 --------------- Plugins/services/vnc/exploiter.go | 25 ---- Plugins/services/vnc/plugin.go | 187 ------------------------- 21 files changed, 26 insertions(+), 851 deletions(-) delete mode 100644 Plugins/services/vnc/connector.go delete mode 100644 Plugins/services/vnc/exploiter.go delete mode 100644 Plugins/services/vnc/plugin.go diff --git a/Plugins/adapters/plugin_adapter.go b/Plugins/adapters/plugin_adapter.go index 40cc3c9..2f1a50a 100644 --- a/Plugins/adapters/plugin_adapter.go +++ b/Plugins/adapters/plugin_adapter.go @@ -1,165 +1,7 @@ +// Package adapters provides plugin compatibility layers. +// This package contains legacy adapter code that was part of a transition architecture. +// The adapter functions were not being used in the current codebase. package adapters -import ( - "context" - "fmt" - "github.com/shadow1ng/fscan/common" - "github.com/shadow1ng/fscan/common/i18n" - "github.com/shadow1ng/fscan/common/output" - "github.com/shadow1ng/fscan/plugins/base" - "time" - - // 导入新插件以触发注册 - _ "github.com/shadow1ng/fscan/plugins/services/mysql" - _ "github.com/shadow1ng/fscan/plugins/services/redis" - _ "github.com/shadow1ng/fscan/plugins/services/ssh" -) - -// PluginAdapter 插件适配器,将新插件架构与旧系统集成 -type PluginAdapter struct { - registry *base.PluginRegistry -} - -// NewPluginAdapter 创建插件适配器 -func NewPluginAdapter() *PluginAdapter { - return &PluginAdapter{ - registry: base.GlobalPluginRegistry, - } -} - -// AdaptPluginScan 适配插件扫描调用 -// 将传统的插件扫描函数调用转换为新架构的插件调用 -func (a *PluginAdapter) AdaptPluginScan(pluginName string, info *common.HostInfo) error { - // 创建插件实例 - plugin, err := a.registry.Create(pluginName) - if err != nil { - // 如果新架构中没有该插件,返回错误让旧系统处理 - return fmt.Errorf("plugin %s not found in new architecture: %v", pluginName, err) - } - - // 初始化插件 - if err := plugin.Initialize(); err != nil { - return fmt.Errorf("plugin %s initialization failed: %v", pluginName, err) - } - - // 设置全局超时上下文 - ctx, cancel := context.WithTimeout(context.Background(), time.Duration(common.GlobalTimeout)*time.Second) - defer cancel() - - // 执行扫描 - result, err := plugin.Scan(ctx, info) - if err != nil { - common.LogError(fmt.Sprintf("Plugin %s scan failed: %v", pluginName, err)) - return err - } - - // 如果扫描成功,记录结果 - if result != nil && result.Success { - target := fmt.Sprintf("%s:%s", info.Host, info.Ports) - - // 适配器层不输出扫描结果,由插件层负责输出 - // 这避免了重复输出的问题 - common.LogDebug(fmt.Sprintf("插件 %s 适配成功: %s", pluginName, target)) - - // 保存结果到文件 - a.saveResult(info, result, pluginName) - - // 如果有漏洞信息,也记录下来 - for _, vuln := range result.Vulnerabilities { - common.LogError(fmt.Sprintf("%s vulnerability found: %s - %s", - pluginName, vuln.ID, vuln.Description)) - } - } - - return nil -} - -// saveResult 保存扫描结果 -func (a *PluginAdapter) saveResult(info *common.HostInfo, result *base.ScanResult, pluginName string) { - // 使用原有的结果保存机制 - - vulnResult := &output.ScanResult{ - Time: time.Now(), - Type: output.TypeVuln, - Target: info.Host, - Status: "vulnerable", - Details: map[string]interface{}{ - "plugin": pluginName, - "port": info.Ports, - "host": info.Host, - }, - } - - if len(result.Credentials) > 0 { - cred := result.Credentials[0] - if cred.Username != "" { - vulnResult.Details["username"] = cred.Username - vulnResult.Details["password"] = cred.Password - vulnResult.Details["credentials"] = fmt.Sprintf("%s:%s", cred.Username, cred.Password) - } else { - vulnResult.Details["password"] = cred.Password - vulnResult.Details["credentials"] = cred.Password - } - } else { - // 未授权访问 - vulnResult.Details["type"] = "unauthorized" - } - - // 保存结果 - common.SaveResult(vulnResult) -} - -// IsPluginSupported 检查插件是否在新架构中支持 -func (a *PluginAdapter) IsPluginSupported(pluginName string) bool { - plugins := a.registry.GetAll() - for _, name := range plugins { - if name == pluginName { - return true - } - } - return false -} - -// GetSupportedPlugins 获取新架构支持的插件列表 -func (a *PluginAdapter) GetSupportedPlugins() []string { - return a.registry.GetAll() -} - -// GetPluginMetadata 获取插件元数据 -func (a *PluginAdapter) GetPluginMetadata(pluginName string) (*base.PluginMetadata, error) { - metadata := a.registry.GetMetadata(pluginName) - if metadata == nil { - return nil, fmt.Errorf("plugin %s not found", pluginName) - } - return metadata, nil -} - -// ============================================================================= -// 全局适配器实例 -// ============================================================================= - -// GlobalAdapter 全局插件适配器实例 -var GlobalAdapter = NewPluginAdapter() - -// ============================================================================= -// 便捷函数 -// ============================================================================= - -// TryNewArchitecture 尝试使用新架构执行插件扫描 -// 如果新架构支持该插件,则使用新架构;否则返回false让调用方使用旧插件 -func TryNewArchitecture(pluginName string, info *common.HostInfo) bool { - if !GlobalAdapter.IsPluginSupported(pluginName) { - common.LogDebug(i18n.GetText("plugin_legacy_using", pluginName)) - return false - } - - common.LogDebug(i18n.GetText("plugin_new_arch_trying", pluginName)) - err := GlobalAdapter.AdaptPluginScan(pluginName, info) - if err != nil { - common.LogError(i18n.GetText("plugin_new_arch_fallback", pluginName, err)) - return false - } - - common.LogDebug(i18n.GetText("plugin_new_arch_success", pluginName)) - return true -} \ No newline at end of file +// Legacy plugin adapter functionality has been removed as it was unused. +// This file is preserved for future compatibility needs if required. \ No newline at end of file diff --git a/Plugins/base/scanner.go b/Plugins/base/scanner.go index 39e707a..d553e23 100644 --- a/Plugins/base/scanner.go +++ b/Plugins/base/scanner.go @@ -264,46 +264,4 @@ func GenerateCredentials(usernames []string, passwords []string) []*Credential { return credentials } -// GeneratePasswordOnlyCredentials 生成仅密码的凭据列表(如Redis) -func GeneratePasswordOnlyCredentials(passwords []string) []*Credential { - var credentials []*Credential - - for _, password := range passwords { - credentials = append(credentials, &Credential{ - Password: password, - Extra: make(map[string]string), - }) - } - - return credentials -} - -// ============================================================================= -// 结果处理工具 -// ============================================================================= - -// SaveScanResult 保存扫描结果到通用输出系统 -func SaveScanResult(info *common.HostInfo, result *ScanResult, pluginName string) { - if result == nil || !result.Success { - return - } - - target := fmt.Sprintf("%s:%d", info.Host, info.Ports) - - // 保存成功的凭据 - for _, cred := range result.Credentials { - var message string - if cred.Username != "" && cred.Password != "" { - message = fmt.Sprintf("%s %s %s %s", pluginName, target, cred.Username, cred.Password) - } else if cred.Password != "" { - message = fmt.Sprintf("%s %s [密码] %s", pluginName, target, cred.Password) - } else { - message = fmt.Sprintf("%s %s 未授权访问", pluginName, target) - } - - common.LogSuccess(message) - - // 保存到输出系统的详细实现... - // 这里可以调用common.SaveResult等函数 - } -} \ No newline at end of file +// 已移除未使用的 GeneratePasswordOnlyCredentials 方法 \ No newline at end of file diff --git a/Plugins/legacy/Base.go b/Plugins/legacy/Base.go index 20fa91a..d315765 100644 --- a/Plugins/legacy/Base.go +++ b/Plugins/legacy/Base.go @@ -1,7 +1,6 @@ package Plugins import ( - "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" @@ -44,32 +43,6 @@ func ReadBytes(conn net.Conn) ([]byte, error) { // 默认AES加密密钥 var key = "0123456789abcdef" -// AesEncrypt 使用AES-CBC模式加密字符串 -func AesEncrypt(orig string, key string) (string, error) { - // 转为字节数组 - origData := []byte(orig) - keyBytes := []byte(key) - - // 创建加密块,要求密钥长度必须为16/24/32字节 - block, err := aes.NewCipher(keyBytes) - if err != nil { - return "", fmt.Errorf("创建加密块失败: %v", err) - } - - // 获取块大小并填充数据 - blockSize := block.BlockSize() - origData = PKCS7Padding(origData, blockSize) - - // 创建CBC加密模式 - blockMode := cipher.NewCBCEncrypter(block, keyBytes[:blockSize]) - - // 加密数据 - encrypted := make([]byte, len(origData)) - blockMode.CryptBlocks(encrypted, origData) - - // base64编码 - return base64.StdEncoding.EncodeToString(encrypted), nil -} // AesDecrypt 使用AES-CBC模式解密字符串 func AesDecrypt(crypted string, key string) (string, error) { @@ -104,12 +77,6 @@ func AesDecrypt(crypted string, key string) (string, error) { return string(origData), nil } -// PKCS7Padding 对数据进行PKCS7填充 -func PKCS7Padding(data []byte, blockSize int) []byte { - padding := blockSize - len(data)%blockSize - padtext := bytes.Repeat([]byte{byte(padding)}, padding) - return append(data, padtext...) -} // PKCS7UnPadding 去除PKCS7填充 func PKCS7UnPadding(data []byte) ([]byte, error) { diff --git a/Plugins/services/activemq/connector.go b/Plugins/services/activemq/connector.go index b1424c4..a490754 100644 --- a/Plugins/services/activemq/connector.go +++ b/Plugins/services/activemq/connector.go @@ -172,15 +172,7 @@ func (c *ActiveMQConnector) parseSTOMPResponse(response string) (bool, error) { -// getProtocolByPort 根据端口获取协议类型 -func (c *ActiveMQConnector) getProtocolByPort(port int) string { - switch port { - case 61613, 61614: - return "STOMP" - default: - return "STOMP" // 默认仅支持STOMP - } -} +// 已移除未使用的 getProtocolByPort 方法 // GetDefaultCredentials 获取ActiveMQ默认凭据 func (c *ActiveMQConnector) GetDefaultCredentials() []*base.Credential { diff --git a/Plugins/services/activemq/plugin.go b/Plugins/services/activemq/plugin.go index 1f22dec..355c830 100644 --- a/Plugins/services/activemq/plugin.go +++ b/Plugins/services/activemq/plugin.go @@ -150,37 +150,7 @@ func (p *ActiveMQPlugin) IsExploitSupported(method base.ExploitType) bool { return p.exploiter.IsExploitSupported(method) } -// generateCredentials 重写凭据生成方法 -func (p *ActiveMQPlugin) generateCredentials() []*base.Credential { - // 获取ActiveMQ专用的用户名字典 - usernames := common.Userdict["activemq"] - if len(usernames) == 0 { - // 默认ActiveMQ用户名 - usernames = []string{ - "admin", "test", "root", "system", "user", "guest", - "manager", "activemq", "mqadmin", "broker", - } - } - - // 生成基本凭据组合 - credentials := base.GenerateCredentials(usernames, common.Passwords) - - // 添加ActiveMQ专用的默认凭据 - defaultCreds := p.ServicePlugin.GetServiceConnector().(*ActiveMQConnector).GetDefaultCredentials() - credentials = append(credentials, defaultCreds...) - - // 去重处理(简化实现) - seen := make(map[string]bool) - var unique []*base.Credential - for _, cred := range credentials { - key := cred.Username + ":" + cred.Password - if !seen[key] { - seen[key] = true - unique = append(unique, cred) - } - } - return unique -} +// 已移除未使用的 generateCredentials 方法 // performServiceIdentification 执行服务识别(-nobr模式) func (p *ActiveMQPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) { diff --git a/Plugins/services/cassandra/plugin.go b/Plugins/services/cassandra/plugin.go index 718345f..36cb5ca 100644 --- a/Plugins/services/cassandra/plugin.go +++ b/Plugins/services/cassandra/plugin.go @@ -85,30 +85,7 @@ func (p *CassandraPlugin) Scan(ctx context.Context, info *common.HostInfo) (*bas return result, nil } -// generateCredentials 生成Cassandra凭据 -func (p *CassandraPlugin) generateCredentials() []*base.Credential { - // 获取Cassandra专用的用户名字典 - usernames := common.Userdict["cassandra"] - if len(usernames) == 0 { - // 默认Cassandra用户名(包含空用户名用于测试未授权访问) - usernames = []string{"", "cassandra", "admin", "root", "user"} - } - - // 生成凭据组合,包括空密码测试未授权访问 - var credentials []*base.Credential - - // 首先测试未授权访问(空用户名和密码) - credentials = append(credentials, &base.Credential{ - Username: "", - Password: "", - }) - - // 然后生成常规用户名密码组合 - regularCreds := base.GenerateCredentials(usernames, common.Passwords) - credentials = append(credentials, regularCreds...) - - return credentials -} +// 已移除未使用的 generateCredentials 方法 // autoExploit 自动利用功能 func (p *CassandraPlugin) autoExploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) { diff --git a/Plugins/services/ftp/plugin.go b/Plugins/services/ftp/plugin.go index 36adb44..07d65ba 100644 --- a/Plugins/services/ftp/plugin.go +++ b/Plugins/services/ftp/plugin.go @@ -99,17 +99,7 @@ func (p *FTPPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.Scan return result, nil } -// generateCredentials 生成FTP凭据 -func (p *FTPPlugin) generateCredentials() []*base.Credential { - // 获取FTP专用的用户名字典 - usernames := common.Userdict["ftp"] - if len(usernames) == 0 { - // 默认FTP用户名 - usernames = []string{"ftp", "ftpuser", "admin", "test", "user", "guest"} - } - - return base.GenerateCredentials(usernames, common.Passwords) -} +// 已移除未使用的 generateCredentials 方法 // autoExploit 自动利用功能 func (p *FTPPlugin) autoExploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) { diff --git a/Plugins/services/imap/plugin.go b/Plugins/services/imap/plugin.go index 520c9ae..4b39043 100644 --- a/Plugins/services/imap/plugin.go +++ b/Plugins/services/imap/plugin.go @@ -75,17 +75,7 @@ func (p *IMAPPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.Sca return result, nil } -// generateCredentials 重写凭据生成方法 -func (p *IMAPPlugin) generateCredentials() []*base.Credential { - // 获取IMAP专用的用户名字典 - usernames := common.Userdict["imap"] - if len(usernames) == 0 { - // 默认IMAP用户名 - usernames = []string{"admin", "root", "test", "mail", "postmaster", "administrator"} - } - - return base.GenerateCredentials(usernames, common.Passwords) -} +// 已移除未使用的 generateCredentials 方法 // Exploit 使用exploiter执行利用 func (p *IMAPPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { diff --git a/Plugins/services/kafka/plugin.go b/Plugins/services/kafka/plugin.go index 192b83c..bb02360 100644 --- a/Plugins/services/kafka/plugin.go +++ b/Plugins/services/kafka/plugin.go @@ -93,17 +93,7 @@ func (p *KafkaPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.Sc return result, nil } -// generateCredentials 重写凭据生成方法 -func (p *KafkaPlugin) generateCredentials() []*base.Credential { - // 获取Kafka专用的用户名字典 - usernames := common.Userdict["kafka"] - if len(usernames) == 0 { - // 默认Kafka用户名 - usernames = []string{"admin", "kafka", "test", "user", "root"} - } - - return base.GenerateCredentials(usernames, common.Passwords) -} +// 已移除未使用的 generateCredentials 方法 // Exploit 使用exploiter执行利用 func (p *KafkaPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { diff --git a/Plugins/services/ldap/plugin.go b/Plugins/services/ldap/plugin.go index 5846f7a..bd41155 100644 --- a/Plugins/services/ldap/plugin.go +++ b/Plugins/services/ldap/plugin.go @@ -94,17 +94,7 @@ func (p *LDAPPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.Sca return result, nil } -// generateCredentials 重写凭据生成方法 -func (p *LDAPPlugin) generateCredentials() []*base.Credential { - // 获取LDAP专用的用户名字典 - usernames := common.Userdict["ldap"] - if len(usernames) == 0 { - // 默认LDAP用户名 - usernames = []string{"admin", "administrator", "ldap", "root", "manager", "directory", "test", "user"} - } - - return base.GenerateCredentials(usernames, common.Passwords) -} +// 已移除未使用的 generateCredentials 方法 // Exploit 使用exploiter执行利用 func (p *LDAPPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { diff --git a/Plugins/services/memcached/plugin.go b/Plugins/services/memcached/plugin.go index 8873655..be754c5 100644 --- a/Plugins/services/memcached/plugin.go +++ b/Plugins/services/memcached/plugin.go @@ -87,13 +87,7 @@ func (p *MemcachedPlugin) Scan(ctx context.Context, info *common.HostInfo) (*bas }, nil } -// generateCredentials Memcached通常无需凭据,返回空凭据 -func (p *MemcachedPlugin) generateCredentials() []*base.Credential { - // Memcached通常无认证机制,只返回空凭据用于未授权访问检测 - return []*base.Credential{ - {Username: "", Password: ""}, - } -} +// 已移除未使用的 generateCredentials 方法 // Exploit 使用exploiter执行利用 func (p *MemcachedPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { diff --git a/Plugins/services/modbus/plugin.go b/Plugins/services/modbus/plugin.go index 9f5c55c..48560ab 100644 --- a/Plugins/services/modbus/plugin.go +++ b/Plugins/services/modbus/plugin.go @@ -94,13 +94,7 @@ func (p *ModbusPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.S }, nil } -// generateCredentials Modbus通常无需凭据,返回空凭据 -func (p *ModbusPlugin) generateCredentials() []*base.Credential { - // Modbus协议通常无认证机制,只返回空凭据用于协议检测 - return []*base.Credential{ - {Username: "", Password: ""}, - } -} +// 已移除未使用的 generateCredentials 方法 // getDeviceInfo 获取Modbus设备信息 func (p *ModbusPlugin) getDeviceInfo(ctx context.Context, info *common.HostInfo) string { diff --git a/Plugins/services/mongodb/plugin.go b/Plugins/services/mongodb/plugin.go index 1bf63dc..2194814 100644 --- a/Plugins/services/mongodb/plugin.go +++ b/Plugins/services/mongodb/plugin.go @@ -89,33 +89,7 @@ func (p *MongoDBPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base. }, nil } -// generateCredentials MongoDB主要用于未授权访问检测 -func (p *MongoDBPlugin) generateCredentials() []*base.Credential { - // MongoDB主要检查未授权访问,但也可以尝试一些默认凭据 - credentials := []*base.Credential{ - {Username: "", Password: ""}, // 未授权访问 - } - - // 如果有MongoDB专用字典,添加常见凭据 - usernames := common.Userdict["mongodb"] - if len(usernames) == 0 { - usernames = []string{"admin", "root", "mongo", "mongodb"} - } - - // 添加一些常见的MongoDB凭据 - for _, username := range usernames { - credentials = append(credentials, &base.Credential{ - Username: username, - Password: "", // MongoDB常见空密码 - }) - credentials = append(credentials, &base.Credential{ - Username: username, - Password: username, // 用户名等于密码 - }) - } - - return credentials -} +// 已移除未使用的 generateCredentials 方法 // Exploit 使用exploiter执行利用 func (p *MongoDBPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { diff --git a/Plugins/services/mysql/connector.go b/Plugins/services/mysql/connector.go index c721368..0ae38e6 100644 --- a/Plugins/services/mysql/connector.go +++ b/Plugins/services/mysql/connector.go @@ -103,22 +103,7 @@ func (c *MySQLConnector) Close(conn interface{}) error { return nil } -// connectWithCredentials 使用凭据创建新连接 -func (c *MySQLConnector) connectWithCredentials(ctx context.Context, originalDB *sql.DB, cred *base.Credential) (*sql.DB, error) { - // 从原始连接中提取主机和端口信息 - // 这里简化处理,实际应该从原始连接字符串中解析 - // 为了示例,我们假设可以从某种方式获取主机端口信息 - - // 临时解决方案:重新构建连接字符串 - connStr := c.buildConnectionStringWithCredentials(cred) - - db, err := sql.Open("mysql", connStr) - if err != nil { - return nil, fmt.Errorf("创建认证连接失败: %v", err) - } - - return db, nil -} +// 已移除未使用的 connectWithCredentials 方法 // buildConnectionString 构建MySQL连接字符串 // 根据是否配置SOCKS代理选择合适的连接方式 @@ -136,11 +121,7 @@ func (c *MySQLConnector) buildConnectionString(host string, port int, username, } } -// buildConnectionStringWithCredentials 构建带凭据的连接字符串 -func (c *MySQLConnector) buildConnectionStringWithCredentials(cred *base.Credential) string { - // 使用保存的主机和端口信息 - return c.buildConnectionString(c.host, c.port, cred.Username, cred.Password) -} +// 已移除未使用的 buildConnectionStringWithCredentials 方法 // connectDirect 内存优化:直接建立MySQL连接,避免连接池开销 // 用于单次认证场景,减少内存分配和资源浪费 diff --git a/Plugins/services/mysql/plugin.go b/Plugins/services/mysql/plugin.go index 74849b0..8f7f11e 100644 --- a/Plugins/services/mysql/plugin.go +++ b/Plugins/services/mysql/plugin.go @@ -124,17 +124,7 @@ func (p *MySQLPlugin) IsExploitSupported(method base.ExploitType) bool { return p.exploiter.IsExploitSupported(method) } -// generateCredentials 重写凭据生成方法 -func (p *MySQLPlugin) generateCredentials() []*base.Credential { - // 获取MySQL专用的用户名字典 - usernames := common.Userdict["mysql"] - if len(usernames) == 0 { - // 默认MySQL用户名 - usernames = []string{"root", "admin", "mysql"} - } - - return base.GenerateCredentials(usernames, common.Passwords) -} +// 已移除未使用的 generateCredentials 方法 // performServiceIdentification 执行MySQL服务识别(-nobr模式) func (p *MySQLPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) { diff --git a/Plugins/services/redis/exploiter.go b/Plugins/services/redis/exploiter.go index eb368a8..3898933 100644 --- a/Plugins/services/redis/exploiter.go +++ b/Plugins/services/redis/exploiter.go @@ -220,68 +220,9 @@ func (e *RedisExploiter) exploitCrontabInjection(ctx context.Context, info *comm return result, nil } -// exploitDataExtraction 数据提取利用 -func (e *RedisExploiter) exploitDataExtraction(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { - conn, err := e.connectToRedis(ctx, info, creds) - if err != nil { - return base.CreateFailedExploitResult(base.ExploitDataExtraction, "data_extraction", err), nil - } - defer e.connector.Close(conn) - - redisConn := conn.(*RedisConnection) - result := base.CreateSuccessExploitResult(base.ExploitDataExtraction, "data_extraction") - - // 获取所有键 - keys, err := e.getAllKeys(redisConn) - if err == nil && len(keys) > 0 { - base.AddOutputToResult(result, i18n.GetText("redis_keys_found", strings.Join(keys[:min(10, len(keys))], ", "))) - result.Extra["keys"] = keys - - // 获取部分键值 - for i, key := range keys { - if i >= 5 { // 限制只获取前5个键的值 - break - } - value, err := e.getKeyValue(redisConn, key) - if err == nil && value != "" { - base.AddOutputToResult(result, fmt.Sprintf("%s = %s", key, value)) - } - } - } - - return result, nil -} +// 已移除未使用的 exploitDataExtraction 方法 -// exploitInfoGathering 信息收集利用 -func (e *RedisExploiter) exploitInfoGathering(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { - conn, err := e.connectToRedis(ctx, info, creds) - if err != nil { - return base.CreateFailedExploitResult(base.ExploitDataExtraction, "info_gathering", err), nil - } - defer e.connector.Close(conn) - - redisConn := conn.(*RedisConnection) - result := base.CreateSuccessExploitResult(base.ExploitDataExtraction, "info_gathering") - - // 获取Redis信息 - infoResponse, err := e.connector.ExecuteCommand(redisConn, "INFO") - if err == nil { - lines := strings.Split(infoResponse, "\n") - for _, line := range lines { - if strings.Contains(line, "redis_version") || - strings.Contains(line, "os") || - strings.Contains(line, "arch_bits") { - base.AddOutputToResult(result, strings.TrimSpace(line)) - } - } - } - - // 获取配置信息 - base.AddOutputToResult(result, i18n.GetText("redis_config_info", fmt.Sprintf("Dir: %s", redisConn.config.Dir))) - base.AddOutputToResult(result, i18n.GetText("redis_config_info", fmt.Sprintf("DBFilename: %s", redisConn.config.DBFilename))) - - return result, nil -} +// 已移除未使用的 exploitInfoGathering 方法 // ============================================================================= // Redis操作辅助函数 @@ -413,36 +354,8 @@ func (e *RedisExploiter) readFirstNonEmptyLine(filename string) (string, error) return "", fmt.Errorf("文件为空或无内容") } -// getAllKeys 获取所有Redis键 -func (e *RedisExploiter) getAllKeys(conn *RedisConnection) ([]string, error) { - response, err := e.connector.ExecuteCommand(conn, "KEYS *") - if err != nil { - return nil, err - } - - // 简单解析键列表(实际应该按Redis协议解析) - lines := strings.Split(response, "\n") - var keys []string - for _, line := range lines { - line = strings.TrimSpace(line) - if line != "" && !strings.HasPrefix(line, "*") && !strings.HasPrefix(line, "$") { - keys = append(keys, line) - } - } - - return keys, nil -} +// 已移除未使用的 getAllKeys 方法 -// getKeyValue 获取键值 -func (e *RedisExploiter) getKeyValue(conn *RedisConnection, key string) (string, error) { - command := fmt.Sprintf("GET %s", key) - return e.connector.ExecuteCommand(conn, command) -} +// 已移除未使用的 getKeyValue 方法 -// min 返回两个整数中的较小值 -func min(a, b int) int { - if a < b { - return a - } - return b -} \ No newline at end of file +// 已移除未使用的 min 函数 \ No newline at end of file diff --git a/Plugins/services/redis/plugin.go b/Plugins/services/redis/plugin.go index 32f752f..175953e 100644 --- a/Plugins/services/redis/plugin.go +++ b/Plugins/services/redis/plugin.go @@ -164,11 +164,7 @@ func (p *RedisPlugin) IsExploitSupported(method base.ExploitType) bool { return p.exploiter.IsExploitSupported(method) } -// generateCredentials 重写凭据生成方法(Redis只需要密码) -func (p *RedisPlugin) generateCredentials() []*base.Credential { - // Redis通常只需要密码,不需要用户名 - return base.GeneratePasswordOnlyCredentials(common.Passwords) -} +// 已移除未使用的 generateCredentials 方法 // performServiceIdentification 执行Redis服务识别(-nobr模式) func (p *RedisPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) { diff --git a/Plugins/services/ssh/plugin.go b/Plugins/services/ssh/plugin.go index 1f97bd3..fddcd70 100644 --- a/Plugins/services/ssh/plugin.go +++ b/Plugins/services/ssh/plugin.go @@ -207,17 +207,7 @@ func (p *SSHPlugin) scanWithKey(ctx context.Context, info *common.HostInfo) *bas return nil } -// generateCredentials 重写凭据生成方法 -func (p *SSHPlugin) generateCredentials() []*base.Credential { - // 获取SSH专用的用户名字典 - usernames := common.Userdict["ssh"] - if len(usernames) == 0 { - // 默认SSH用户名 - usernames = []string{"root", "admin", "ubuntu", "centos", "user", "test"} - } - - return base.GenerateCredentials(usernames, common.Passwords) -} +// 已移除未使用的 generateCredentials 方法 // Exploit 使用exploiter执行利用 diff --git a/Plugins/services/vnc/connector.go b/Plugins/services/vnc/connector.go deleted file mode 100644 index fedcec7..0000000 --- a/Plugins/services/vnc/connector.go +++ /dev/null @@ -1,111 +0,0 @@ -package vnc - -import ( - "context" - "fmt" - "net" - "time" - - "github.com/mitchellh/go-vnc" - "github.com/shadow1ng/fscan/common" - "github.com/shadow1ng/fscan/common/i18n" - "github.com/shadow1ng/fscan/plugins/base" -) - -// VNCConnector VNC服务连接器 -type VNCConnector struct{} - -// NewVNCConnector 创建新的VNC连接器 -func NewVNCConnector() *VNCConnector { - return &VNCConnector{} -} - -// Connect 连接到VNC服务 -func (c *VNCConnector) Connect(ctx context.Context, info *common.HostInfo) (interface{}, error) { - target := fmt.Sprintf("%s:%s", info.Host, info.Ports) - timeout := time.Duration(common.Timeout) * time.Second - - // 使用带上下文的TCP连接 - conn, err := common.WrapperTcpWithTimeout("tcp", target, timeout) - if err != nil { - return nil, fmt.Errorf(i18n.GetText("vnc_connection_failed"), err) - } - - // 设置读写超时 - if err := conn.SetDeadline(time.Now().Add(timeout)); err != nil { - conn.Close() - return nil, fmt.Errorf("failed to set connection deadline: %v", err) - } - - return conn, nil -} - -// Authenticate 认证VNC服务 -func (c *VNCConnector) Authenticate(ctx context.Context, conn interface{}, cred *base.Credential) error { - netConn, ok := conn.(net.Conn) - if !ok { - return fmt.Errorf("invalid connection type") - } - - // 检查上下文是否已取消 - select { - case <-ctx.Done(): - return ctx.Err() - default: - } - - // VNC只使用密码认证,忽略用户名 - password := cred.Password - if password == "" && cred.Username != "" { - // 如果密码为空但用户名不为空,尝试使用用户名作为密码 - password = cred.Username - } - - // 创建完成通道 - doneChan := make(chan error, 1) - - // 在协程中处理VNC认证 - go func() { - // 配置VNC客户端 - config := &vnc.ClientConfig{ - Auth: []vnc.ClientAuth{ - &vnc.PasswordAuth{ - Password: password, - }, - }, - } - - // 尝试VNC认证 - client, err := vnc.Client(netConn, config) - if err != nil { - select { - case <-ctx.Done(): - case doneChan <- err: - } - return - } - - // 认证成功,立即关闭客户端 - client.Close() - select { - case <-ctx.Done(): - case doneChan <- nil: - } - }() - - // 等待认证结果或上下文取消 - select { - case err := <-doneChan: - return err - case <-ctx.Done(): - return ctx.Err() - } -} - -// Close 关闭连接 -func (c *VNCConnector) Close(conn interface{}) error { - if closer, ok := conn.(interface{ Close() error }); ok && closer != nil { - return closer.Close() - } - return nil -} \ No newline at end of file diff --git a/Plugins/services/vnc/exploiter.go b/Plugins/services/vnc/exploiter.go deleted file mode 100644 index 169ea5e..0000000 --- a/Plugins/services/vnc/exploiter.go +++ /dev/null @@ -1,25 +0,0 @@ -package vnc - -import ( - "context" - - "github.com/shadow1ng/fscan/common" - "github.com/shadow1ng/fscan/plugins/base" -) - -// VNCExploiter VNC服务利用器 -// 遵循新架构设计模式,当前为空实现 -type VNCExploiter struct{} - -// NewVNCExploiter 创建新的VNC利用器 -func NewVNCExploiter() *VNCExploiter { - return &VNCExploiter{} -} - -// Exploit 执行VNC服务利用 -// 当前为空实现,遵循其他插件的一致性设计 -func (e *VNCExploiter) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) { - // 空实现 - 遵循新架构中其他服务插件的模式 - // 主要功能集中在连接器和插件主体中实现 - return nil, nil -} \ No newline at end of file diff --git a/Plugins/services/vnc/plugin.go b/Plugins/services/vnc/plugin.go deleted file mode 100644 index 32e4bcf..0000000 --- a/Plugins/services/vnc/plugin.go +++ /dev/null @@ -1,187 +0,0 @@ -package vnc - -import ( - "context" - "fmt" - - "github.com/shadow1ng/fscan/common" - "github.com/shadow1ng/fscan/common/i18n" - "github.com/shadow1ng/fscan/plugins/base" -) - -// VNCPlugin VNC服务插件 -type VNCPlugin struct { - *base.ServicePlugin - exploiter *VNCExploiter -} - -// NewVNCPlugin 创建VNC插件 -func NewVNCPlugin() *VNCPlugin { - // 插件元数据 - metadata := &base.PluginMetadata{ - Name: "vnc", - Version: "2.0.0", - Author: "fscan-team", - Description: "VNC远程桌面协议服务检测和弱口令扫描", - Category: "service", - Ports: []int{5900, 5901, 5902, 5903}, // VNC常用端口 - Protocols: []string{"tcp"}, - Tags: []string{"vnc", "remote-desktop", "weak-password"}, - } - - // 创建连接器和服务插件 - connector := NewVNCConnector() - servicePlugin := base.NewServicePlugin(metadata, connector) - - // 创建VNC插件 - plugin := &VNCPlugin{ - ServicePlugin: servicePlugin, - exploiter: NewVNCExploiter(), - } - - // 设置能力 - plugin.SetCapabilities([]base.Capability{ - base.CapWeakPassword, - }) - - return plugin -} - -// init 自动注册VNC插件 -func init() { - // 创建插件工厂 - metadata := &base.PluginMetadata{ - Name: "vnc", - Version: "2.0.0", - Author: "fscan-team", - Description: "VNC远程桌面协议服务检测和弱口令扫描", - Category: "service", - Ports: []int{5900, 5901, 5902, 5903}, - Protocols: []string{"tcp"}, - Tags: []string{"vnc", "remote-desktop", "weak-password"}, - } - - factory := base.NewSimplePluginFactory(metadata, func() base.Plugin { - return NewVNCPlugin() - }) - - base.GlobalPluginRegistry.Register("vnc", factory) -} - -// Scan 重写扫描方法,进行VNC服务扫描 -func (p *VNCPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) { - // 如果禁用了暴力破解,只进行服务识别 - if common.DisableBrute { - return p.performServiceIdentification(ctx, info) - } - - target := fmt.Sprintf("%s:%s", info.Host, info.Ports) - - // 生成凭据进行暴力破解 - credentials := p.generateCredentials() - if len(credentials) == 0 { - return &base.ScanResult{ - Success: false, - Error: fmt.Errorf("no credentials available"), - }, nil - } - - // 遍历凭据进行测试 - for _, cred := range credentials { - result, err := p.ScanCredential(ctx, info, cred) - if err == nil && result.Success { - // 认证成功 - common.LogSuccess(i18n.GetText("vnc_weak_password_success", target, cred.Password)) - - return &base.ScanResult{ - Success: true, - Service: "VNC", - Credentials: []*base.Credential{cred}, - Banner: result.Banner, - Extra: map[string]interface{}{ - "service": "VNC", - "port": info.Ports, - "password": cred.Password, - "type": "weak-password", - }, - }, nil - } - } - - // 没有找到有效凭据 - return &base.ScanResult{ - Success: false, - Service: "VNC", - Error: fmt.Errorf("authentication failed for all credentials"), - }, nil -} - -// performServiceIdentification 执行服务识别 -func (p *VNCPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) { - // 尝试连接到服务进行基本识别 - conn, err := p.GetServiceConnector().Connect(ctx, info) - if err != nil { - return &base.ScanResult{ - Success: false, - Error: err, - }, nil - } - defer p.GetServiceConnector().Close(conn) - - // 服务识别成功 - return &base.ScanResult{ - Success: true, - Service: "VNC", - Banner: "VNC service detected", - Extra: map[string]interface{}{ - "service": "VNC", - "port": info.Ports, - "type": "service-identification", - }, - }, nil -} - -// generateCredentials 生成VNC认证凭据 -func (p *VNCPlugin) generateCredentials() []*base.Credential { - var credentials []*base.Credential - - // VNC只使用密码认证,不需要用户名 - passwords := common.Passwords - if len(passwords) == 0 { - // 使用默认VNC密码 - passwords = []string{"", "123456", "password", "vnc", "admin", "root", "888888", "123123"} - } - - // 生成密码凭据(VNC不使用用户名) - for _, password := range passwords { - credentials = append(credentials, &base.Credential{ - Username: "", // VNC不需要用户名 - Password: password, - }) - } - - // 额外尝试常见的VNC密码组合 - commonVNCPasswords := []string{ - "vnc", "password", "123456", "admin", "root", "guest", - "1234", "12345", "qwerty", "abc123", "888888", "000000", - } - - for _, password := range commonVNCPasswords { - // 避免重复添加 - found := false - for _, existing := range credentials { - if existing.Password == password { - found = true - break - } - } - if !found { - credentials = append(credentials, &base.Credential{ - Username: "", - Password: password, - }) - } - } - - return credentials -} \ No newline at end of file