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

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

258 lines
7.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 cassandra
import (
"context"
"fmt"
"net"
"strings"
"time"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/common/i18n"
"github.com/shadow1ng/fscan/plugins/base"
)
// CassandraPlugin Cassandra插件实现
type CassandraPlugin struct {
*base.ServicePlugin
exploiter *CassandraExploiter
}
// NewCassandraPlugin 创建Cassandra插件
func NewCassandraPlugin() *CassandraPlugin {
// 插件元数据
metadata := &base.PluginMetadata{
Name: "cassandra",
Version: "2.0.0",
Author: "fscan-team",
Description: "Apache Cassandra服务扫描和利用插件",
Category: "service",
Ports: []int{9042}, // Cassandra Native Protocol
Protocols: []string{"tcp"},
Tags: []string{"cassandra", "nosql", "database", "bruteforce"},
}
// 创建连接器和服务插件
connector := NewCassandraConnector()
servicePlugin := base.NewServicePlugin(metadata, connector)
// 创建Cassandra插件
plugin := &CassandraPlugin{
ServicePlugin: servicePlugin,
exploiter: NewCassandraExploiter(),
}
// 设置能力
plugin.SetCapabilities([]base.Capability{
base.CapWeakPassword,
base.CapDataExtraction,
base.CapInformationLeak,
})
return plugin
}
// Scan 重写扫描方法以支持自动利用
func (p *CassandraPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
// 如果禁用暴力破解,只进行服务识别
if common.DisableBrute {
return p.performServiceIdentification(ctx, info)
}
// 执行基础的密码扫描
result, err := p.ServicePlugin.Scan(ctx, info)
if err != nil || !result.Success {
return result, err
}
// 记录成功的弱密码/未授权访问发现
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
cred := result.Credentials[0]
if cred.Username == "" && cred.Password == "" {
// 未授权访问
common.LogSuccess(i18n.GetText("plugin_unauthorized_access", "Cassandra", target))
} else {
// 弱密码
common.LogSuccess(i18n.GetText("plugin_login_success", "Cassandra", target, cred.Username, cred.Password))
}
// 自动利用功能(可通过-ne参数禁用
if result.Success && len(result.Credentials) > 0 && !common.DisableExploit {
p.autoExploit(context.Background(), info, result.Credentials[0])
}
return result, nil
}
// 已移除未使用的 generateCredentials 方法
// autoExploit 自动利用功能
func (p *CassandraPlugin) autoExploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
common.LogDebug(i18n.GetText("plugin_exploit_start", "Cassandra", target))
// 执行利用操作
result, err := p.exploiter.Exploit(ctx, info, creds)
if err != nil {
common.LogError(i18n.GetText("plugin_exploit_failed", "Cassandra", err))
return
}
// 处理利用结果
if result != nil && result.Success {
// SaveExploitResult会自动使用LogSuccess显示红色利用成功消息
base.SaveExploitResult(info, result, "Cassandra")
}
}
// Exploit 使用exploiter执行利用
func (p *CassandraPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) {
return p.exploiter.Exploit(ctx, info, creds)
}
// GetExploitMethods 获取利用方法
func (p *CassandraPlugin) GetExploitMethods() []base.ExploitMethod {
return p.exploiter.GetExploitMethods()
}
// IsExploitSupported 检查利用支持
func (p *CassandraPlugin) IsExploitSupported(method base.ExploitType) bool {
return p.exploiter.IsExploitSupported(method)
}
// performServiceIdentification 执行Cassandra服务识别-nobr模式
func (p *CassandraPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
// 尝试连接到Cassandra服务进行识别
cassandraInfo, isCassandra := p.identifyCassandraService(ctx, info)
if isCassandra {
// 记录服务识别成功
common.LogSuccess(i18n.GetText("cassandra_service_identified", target, cassandraInfo))
return &base.ScanResult{
Success: true,
Service: "Cassandra",
Banner: cassandraInfo,
Extra: map[string]interface{}{
"service": "Cassandra",
"port": info.Ports,
"info": cassandraInfo,
},
}, nil
}
// 如果无法识别为Cassandra返回失败
return &base.ScanResult{
Success: false,
Error: fmt.Errorf("无法识别为Cassandra服务"),
}, nil
}
// identifyCassandraService 通过连接识别Cassandra服务
func (p *CassandraPlugin) identifyCassandraService(ctx context.Context, info *common.HostInfo) (string, bool) {
// 尝试建立简单的TCP连接
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
conn, err := common.WrapperTcpWithTimeout("tcp", target, time.Duration(common.Timeout)*time.Second)
if err != nil {
return "", false
}
defer conn.Close()
// 对于Cassandra native protocol (9042)尝试发送OPTIONS frame
if info.Ports == "9042" {
return p.identifyNativeProtocol(conn)
}
// 通用端口检测(其他端口)
return p.identifyGenericCassandra(conn)
}
// identifyNativeProtocol 识别Cassandra native protocol
func (p *CassandraPlugin) identifyNativeProtocol(conn net.Conn) (string, bool) {
// 设置读写超时
conn.SetDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
// Cassandra native protocol OPTIONS frame
// Frame format: version(1) + flags(1) + stream(2) + opcode(1) + length(4) + body
optionsFrame := []byte{
0x04, // Version 4
0x00, // Flags
0x00, 0x00, // Stream ID
0x05, // Opcode: OPTIONS
0x00, 0x00, 0x00, 0x00, // Body length: 0
}
// 发送OPTIONS请求
_, err := conn.Write(optionsFrame)
if err != nil {
return "", false
}
// 读取响应
response := make([]byte, 1024)
n, err := conn.Read(response)
if err != nil || n < 8 {
return "", false
}
// 检查响应是否为有效的Cassandra协议响应
if n >= 8 && response[0] == 0x84 { // Response version
// 简单解析响应以获取支持的版本信息
return "Cassandra Native Protocol v4", true
}
return "", false
}
// identifyGenericCassandra 通用Cassandra识别
func (p *CassandraPlugin) identifyGenericCassandra(conn net.Conn) (string, bool) {
// 设置超时
conn.SetDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
// 尝试读取任何初始数据
response := make([]byte, 512)
n, err := conn.Read(response)
if err == nil && n > 0 {
responseStr := string(response[:n])
// 检查响应中是否包含Cassandra相关信息
if strings.Contains(strings.ToLower(responseStr), "cassandra") {
return fmt.Sprintf("Cassandra服务: %s", strings.TrimSpace(responseStr)), true
}
}
// 如果端口开放但没有明确标识仍然认为可能是Cassandra
return "Cassandra服务", true
}
// =============================================================================
// 插件注册
// =============================================================================
// RegisterCassandraPlugin 注册Cassandra插件
func RegisterCassandraPlugin() {
factory := base.NewSimplePluginFactory(
&base.PluginMetadata{
Name: "cassandra",
Version: "2.0.0",
Author: "fscan-team",
Description: "Apache Cassandra服务扫描和利用插件",
Category: "service",
Ports: []int{9042}, // Cassandra Native Protocol
Protocols: []string{"tcp"},
Tags: []string{"cassandra", "nosql", "database", "bruteforce"},
},
func() base.Plugin {
return NewCassandraPlugin()
},
)
base.GlobalPluginRegistry.Register("cassandra", factory)
}
// 自动注册
func init() {
RegisterCassandraPlugin()
}