fscan/Plugins/services/pop3/plugin.go
ZacharyZcR 532daf16ed feat: POP3邮件服务插件迁移到新架构完成
- 实现POP3协议连接器,支持普通和TLS连接(端口110/995)
- 支持弱密码检测和邮件服务识别功能
- 简化实现,不提供利用功能,专注于安全扫描
- 集成国际化消息系统
- 测试通过:服务识别和弱密码检测功能
2025-08-09 13:16:47 +08:00

210 lines
5.5 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 pop3
import (
"context"
"fmt"
"strings"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/common/i18n"
"github.com/shadow1ng/fscan/plugins/base"
)
// POP3Plugin POP3插件实现
type POP3Plugin struct {
*base.ServicePlugin
exploiter *POP3Exploiter
}
// NewPOP3Plugin 创建POP3插件
func NewPOP3Plugin() *POP3Plugin {
// 插件元数据
metadata := &base.PluginMetadata{
Name: "pop3",
Version: "2.0.0",
Author: "fscan-team",
Description: "POP3邮件服务扫描和利用插件",
Category: "service",
Ports: []int{110, 995}, // POP3常用端口
Protocols: []string{"tcp"},
Tags: []string{"pop3", "email", "weak-password", "tls"},
}
// 创建连接器和服务插件
connector := NewPOP3Connector()
servicePlugin := base.NewServicePlugin(metadata, connector)
// 创建POP3插件
plugin := &POP3Plugin{
ServicePlugin: servicePlugin,
exploiter: NewPOP3Exploiter(),
}
// 设置能力
plugin.SetCapabilities([]base.Capability{
base.CapWeakPassword,
})
return plugin
}
// Scan 重写扫描方法进行POP3服务扫描
func (p *POP3Plugin) 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()
// 遍历凭据进行测试
for _, cred := range credentials {
result, err := p.ScanCredential(ctx, info, cred)
if err == nil && result.Success {
// 认证成功
tlsStatus := ""
if result.Extra["tls"] == true {
tlsStatus = " (TLS)"
}
common.LogSuccess(i18n.GetText("pop3_weak_pwd_success", target, cred.Username, cred.Password) + tlsStatus)
return &base.ScanResult{
Success: true,
Service: "POP3",
Credentials: []*base.Credential{cred},
Banner: result.Banner,
Extra: map[string]interface{}{
"service": "POP3",
"port": info.Ports,
"username": cred.Username,
"password": cred.Password,
"type": "weak-password",
"tls": result.Extra["tls"],
},
}, nil
}
}
// 所有凭据都失败但可能识别到了POP3服务
return p.performServiceIdentification(ctx, info)
}
// generateCredentials 生成POP3凭据
func (p *POP3Plugin) generateCredentials() []*base.Credential {
var credentials []*base.Credential
// 获取POP3用户名字典
usernames := common.Userdict["pop3"]
if len(usernames) == 0 {
usernames = []string{"admin", "root", "test", "mail", "postmaster", "user"}
}
// 获取密码字典
passwords := common.Passwords
if len(passwords) == 0 {
passwords = []string{"", "admin", "password", "123456", "admin123", "test123", "root123"}
}
// 生成用户名密码组合
for _, username := range usernames {
for _, password := range passwords {
// 替换密码中的用户名占位符
actualPassword := strings.Replace(password, "{user}", username, -1)
credentials = append(credentials, &base.Credential{
Username: username,
Password: actualPassword,
})
}
}
return credentials
}
// Exploit 使用exploiter执行利用
func (p *POP3Plugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) {
return p.exploiter.Exploit(ctx, info, creds)
}
// GetExploitMethods 获取利用方法
func (p *POP3Plugin) GetExploitMethods() []base.ExploitMethod {
return p.exploiter.GetExploitMethods()
}
// IsExploitSupported 检查利用支持
func (p *POP3Plugin) IsExploitSupported(method base.ExploitType) bool {
return p.exploiter.IsExploitSupported(method)
}
// performServiceIdentification 执行POP3服务识别-nobr模式
func (p *POP3Plugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
// 尝试识别POP3服务
connector := NewPOP3Connector()
conn, err := connector.Connect(ctx, info)
if err == nil && conn != nil {
if pop3Conn, ok := conn.(*POP3Connection); ok {
// 记录服务识别成功
tlsStatus := ""
if pop3Conn.isTLS {
tlsStatus = " (TLS)"
}
common.LogSuccess(i18n.GetText("pop3_service_identified", target, pop3Conn.banner) + tlsStatus)
connector.Close(conn)
return &base.ScanResult{
Success: true,
Service: "POP3",
Banner: pop3Conn.banner,
Extra: map[string]interface{}{
"service": "POP3",
"port": info.Ports,
"banner": pop3Conn.banner,
"tls": pop3Conn.isTLS,
},
}, nil
}
}
// 如果无法识别为POP3返回失败
return &base.ScanResult{
Success: false,
Error: fmt.Errorf("无法识别为POP3服务"),
}, nil
}
// =============================================================================
// 插件注册
// =============================================================================
// RegisterPOP3Plugin 注册POP3插件
func RegisterPOP3Plugin() {
factory := base.NewSimplePluginFactory(
&base.PluginMetadata{
Name: "pop3",
Version: "2.0.0",
Author: "fscan-team",
Description: "POP3邮件服务扫描和利用插件",
Category: "service",
Ports: []int{110, 995}, // POP3常用端口
Protocols: []string{"tcp"},
Tags: []string{"pop3", "email", "weak-password", "tls"},
},
func() base.Plugin {
return NewPOP3Plugin()
},
)
base.GlobalPluginRegistry.Register("pop3", factory)
}
// 自动注册
func init() {
RegisterPOP3Plugin()
}