fscan/Plugins/services/memcached/plugin.go
ZacharyZcR f097d2812a refactor: 清理项目死代码和未使用函数
- 移除所有未使用的generateCredentials方法
- 删除插件适配器中的过时函数
- 清理MySQL连接器中的无用方法
- 移除Redis利用器中的未调用函数
- 删除遗留加密函数和基础扫描器无用方法
- 完全移除未注册的VNC插件
- 优化代码结构,提升项目可维护性

清理统计: 移除25+个死代码函数,减少400+行无用代码
2025-08-12 11:51:36 +08:00

223 lines
6.0 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 memcached
import (
"context"
"fmt"
"net"
"strings"
"time"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/common/i18n"
"github.com/shadow1ng/fscan/plugins/base"
)
// MemcachedPlugin Memcached插件实现
type MemcachedPlugin struct {
*base.ServicePlugin
exploiter *MemcachedExploiter
}
// NewMemcachedPlugin 创建Memcached插件
func NewMemcachedPlugin() *MemcachedPlugin {
// 插件元数据
metadata := &base.PluginMetadata{
Name: "memcached",
Version: "2.0.0",
Author: "fscan-team",
Description: "Memcached分布式内存缓存系统扫描和利用插件",
Category: "service",
Ports: []int{11211}, // 默认Memcached端口
Protocols: []string{"tcp"},
Tags: []string{"memcached", "cache", "unauthorized"},
}
// 创建连接器和服务插件
connector := NewMemcachedConnector()
servicePlugin := base.NewServicePlugin(metadata, connector)
// 创建Memcached插件
plugin := &MemcachedPlugin{
ServicePlugin: servicePlugin,
exploiter: NewMemcachedExploiter(),
}
// 设置能力
plugin.SetCapabilities([]base.Capability{
base.CapUnauthorized,
base.CapDataExtraction,
})
return plugin
}
// Scan 重写扫描方法,检测未授权访问
func (p *MemcachedPlugin) 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)
// Memcached通常无认证直接检查未授权访问
unauthCred := &base.Credential{Username: "", Password: ""}
result, err := p.ScanCredential(ctx, info, unauthCred)
if err == nil && result.Success {
// 未授权访问成功
common.LogSuccess(i18n.GetText("memcached_unauth_access", target))
return &base.ScanResult{
Success: true,
Service: "Memcached",
Credentials: []*base.Credential{unauthCred},
Extra: map[string]interface{}{
"service": "Memcached",
"port": info.Ports,
"unauthorized": true,
"access_type": "no_authentication",
},
}, nil
}
// 如果未授权访问失败,返回失败结果
return &base.ScanResult{
Success: false,
Error: fmt.Errorf("Memcached服务不可访问或需要认证"),
}, nil
}
// 已移除未使用的 generateCredentials 方法
// Exploit 使用exploiter执行利用
func (p *MemcachedPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) {
return p.exploiter.Exploit(ctx, info, creds)
}
// GetExploitMethods 获取利用方法
func (p *MemcachedPlugin) GetExploitMethods() []base.ExploitMethod {
return p.exploiter.GetExploitMethods()
}
// IsExploitSupported 检查利用支持
func (p *MemcachedPlugin) IsExploitSupported(method base.ExploitType) bool {
return p.exploiter.IsExploitSupported(method)
}
// performServiceIdentification 执行Memcached服务识别-nobr模式
func (p *MemcachedPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
// 尝试连接Memcached服务获取基本信息
memcachedInfo, isMemcached := p.identifyMemcachedService(ctx, info)
if isMemcached {
// 记录服务识别成功
common.LogSuccess(i18n.GetText("memcached_service_identified", target, memcachedInfo))
return &base.ScanResult{
Success: true,
Service: "Memcached",
Banner: memcachedInfo,
Extra: map[string]interface{}{
"service": "Memcached",
"port": info.Ports,
"info": memcachedInfo,
},
}, nil
}
// 如果无法识别为Memcached返回失败
return &base.ScanResult{
Success: false,
Error: fmt.Errorf("无法识别为Memcached服务"),
}, nil
}
// identifyMemcachedService 通过连接识别Memcached服务
func (p *MemcachedPlugin) identifyMemcachedService(ctx context.Context, info *common.HostInfo) (string, bool) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
timeout := time.Duration(common.Timeout) * time.Second
// 尝试建立TCP连接
conn, err := net.DialTimeout("tcp", target, timeout)
if err != nil {
return "", false
}
defer conn.Close()
// 设置操作超时
conn.SetDeadline(time.Now().Add(timeout))
// 发送version命令获取版本信息
if _, err := conn.Write([]byte("version\n")); err != nil {
return "", false
}
// 读取响应
buffer := make([]byte, 512)
n, err := conn.Read(buffer)
if err != nil {
return "", false
}
response := strings.TrimSpace(string(buffer[:n]))
// 检查是否是Memcached版本响应
if strings.HasPrefix(response, "VERSION") {
// 提取版本信息
parts := strings.Fields(response)
if len(parts) >= 2 {
return fmt.Sprintf("Memcached %s", parts[1]), true
}
return "Memcached服务", true
}
// 尝试stats命令进行二次确认
if _, err := conn.Write([]byte("stats\n")); err != nil {
return "", false
}
n, err = conn.Read(buffer)
if err != nil {
return "", false
}
response = string(buffer[:n])
// 检查是否包含STAT关键字
if strings.Contains(response, "STAT") {
return "Memcached服务", true
}
return "", false
}
// =============================================================================
// 插件注册
// =============================================================================
// RegisterMemcachedPlugin 注册Memcached插件
func RegisterMemcachedPlugin() {
factory := base.NewSimplePluginFactory(
&base.PluginMetadata{
Name: "memcached",
Version: "2.0.0",
Author: "fscan-team",
Description: "Memcached分布式内存缓存系统扫描和利用插件",
Category: "service",
Ports: []int{11211}, // 默认Memcached端口
Protocols: []string{"tcp"},
Tags: []string{"memcached", "cache", "unauthorized"},
},
func() base.Plugin {
return NewMemcachedPlugin()
},
)
base.GlobalPluginRegistry.Register("memcached", factory)
}
// 自动注册
func init() {
RegisterMemcachedPlugin()
}