验证邮箱用户是否存在

  • A+
所属分类:安全博客

说明

  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,会不会超时?

验证邮箱用户是否存在

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"33[%sm%s%s" % (colors[u"red"], flags[flag], string))
if flag =="info":
print(u"33[%sm%s%s" % (colors[u"white"], flags[flag], string))
if flag == 'echo' or flag == '' or flag == 0:
print(u"33[%sm%s%s" % (colors[u"white"], flags[flag], string))
if flag == 'success':
print(u"33[%sm%s%s" % (colors[u"green"], flags[flag], string))
if verbose == 1:
if flag == 'warning':
print(u"33[%sm%s%s" % (colors[u"yellow"], flags[flag], string))
if flag == 'debug':
print(u"33[%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 %srn" % 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>rn" % 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>rn" % 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 = "QUITrn"
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)

Source:wolvez.club | Author:wolvez

相关推荐: Fuzzing binder for fun and profit

这是11.20日我在京东沙龙演讲的ppt, 讲述了binder的基本结构和我们发现的几个漏洞的利用方式. 由于讲的0day内容google还没有公开补丁,故这个公开下载的ppt马赛克了这部分内容. ppt链接在 http://tool.flanker017.m…

发表评论

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