fscan/Plugins/services/imap/plugin.go
ZacharyZcR 0808461026 feat: 实现IMAP邮件服务专业扫描插件
- 新增IMAP/IMAPS插件支持143和993端口扫描
- 实现TLS/SSL加密连接支持
- 添加IMAP协议专用超时机制(默认超时+5秒)
- 支持弱密码暴力破解和服务识别功能
- 完善IMAP相关国际化消息支持
- 兼容新插件架构设计模式
2025-08-08 11:27:55 +08:00

224 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 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 重写凭据生成方法
func (p *IMAPPlugin) generateCredentials() []*base.Credential {
// 获取IMAP专用的用户名字典
usernames := common.Userdict["imap"]
if len(usernames) == 0 {
// 默认IMAP用户名
usernames = []string{"admin", "root", "test", "mail", "postmaster", "administrator"}
}
return base.GenerateCredentials(usernames, common.Passwords)
}
// 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()
}