邮件测试工具

admin 2022年5月17日03:55:12安全博客 安全工具评论42 views6511字阅读21分42秒阅读模式

请勿用于非法用途,仅供测试使用

  • 开发此软件初衷:
    原本一直使用:swaks 工具进行邮件发送测试, 忽然有一天想发送带中文标题的发现乱码(这能忍?),想尝试修改swaks,看了swaks 源码之后放弃了,非常难读懂,所以就写了该工具

  • 题外话: 网上只要涉及钓鱼邮件的文章都推荐用swaks,不是说这工具不好,swaks功能非常强大,但用来作邮件欺骗有些杀鸡用牛刀了,smtp发送大多数情况下并不需要发送方提供smtp服务器,SPF只是为了保护自己域名的,网上很多文章没有搞懂. 转发邮件伪装效果并不好,后面出一篇如何伪造相关的文章

  • 网上那么多类似的工具为什么要自己造轮子:
    自己造轮子的好处是真正了解功能如何实现,出现bug或有其它需求知道怎么快速改

待实现功能

  • CC 邮件抄送
  • BCC 密件抄送
  • 定义回复邮件者
  • web编辑邮件内容功能
  • tls 支持

推荐文章

2020-12-14-04-15-18

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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# -*- coding: utf-8 -*-
import argparse
from smtplib import SMTP
from base64 import encodebytes
from email.utils import make_msgid, formatdate
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
import random
import dns.resolver
from email.header import Header
import base64
import os
from io import open
from os.path import basename

def isBase64(content):
try:
return base64.b64encode(base64.b64decode(str)) == content
except Exception:
return False


def isFile(content):
try:
return os.path.isfile(content)
except Exception:
return False


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


def DNSQuery(mailaddr):
verbose = 1
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="success", verbose=verbose)
return strMx


def send_mail(server=None, port=None, mail_from=None, to=None, h_from=None, subject=None, content=None, html=None,
auth=None, user=None, password=None, tls=None, debuglevel=2, attachment=None):

# Compose mail headers
msg = MIMEMultipart('alternative')
msg['Subject'] = Header(subject, 'utf-8')
msg['X-Mailer'] = "MSOffice365"
msg['To'] = to
msg['Message-id'] = make_msgid() # Message-ID标头
msg['Date'] = formatdate() # 日期
if h_from:
msg['From'] = Header(h_from, 'utf-8')
else:
msg['From'] = Header(mail_from, 'utf-8')
# Compose mail body
if html and content:
ColorPrint("The \"--html\" and \"--content\" args do not go together!", "error", verbose=1)
return 0
if html:
if isFile(html):
with open(html, "rb") as content_str:
new_content_str = content_str.read().decode("UTF-8")
if isBase64(new_content_str):
base64txt = base64.b64decode(new_content_str.strip())
html_part = MIMEText(base64txt.decode(), 'html', "utf-8")
else:
html_part = MIMEText(new_content_str, 'html', "utf-8")
msg.attach(html_part)
else:
ColorPrint("Example: \"--html\" ./msg.html !", "error", verbose=1)
return 0

if content:
if isFile(content):
with open(content, "rb") as content_str:
new_content_str = content_str.read().decode("UTF-8")
if isBase64(new_content_str):
base64txt = base64.b64decode(new_content_str.strip())
text_part = MIMEText(base64txt.decode(), 'plain', "utf-8")
else:
text_part = MIMEText(new_content_str, 'plain', "utf-8")
msg.attach(text_part)
else:
#print(content)
text_part = MIMEText(content, 'plain', "utf-8")
msg.attach(text_part)

if attachment:
with open(attachment, 'rb') as f:
attachfile = MIMEBase('application', "octet-stream")
attachfile.set_payload(encodebytes(f.read()).decode())
f.close()
attachfile.add_header('Content-Transfer-Encoding', 'base64')
attachfile.add_header('Content-Disposition', 'attachment', filename=attachment)
msg.attach(attachfile)


smtp = SMTP()
smtp.set_debuglevel(debuglevel)
if not server:
server = DNSQuery(to)
ehlo = domain = to[to.find(u"@") + 1:]
try:
smtp.connect(server, port)
smtp.ehlo(ehlo)
if auth:
smtp.login(user, password)
smtp.sendmail(mail_from, to, msg.as_string())
ColorPrint("send success!", flag="success", verbose=1)
except SMTP.SMTPException as e:
ColorPrint(e, flag="error", verbose=1)
smtp.quit()
smtp.close()
finally:
smtp.quit()
smtp.close()


parser = argparse.ArgumentParser(description="mailsender version 1.0 by wolvez", epilog='Example :\nmailsender.py --auth 1 --server smtp.mailgun.org --user [email protected] --password [email protected] -to [email protected] --subject "测试邮件" --mail-from [email protected] --debuglevel 1 --html ./test.html --file ./test.txt')
parser.add_argument("-s", "--server", help="Smtp Server.") # smtp服务器地址
parser.add_argument("-p", "--port", help="Smtp Server Port.", default=25, type=int) # smtp服务器端口
parser.add_argument("--mail-from", dest="mail_from", help="from mail addresses.", required=True) # 实际发送者,MAIL FROM
parser.add_argument("-to", "--to", help="to mail addresses.", required=True) # 接收邮件者,可为多个
parser.add_argument("--h-from", help="mail Mailsender") # 显示的发件人,FROM,伪造邮件头
parser.add_argument("--subject", help="message title", default="testmail") # 邮件主题
parser.add_argument('--content', '--msg-content', "--body", help="message body") # 邮件内容,如果为文件可包含html文件,也可以为输入包含html内容邮件
parser.add_argument("--html", help="message html body")
parser.add_argument("--attachment", "--file", required=False, help="One or few files to attach") # 邮件附件
parser.add_argument("--auth", help="Smtp Auth", type=bool, default=False) # smtp登录
parser.add_argument("--user", help="Smtp Auth username") # smtp 用户名
parser.add_argument("--password", help="Smtp Auth Password") # smtp 密码
parser.add_argument('--tls', dest='tls', default=False, type=bool, help="Use TLS if specified") # smtpsll方式
parser.add_argument("--debuglevel", required=False, type=int, default=True, help="Debug level")

args = parser.parse_args()
kwargs = args.__dict__
send_mail(**kwargs)

FROM :WOLVEZ'S BLOG| Author:wolve

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

发表评论

匿名网友 填写信息

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