fscan/Plugins/POP3.go
2024-12-23 02:21:17 +08:00

124 lines
3.1 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 Plugins
import (
"bufio"
"crypto/tls"
"fmt"
"github.com/shadow1ng/fscan/Common"
"net"
"strings"
"time"
)
func POP3Scan(info *Common.HostInfo) (tmperr error) {
if Common.DisableBrute {
return
}
starttime := time.Now().Unix()
for _, user := range Common.Userdict["pop3"] {
for _, pass := range Common.Passwords {
pass = strings.Replace(pass, "{user}", user, -1)
flag, err := POP3Conn(info, user, pass)
if flag && err == nil {
return err
}
errlog := fmt.Sprintf("[-] POP3服务 %v:%v 尝试失败 用户名: %v 密码: %v 错误: %v", info.Host, info.Ports, user, pass, err)
Common.LogError(errlog)
tmperr = err
if Common.CheckErrs(err) {
return err
}
if time.Now().Unix()-starttime > (int64(len(Common.Userdict["pop3"])*len(Common.Passwords)) * Common.Timeout) {
return err
}
}
}
return tmperr
}
func POP3Conn(info *Common.HostInfo, user string, pass string) (bool, error) {
host, port := info.Host, info.Ports
timeout := time.Duration(Common.Timeout) * time.Second
addr := fmt.Sprintf("%s:%s", host, port)
// 首先尝试普通连接
conn, err := net.DialTimeout("tcp", addr, timeout)
if err == nil {
if flag, err := tryPOP3Auth(conn, host, port, user, pass, timeout, false); err == nil {
return flag, nil
}
conn.Close()
}
// 如果普通连接失败尝试TLS连接
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
}
conn, err = tls.DialWithDialer(&net.Dialer{Timeout: timeout}, "tcp", addr, tlsConfig)
if err != nil {
return false, fmt.Errorf("连接失败: %v", err)
}
defer conn.Close()
return tryPOP3Auth(conn, host, port, user, pass, timeout, true)
}
func tryPOP3Auth(conn net.Conn, host string, port string, user string, pass string, timeout time.Duration, isTLS bool) (bool, error) {
reader := bufio.NewReader(conn)
conn.SetDeadline(time.Now().Add(timeout))
// 读取欢迎信息
_, err := reader.ReadString('\n')
if err != nil {
return false, fmt.Errorf("读取欢迎消息失败: %v", err)
}
// 发送用户名
conn.SetDeadline(time.Now().Add(timeout))
_, err = conn.Write([]byte(fmt.Sprintf("USER %s\r\n", user)))
if err != nil {
return false, fmt.Errorf("发送用户名失败: %v", err)
}
// 读取用户名响应
conn.SetDeadline(time.Now().Add(timeout))
response, err := reader.ReadString('\n')
if err != nil {
return false, fmt.Errorf("读取用户名响应失败: %v", err)
}
if !strings.Contains(response, "+OK") {
return false, fmt.Errorf("用户名无效")
}
// 发送密码
conn.SetDeadline(time.Now().Add(timeout))
_, err = conn.Write([]byte(fmt.Sprintf("PASS %s\r\n", pass)))
if err != nil {
return false, fmt.Errorf("发送密码失败: %v", err)
}
// 读取密码响应
conn.SetDeadline(time.Now().Add(timeout))
response, err = reader.ReadString('\n')
if err != nil {
return false, fmt.Errorf("读取密码响应失败: %v", err)
}
if strings.Contains(response, "+OK") {
result := fmt.Sprintf("[+] POP3服务 %v:%v 爆破成功 用户名: %v 密码: %v", host, port, user, pass)
if isTLS {
result += " (TLS)"
}
Common.LogSuccess(result)
return true, nil
}
return false, fmt.Errorf("认证失败")
}