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

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

314 lines
9.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 activemq
import (
"context"
"fmt"
"net"
"strings"
"time"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/common/i18n"
"github.com/shadow1ng/fscan/plugins/base"
)
// ActiveMQ插件基于新一代插件架构的完整实现
// 支持STOMP协议的弱密码检测、信息收集、队列管理等功能
// 展示了消息队列服务插件的标准实现模式
// ActiveMQPlugin ActiveMQ消息队列扫描和利用插件
// 集成了弱密码检测、自动利用、信息收集等完整功能
type ActiveMQPlugin struct {
*base.ServicePlugin // 继承基础服务插件功能
exploiter *ActiveMQExploiter // ActiveMQ专用利用模块
}
// NewActiveMQPlugin 创建新的ActiveMQ插件实例
// 这是标准的插件工厂函数,展示了新架构的完整初始化流程
func NewActiveMQPlugin() *ActiveMQPlugin {
// 定义插件元数据 - 这些信息用于插件注册和管理
metadata := &base.PluginMetadata{
Name: "activemq", // 插件唯一标识符
Version: "2.0.0", // 插件版本(新架构版本)
Author: "fscan-team", // 开发团队
Description: "ActiveMQ消息队列扫描和利用插件", // 功能描述
Category: "service", // 插件类别
Ports: []int{61613, 61614}, // ActiveMQ STOMP端口标准端口, SSL端口
Protocols: []string{"tcp", "stomp"}, // 支持的协议
Tags: []string{"message-queue", "activemq", "stomp", "bruteforce", "exploit"}, // 功能标签
}
// 创建ActiveMQ专用连接器
connector := NewActiveMQConnector()
// 基于连接器创建基础服务插件
servicePlugin := base.NewServicePlugin(metadata, connector)
// 组装完整的ActiveMQ插件
plugin := &ActiveMQPlugin{
ServicePlugin: servicePlugin,
exploiter: NewActiveMQExploiter(), // 集成利用模块
}
// 声明插件具备的安全测试能力
plugin.SetCapabilities([]base.Capability{
base.CapWeakPassword, // 弱密码检测
base.CapDataExtraction, // 数据提取
base.CapInformationLeak, // 信息泄露
base.CapPrivilegeEsc, // 权限提升
})
return plugin
}
// Scan 执行ActiveMQ服务的完整安全扫描
// 重写基础扫描方法,集成弱密码检测和自动利用功能
func (p *ActiveMQPlugin) Scan(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
// 如果禁用暴力破解,则进行基础服务识别
if common.DisableBrute {
return p.performServiceIdentification(ctx, info)
}
// 调用基础服务插件进行弱密码扫描
result, err := p.ServicePlugin.Scan(ctx, info)
if err != nil || !result.Success {
return result, err // 扫描失败,直接返回
}
// 记录成功的弱密码发现使用i18n根据端口显示不同协议
cred := result.Credentials[0]
// 专注于STOMP协议的成功消息
common.LogSuccess(i18n.GetText("activemq_stomp_scan_success", 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
}
// autoExploit 自动利用
func (p *ActiveMQPlugin) 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", "ActiveMQ", target))
// 执行利用
result, err := p.exploiter.Exploit(ctx, info, creds)
if err != nil {
common.LogDebug(i18n.GetText("plugin_exploit_failed", "ActiveMQ", err))
return
}
if result != nil && result.Success {
// 使用利用结果中的Method字段作为方法名称
methodName := result.Method
if methodName == "" {
methodName = p.getExploitMethodName(result.Type)
}
// 只显示一次完整的利用结果
if result.Output != "" {
common.LogSuccess(fmt.Sprintf("ActiveMQ %s %s 利用成功 输出: %s", target, methodName, result.Output))
} else {
common.LogSuccess(fmt.Sprintf("ActiveMQ %s %s 利用成功", target, methodName))
}
// 保存利用结果(不显示额外日志)
// base.SaveExploitResult(info, result, "ActiveMQ")
}
}
// getExploitMethodName 获取利用方法的中文名称
func (p *ActiveMQPlugin) getExploitMethodName(method base.ExploitType) string {
switch method {
case base.ExploitDataExtraction:
return i18n.GetText("exploit_method_name_data_extraction")
case base.ExploitPrivilegeEsc:
return i18n.GetText("exploit_method_name_activemq_queue_mgmt")
default:
return "未知利用"
}
}
// Exploit 手动利用接口
func (p *ActiveMQPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) {
return p.exploiter.Exploit(ctx, info, creds)
}
// GetExploitMethods 获取利用方法
func (p *ActiveMQPlugin) GetExploitMethods() []base.ExploitMethod {
return p.exploiter.GetExploitMethods()
}
// IsExploitSupported 检查利用支持
func (p *ActiveMQPlugin) IsExploitSupported(method base.ExploitType) bool {
return p.exploiter.IsExploitSupported(method)
}
// 已移除未使用的 generateCredentials 方法
// performServiceIdentification 执行服务识别(-nobr模式
func (p *ActiveMQPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
// 尝试连接到ActiveMQ服务进行基础识别
conn, err := common.WrapperTcpWithTimeout("tcp", target, time.Duration(common.Timeout)*time.Second)
if err != nil {
return &base.ScanResult{
Success: false,
Error: err,
}, nil
}
defer conn.Close()
// 尝试STOMP协议识别
stompInfo, isActiveMQ := p.identifySTOMPService(conn)
if isActiveMQ {
// 记录服务识别成功
common.LogSuccess(i18n.GetText("activemq_service_identified", target, "STOMP", stompInfo))
return &base.ScanResult{
Success: true,
Service: "ActiveMQ",
Banner: stompInfo,
Extra: map[string]interface{}{
"service": "ActiveMQ",
"protocol": "STOMP",
"port": info.Ports,
"info": stompInfo,
},
}, nil
}
// 如果无法识别为ActiveMQ返回一般服务信息
return &base.ScanResult{
Success: false,
Error: fmt.Errorf("无法识别为ActiveMQ服务"),
}, nil
}
// identifySTOMPService 识别STOMP协议服务
func (p *ActiveMQPlugin) identifySTOMPService(conn net.Conn) (string, bool) {
// 发送STOMP CONNECT帧进行协议识别不提供凭据
connectFrame := "CONNECT\naccept-version:1.0,1.1,1.2\nhost:localhost\n\n\x00"
conn.SetWriteDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
if _, err := conn.Write([]byte(connectFrame)); err != nil {
return "", false
}
// 读取响应
conn.SetReadDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
response := make([]byte, 1024)
n, err := conn.Read(response)
if err != nil {
return "", false
}
responseStr := string(response[:n])
// 检查是否为STOMP协议响应
if strings.Contains(responseStr, "CONNECTED") {
// 提取版本信息
version := "unknown"
if strings.Contains(responseStr, "version:") {
lines := strings.Split(responseStr, "\n")
for _, line := range lines {
if strings.HasPrefix(line, "version:") {
version = strings.TrimPrefix(line, "version:")
break
}
}
}
return fmt.Sprintf("STOMP协议版本: %s", version), true
} else if strings.Contains(responseStr, "ERROR") {
// 即使返回错误但能识别STOMP协议格式
return "STOMP协议需要认证", true
}
return "", false
}
// GetServiceName 获取服务名称
func (p *ActiveMQPlugin) GetServiceName() string {
return "ActiveMQ"
}
// GetServiceDescription 获取服务描述
func (p *ActiveMQPlugin) GetServiceDescription() string {
return "Apache ActiveMQ消息队列中间件"
}
// GetDefaultPorts 获取默认端口
func (p *ActiveMQPlugin) GetDefaultPorts() []int {
return []int{61613, 61614}
}
// SupportsBruteforce 支持暴力破解
func (p *ActiveMQPlugin) SupportsBruteforce() bool {
return true
}
// SupportsExploit 支持利用
func (p *ActiveMQPlugin) SupportsExploit() bool {
return true
}
// GetProtocols 获取支持的协议
func (p *ActiveMQPlugin) GetProtocols() []string {
return []string{"tcp", "stomp"}
}
// ValidateTarget 验证目标是否适用
func (p *ActiveMQPlugin) ValidateTarget(info *common.HostInfo) error {
// 基本验证
if info.Host == "" {
return fmt.Errorf("主机地址不能为空")
}
if info.Ports == "" {
return fmt.Errorf("端口不能为空")
}
return nil
}
// =============================================================================
// 插件注册
// =============================================================================
// RegisterActiveMQPlugin 注册ActiveMQ插件
func RegisterActiveMQPlugin() {
factory := base.NewSimplePluginFactory(
&base.PluginMetadata{
Name: "activemq",
Version: "2.0.0",
Author: "fscan-team",
Description: "ActiveMQ消息队列扫描和利用插件",
Category: "service",
Ports: []int{61613, 61614},
Protocols: []string{"tcp", "stomp"},
Tags: []string{"message-queue", "activemq", "stomp", "bruteforce", "exploit"},
},
func() base.Plugin {
return NewActiveMQPlugin()
},
)
// 注册到全局插件注册表
base.GlobalPluginRegistry.Register("activemq", factory)
// 记录注册信息
common.LogDebug("ActiveMQ插件已注册")
}
// 自动注册
func init() {
RegisterActiveMQPlugin()
}