验证邮箱用户是否存在

admin 2022年5月17日03:54:41安全博客评论32 views4596字阅读15分19秒阅读模式

说明

  1. 原理: 使用smtp RCPT TO 指令,存在返回250状态码,邮箱地址不存在,返回550状态码(感谢klion指点)
  2. 第一版仅作邮件地址是否存在校验
  3. 如果提示554 Your access to this mail system has been rejected due to the sending MTA's poor reputation 之类字样,当前请求IP信誉不佳请尝试更换服务器, 如aliyun,azure,Amazon之类服务运行该脚本
  4. 关于exchange 接口可用metasploit-framework auxiliary/scanner/msmail/onprem_enum 模块
  5. 请勿用于非法用途,本脚本仅用作技术研究

待完成功能:

  • 字典批量验证
  • 多线程批量验证
  • 支持SMTP/SSL

问题:

  1. 多次登录会不会被纳入信誉不佳?
  2. 可不可以一次登录,发送多次 RCPT TO:xxx,会不会超时?

2020-12-07-04-05-59

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# -*- coding: utf-8 -*-
import dns.resolver
import argparse
from socket import *
import random

def ColorPrint(string="", flag="", verbose=""):
colors = {
u"gray": "2",
u"red": "31",
u"green": "32",
u"yellow": "33",
u"blue": "34",
u"pink": "35",
u"cyan": "36",
u"white": "37",
}
flags = {
u"error": "[-] ",
u"warning": "[!] ",
u"info": "[*] ",
u"success": "[+] ",
u"debug": ">>> ",
u"echo": ">>> "
}
try:
if flag == 'error':
print(u"\033[%sm%s%s" % (colors[u"red"], flags[flag], string))
if flag =="info":
print(u"\033[%sm%s%s" % (colors[u"white"], flags[flag], string))
if flag == 'echo' or flag == '' or flag == 0:
print(u"\033[%sm%s%s" % (colors[u"white"], flags[flag], string))
if flag == 'success':
print(u"\033[%sm%s%s" % (colors[u"green"], flags[flag], string))
if verbose == 1:
if flag == 'warning':
print(u"\033[%sm%s%s" % (colors[u"yellow"], flags[flag], string))
if flag == 'debug':
print(u"\033[%sm%s%s" % (colors[u"white"], flags[flag], string))
except:
return 0

# 第一步: 获取域名MX 记录


def DNSQuery(mailaddr):
dns_resolver = dns.resolver.Resolver(configure=False)
dns_resolver.timeout = 5
dns_resolver.lifetime = 5
dns_resolver.nameservers = ['119.29.29.29']
record = "MX"
domain = mailaddr[mailaddr.find(u"@") + 1:]
ColorPrint("query MX of DNS for %s" % domain, flag= "echo", verbose=verbose)
try:
MX = dns_resolver.resolve(domain, record)
m = random.randint(0, len(MX))
mx = MX[0].exchange
strMx = str(mx)[:-1]
assert strMx != u""
except Exception as e:
ColorPrint("query MX of %s failed: %s" % (strMx, e), flag="error", verbose=verbose)
return 0
ColorPrint("MX Server: %s" % strMx, flag="info", verbose=verbose)
return strMx

# 第二步: 请求mail服务器

def smtpsend(server, port=20, mail_rcptTo=""):
mailserver = (server, port)
clientSocket = socket(AF_INET, SOCK_STREAM)
helloDomain = server[server.find(u".") + 1:]
mail_from = "[email protected]"
ColorPrint("connect to %s:%.f" % (server, port), flag="debug", verbose=verbose)
try:
clientSocket.connect(mailserver)
recv = clientSocket.recv(1024)
recv = recv.decode()
if recv[0:3] != '220':
ColorPrint("info: " + recv, flag="debug", verbose=verbose)
return 0
except Exception as e:
ColorPrint("Error: %s" % e, flag="error", verbose=verbose)
ColorPrint("Done. " , flag="info", verbose=verbose)
return 0
ColorPrint("Message after connection request: \n" + recv, flag="debug", verbose=verbose)
hello_command = "EHLO %s\r\n" % helloDomain
clientSocket.send(hello_command.encode())
recv1 = clientSocket.recv(1024)
recv1 = recv1.decode()
ColorPrint("Message after EHLO command:\n" + recv1, flag="debug", verbose=verbose)
if recv1[:3] != '250':
ColorPrint("250 reply not received from server." + recv1, flag="error", verbose=verbose)
return 0
mail_from_command = "MAIL FROM:<%s>\r\n" % mail_from
clientSocket.send(mail_from_command.encode())
recv2 = clientSocket.recv(1024)
recv2 = recv2.decode()
ColorPrint("After MAIL FROM command: " + recv2, flag="debug", verbose=verbose)
rcptTo = "RCPT TO:<%s>\r\n" % mail_rcptTo
clientSocket.send(rcptTo.encode())
recv3 = clientSocket.recv(1024)
recv3 = recv3.decode()
if recv3[:3] == '550':
ColorPrint("Account: %s does not exist." % mail_rcptTo, flag="error", verbose=verbose)
ColorPrint("Done. ", flag="info", verbose=verbose)
return 0
ColorPrint("Account: %s exists." % mail_rcptTo, flag="success", verbose=verbose)
ColorPrint("After RCPT TO command: %s" % recv3, flag="debug", verbose=verbose)
quit = "QUIT\r\n"
clientSocket.send(quit.encode())
recv4 = clientSocket.recv(1024)
clientSocket.close()
ColorPrint("Done. " , flag="info", verbose=verbose)
return mail_rcptTo


if __name__ == "__main__":
'''
port = 25
verbose = False #详细输出,可输出debug信息
mailaddr = "[email protected]" # 需要验证的邮箱地址
mail_rcptTo = mailaddr
server = DNSQuery(mailaddr)
smtpsend(server, port, mail_rcptTo)
'''
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--email",
help="Verification Email Address.", required=True)
parser.add_argument("-s", "--server",
help="Smtp Server.")
parser.add_argument("-p", "--port",
help="Smtp Server Port.", default=25, type=int)
parser.add_argument("-v", "--verbose",
help="verbose info (choice in [True, False])", default=False, type=bool)

args = parser.parse_args()

port = args.port
verbose = args.verbose
mailaddr = args.email
mail_rcptTo = mailaddr
server = args.server
if server == None:
server = DNSQuery(mailaddr)
smtpsend(server, port, mail_rcptTo)

FROM :WOLVEZ'S BLOG| Author:wolve

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年5月17日03:54:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  验证邮箱用户是否存在 http://cn-sec.com/archives/1012609.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: