浅析邮件伪造

SPF配置

spf全称为(Sender Policy Framework),即发件人策略框架

目前所进行的邮件通信,使用的是smtp协议(Simple Mail Transfer Protocol),即简单邮件传输协议。但是smtp是没有很好的安全措施的,一个简单的例子为:发件人的邮箱地址可以由发信方任意声明,即发件人邮箱伪造。

spf就是为了解决这个问题,spf的原理:

假设邮件服务器收到了一封邮件,发件人的IP为:192.6.6.6,并且声称发件人为 email@example.com。为了确认发件人不是伪造的,邮件服务器会查询 example.com的spf记录。如果该域的spf记录设置允许IP为 192.6.6.6 主机发送邮件,则服务器认为这封邮件是合法的,否则,会退信(即收件人收不到邮件),或者邮件躺在垃圾箱。邮箱伪造可以声明他来自example.com,但是却无法操作 example.com 的 DNS解析记录,也无法伪造自己的IP地址,所以SPF还是可以有效防御邮件伪造的。

通俗的来讲,A 和 B 两个人建立通信,A向B发送信息,B 检查 A是不是在常用地(白名单)发的信息,如果不是,则拒收信息。

SPF 记录的语法

一条 SPF 记录定义了一个或者多个 mechanism(机制),而 mechanism 则定义了哪些 IP 是允许的,哪些 IP 是拒绝的。

这些 mechanism 包括以下几类:

1
all | ip4 | ip6 | a | mx | ptr | exists | include

每个 mechanism 可以有四种前缀:

1
2
3
4
"+"  Pass(通过)
"-" Fail(拒绝)
"~" Soft Fail(软拒绝)
"?" Neutral(中立)

测试时,将从前往后依次测试每个 mechanism。如果一个 mechanism 包含了要查询的 IP 地址(称为命中),则测试结果由相应 mechanism 的前缀决定。默认的前缀为+。如果测试完所有的 mechanisms 也没有命中,则结果为 Neutral。

除了以上四种情况,还有 None(无结果)、PermError(永久错误)和 TempError(临时错误)三种其他情况。对于这些情况的解释和服务器通常的处理办法如下:

结果 含义 服务器处理办法
Pass 发件 IP 是合法的 接受来信
Fail 发件 IP 是非法的 退信
Soft Fail 发件 IP 非法,但是不采取强硬措施 接受来信,但是做标记
Neutral SPF 记录中没有关于发件 IP 是否合法的信息 接受来信
None 服务器没有设定 SPF 记录 接受来信
PermError 发生了严重错误(例如 SPF 记录语法错误) 没有规定
TempError 发生了临时错误(例如 DNS 查询失败) 接受或拒绝

注意,上面所说的「服务器处理办法」仅仅是 SPF 标准做出的建议,实际测试中,并非所有的邮件服务器都严格遵循这套规定。还是要仔细看。

Mechanisms(机制)

下面介绍上面提到的 mechanism,mechanism 是规则,而上面说的服务器处理办法是服务器的返回值,简单来说,mechanism是因,服务器处理办法是果。

all

表示所有 IP,肯定会命中。因此通常把它放在 SPF 记录的结尾,表示处理剩下的所有情况。例如:

1
2
"v=spf1 -all" 拒绝所有(表示这个域名不会发出邮件)
"v=spf1 +all" 接受所有(域名所有者认为 SPF 是没有用的,或者根本不在乎它)

ip4

格式为ip4:<ip4-address>或者ip4:<ip4-network>/<prefix-length>,指定一个 IPv4 地址或者地址段。如果prefix-length没有给出,则默认为/32。例如:

1
2
"v=spf1 ip4:192.168.0.1/16 -all"
只允许在 192.168.0.1 ~ 192.168.255.255 范围内的 IP

ip6

格式和ip4的很类似,默认的prefix-length/128。例如:

1
2
"v=spf1 ip6:1080::8:800:200C:417A/96 -all"
只允许在 1080::8:800:0000:0000 ~ 1080::8:800:FFFF:FFFF 范围内的 IP

a 和 mx

这俩的格式是相同的,以a为例,格式为以下四种之一:

1
2
3
4
a
a/<prefix-length>
a:<domain>
a:<domain>/<prefix-length>

会命中相应域名的 a 记录(或 mx 记录)中包含的 IP 地址(或地址段)。如果没有提供域名,则使用当前域名。例如:

1
2
3
4
5
6
7
8
"v=spf1 mx -all"
允许当前域名的 mx 记录对应的 IP 地址。

"v=spf1 mx mx:deferrals.example.com -all"
允许当前域名和 deferrals.example.com 的 mx 记录对应的 IP 地址。

"v=spf1 a/24 -all"
类似地,这个用法则允许一个地址段。

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

1
v=spf1 a mx ip4:173.194.72.103 -all

include

格式为include:<domain>,表示引入<domain>域名下的 SPF 记录。注意,如果该域名下不存在 SPF 记录,则会导致一个PermError结果。例如:

1
"v=spf1 include:example.com -all" 即采用和 example.com 完全一样的 SPF 记录

exists

格式为exists:<domain>。将对<domain>执行一个 A 查询,如果有返回结果(无论结果是什么),都会看作命中。

ptr

格式为ptr或者ptr:<domain>。使用ptr机制会带来大量很大开销的 DNS 查询,所以连官方都不推荐使用它。

关于v=spf1

这是必须的,表示采用 SPF 1 版本,现在它的最新版本就是第 1 版。

Modifiers

SPF 记录中还可以包括两种可选的 modifier;一个 modifier 只能出现一次。

redirect

格式为redirect=<domain>

将用给定域名的 SPF 记录替换当前记录。

exp

格式为exp=<domain>,目的是如果邮件被拒绝,可以给出一个消息。而消息的具体内容会首先对<domain>执行 TXT 查询,然后执行宏扩展得到。

查看目标服务器的spf配置信息

1
dig +short TXT xxx.com

image-20220109230845909

根据上面的小知识,这里可以判断出:

使用的spf1版本的spf,include 后面 采用和 tencent.com qq.com完全一样的spf记录,-all,硬拒绝

swaks使用

1
2
3
4
5
6
7
8
9
10
11
--from test@qq.com 				//发件人邮箱;

--ehlo qq.com //伪造邮件ehlo头,即是发件人邮箱的域名。提供身份认证

--body "http://www.baidu.com" //引号中的内容即为邮件正文;

--header "Subject:hello" //邮件头信息,subject为邮件标题

--data ./Desktop/email.txt //将正常源邮件的内容保存成TXT文件,再作为正常邮件发送

--server mail.smtp2go.com -p 2525 -au 用户名 -ap 密码 //自己的邮箱服务器

最开始是拿自己的qq邮箱测试,但是收不到邮件,下面也指出了原因,因为qq.com作为发信域名设置了spf,这里导致伪造失败。

image-20220107152601144

image-20220107152942708

这是伪造的tencent.com

image-20220107155906940

换了个邮箱,发信成功

image-20220107152504848

image-20220107152442966

关于swaks更高级的用法这里就不说了,网上都可以找到。

找到邮箱中的邮件,导出为eml文件,to后面改为目标邮箱

1
swaks --to xxx@qq.com --from campus@tencent.com --data test.eml --header "Subject: 入职提醒" 

image-20220109232631767

可恶啊,还是失败了

image-20220109232956924

smtp2go

从evi1cg师傅那里看到的,smtp2go主要是相当于邮件托管,可以分发子账户进行发送。

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

下文有提到,倾璇师傅利用python实现了工具化。

去除Mailer特征

1
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> 

附件钓鱼

1
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

脚本伪造

是朋友根据倾璇师傅的脚本改的。倾璇师傅用的smtp2go,这里改了88邮箱。

在88邮箱开个smtp服务,利用88邮箱作为发件箱

image-20220109234851238

看结果

image-20220109234650518

因为不是源码不是我写的,没办法贴出来

总结

swaks玩的好的话,配合钓鱼的手法,很容易可以撕开权限入口。钓鱼的手法多种多样,需要天马行空的想象,思路要骚,进入内网漫游一圈后,运气好的话,就不需要伪造发件人了嘿嘿。这篇文章只是浅析邮件伪造,更多关于smtp协议的知识我也没有深入去学习,暂时感觉还没有这个必要。

参考链接:

1
2
3
4
5
https://payloads.online/archivers/2019-05-09/1/
https://hex.moe/p/4878b295/
https://blog.csdn.net/Alexz__/article/details/105564647
https://www.cnblogs.com/backlion/p/10842676.html
https://www.cnblogs.com/zhaijiahui/p/11494626.html

Peace.