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() }