fscan/plugins/services/imap/plugin.go
ZacharyZcR 4a3f281b6b refactor: 统一Plugins目录大小写为小写
- 将所有Plugins路径重命名为plugins
- 修复Git索引与实际文件系统大小写不一致问题
- 确保跨平台兼容性和路径一致性
2025-08-12 13:08:06 +08:00

214 lines
5.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 imap
import (
"context"
"crypto/tls"
"fmt"
"net"
"regexp"
"strings"
"time"
"github.com/shadow1ng/fscan/common"
"github.com/shadow1ng/fscan/common/i18n"
"github.com/shadow1ng/fscan/plugins/base"
)
// IMAPPlugin IMAP插件实现
type IMAPPlugin struct {
*base.ServicePlugin
exploiter *IMAPExploiter
}
// NewIMAPPlugin 创建IMAP插件
func NewIMAPPlugin() *IMAPPlugin {
// 插件元数据
metadata := &base.PluginMetadata{
Name: "imap",
Version: "2.0.0",
Author: "fscan-team",
Description: "IMAP邮件服务扫描和利用插件",
Category: "service",
Ports: []int{143, 993}, // IMAP和IMAPS端口
Protocols: []string{"tcp"},
Tags: []string{"imap", "mail", "bruteforce"},
}
// 创建连接器和服务插件
connector := NewIMAPConnector()
servicePlugin := base.NewServicePlugin(metadata, connector)
// 创建IMAP插件
plugin := &IMAPPlugin{
ServicePlugin: servicePlugin,
exploiter: NewIMAPExploiter(),
}
// 设置能力
plugin.SetCapabilities([]base.Capability{
base.CapWeakPassword,
base.CapDataExtraction,
})
return plugin
}
// Scan 重写扫描方法以支持服务识别
func (p *IMAPPlugin) 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]
common.LogSuccess(i18n.GetText("imap_weak_pwd_success", target, cred.Username, cred.Password))
return result, nil
}
// 已移除未使用的 generateCredentials 方法
// Exploit 使用exploiter执行利用
func (p *IMAPPlugin) Exploit(ctx context.Context, info *common.HostInfo, creds *base.Credential) (*base.ExploitResult, error) {
return p.exploiter.Exploit(ctx, info, creds)
}
// GetExploitMethods 获取利用方法
func (p *IMAPPlugin) GetExploitMethods() []base.ExploitMethod {
return p.exploiter.GetExploitMethods()
}
// IsExploitSupported 检查利用支持
func (p *IMAPPlugin) IsExploitSupported(method base.ExploitType) bool {
return p.exploiter.IsExploitSupported(method)
}
// performServiceIdentification 执行IMAP服务识别-nobr模式
func (p *IMAPPlugin) performServiceIdentification(ctx context.Context, info *common.HostInfo) (*base.ScanResult, error) {
target := fmt.Sprintf("%s:%s", info.Host, info.Ports)
// 根据端口选择连接类型
var conn net.Conn
var err error
if info.Ports == "993" {
// IMAPS端口使用TLS连接
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
}
conn, err = common.WrapperTlsWithContext(ctx, "tcp", target, tlsConfig)
} else {
// IMAP端口使用普通连接
conn, err = common.WrapperTcpWithContext(ctx, "tcp", target)
}
if err != nil {
return &base.ScanResult{
Success: false,
Error: err,
}, nil
}
defer conn.Close()
// 读取IMAP Banner
imapInfo, isIMAP := p.identifyIMAPService(conn)
if isIMAP {
// 记录服务识别成功
service := "IMAP"
if info.Ports == "993" {
service = "IMAPS"
}
common.LogSuccess(i18n.GetText("imap_service_identified", target, imapInfo))
return &base.ScanResult{
Success: true,
Service: service,
Banner: imapInfo,
Extra: map[string]interface{}{
"service": service,
"port": info.Ports,
"info": imapInfo,
},
}, nil
}
// 如果无法识别为IMAP返回失败
return &base.ScanResult{
Success: false,
Error: fmt.Errorf("无法识别为IMAP服务"),
}, nil
}
// identifyIMAPService 通过Banner识别IMAP服务
func (p *IMAPPlugin) identifyIMAPService(conn net.Conn) (string, bool) {
// 设置读取超时
conn.SetReadDeadline(time.Now().Add(time.Duration(common.Timeout) * time.Second))
// IMAP服务器在连接后会发送欢迎消息
banner := make([]byte, 512)
n, err := conn.Read(banner)
if err != nil || n < 4 {
return "", false
}
bannerStr := strings.TrimSpace(string(banner[:n]))
// 检查IMAP协议标识
if strings.Contains(bannerStr, "* OK") && (strings.Contains(strings.ToLower(bannerStr), "imap") ||
strings.Contains(strings.ToLower(bannerStr), "dovecot") ||
strings.Contains(strings.ToLower(bannerStr), "courier") ||
strings.Contains(strings.ToLower(bannerStr), "cyrus")) {
// 提取服务器信息
if matched := regexp.MustCompile(`\* OK (.+?) ready`).FindStringSubmatch(bannerStr); len(matched) >= 2 {
return fmt.Sprintf("IMAP服务: %s", matched[1]), true
}
if matched := regexp.MustCompile(`\* OK (.+?)$`).FindStringSubmatch(bannerStr); len(matched) >= 2 {
return fmt.Sprintf("IMAP服务: %s", matched[1]), true
}
return fmt.Sprintf("IMAP服务: %s", bannerStr), true
}
return "", false
}
// =============================================================================
// 插件注册
// =============================================================================
// RegisterIMAPPlugin 注册IMAP插件
func RegisterIMAPPlugin() {
factory := base.NewSimplePluginFactory(
&base.PluginMetadata{
Name: "imap",
Version: "2.0.0",
Author: "fscan-team",
Description: "IMAP邮件服务扫描和利用插件",
Category: "service",
Ports: []int{143, 993}, // IMAP和IMAPS端口
Protocols: []string{"tcp"},
Tags: []string{"imap", "mail", "bruteforce"},
},
func() base.Plugin {
return NewIMAPPlugin()
},
)
base.GlobalPluginRegistry.Register("imap", factory)
}
// 自动注册
func init() {
RegisterIMAPPlugin()
}