SPF(Sender Policy Framework)发件人策略框架
SPF 是为了防范伪造发件人地址发送垃圾邮件而提出的一种开放式标准,是一种以 IP 地址认证电子邮件发件人身份的技术。域名所有者通过在 DNS 中发布 SPF 记录来授权合法使用该域名发送邮件的 IP 地址。
当在 DNS 中定义了域名的 SPF 记录后,为了确认邮件声称发件人不是伪造的,邮件接收方首先检查邮件域名的 SPF 记录,来确定发件人的 IP 地址是否被包含在 SPF 记录中,若包含,则认为是一封正确的邮件,否则认为是一封伪造的邮件并退回,或将其标记为垃圾 / 仿冒邮件。
设置正确的 SPF 记录可以提高邮件系统发送外域邮件的成功率,也可以一定程度上防止被假冒域名发送邮件。
比如 qq.com 的 qQ.coM text = “v=spf1 include:spf.mail.qq.com -all”
SPF记录是由SPF版本和指定的IP组成。
SPF记录由一个版本开始,格式为:
record = version terms *SP
version = “v=spf1”
terms 由机制mechanisms和修改符modifiers(可选的)组成。
域名定义了一个或者多个机制mechanisms,用来描述哪些IP是被允许使用该域名发送邮件。
Mechanisms包含以下几种类型:
mechanism = ( all / include/ a / mx / ptr / ip4 / ip6 / exists )
知识点:
A 记录(Address)
是用来指定主机名(或域名)对应的IP地址记录。用户可以将该域名下的网站服务器指向到自己的web server上。同时也可以设置您域名的二级域名。
别名记录(CNAME)
也被称为规范名字。这种记录允许您将多个名字映射到同一台计算机。 通常用于同时提供WWW和MAIL服务的计算机。
例如,有一台计算机名为“host.eblhost.cn”(A记录),它同时提供WWW和MAIL服务。为了便于用户访问服务,可以为该计算机设置两个别名(CNAME):WWW和MAIL。 这两个别名的全称就是“www.eblhost.cn” 和“mail.eblhost.cn”。实际上他们都指向“host.eblhost.cn”。
CNAME还有一个特别的好处,就是当您拥有多个域名需要指向同一服务器IP,此时您就可以将一个域名做A记录指向服务器IP,然后将其他的域名做别名到之前做A记录的域名上。当您的服务器IP地址变更时,您就可以不必麻烦的一个一个域名更改指向了,只需要更改做A记录的那个域名所指向的IP,其他做别名的那些域名的指向也将自动更改到新的IP地址上了。
NS记录(Name Server)
Name server是指域名的DNS服务器,DNS服务器可以在注册域名时设定或后期进行更改。
利用NS记录,您可以针对每个域名或子域名来设定NS记录。设定以后,相当于把该域名的解析权交给了对应的DNS服务器。
MX记录(Mail eXchanger)
是邮件交换记录,它指向一个邮件服务器,用于电子邮件系统发邮件时根据 收信人的地址后缀来定位邮件服务器。例如,当Internet上的某用户要发一封信给 [email protected] 时,该用户的邮件系统通过DNS查找mydomain.com这个域名的MX记录,如果MX记录存在, 用户计算机就将邮件发送到MX记录所指定的邮件服务器上。
DNS的名字解析数据可以有各种不同的类型,有设置这个zone的参数的SOA类型数据,有设置名字对应的IP地址的A类型数据,有设置邮件交换的 MX类型数据。这些不同类型的数据均可以通过nslookup的交互模式来查询,在查询过程中可以使用 set type命令设置相应的查询类型。
域名可能也定义修改符modifiers,每个修改符只能使用一次。
Modifiers包含以下几种类型:
modifier = redirect / explanation
每个mechanism有四种前缀(默认前缀为“+”):
在一条SPF记录中,从左到右依次对每个mechanism进行验证。对一个mechanism进行检测,有三种结果可能发生:IP匹配成功,IP匹配失败或者返回异常。如果IP匹配成功,处理结果返回该mechanism的前缀;如果IP匹配失败,继续下一个mechanism;如果返回异常,则mechanism结束并返回该异常值;如果没有mechanism或者modifier匹配,则结果返回“Neutral”。
如果不存在SPF记录,则返回“None”;如果在DNS解析过程中出现临时性错误,则返回“TempError”;如果存在某些语法错误或者评估错误(如该域指向不为人知的机制),则返回“PermError”。
SPF记录验证可能返回的结果如下:
当设置了 SPF 但为软失败时,可以进行邮件伪造
查询命令:
nslookup -qt=txt qq.com
参考
https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=16&&no=1001505
https://www.freebuf.com/sectool/184555.html
https://help.laoxuehost.com/domain-name/a-mx-cname.html
DKIM(DomainKeys Identified Mail)域密钥识别邮件
DKIM 是一种防范电子邮件欺诈的验证技术,通过消息加密认证的方式对邮件发送域名进行验证。
邮件发送方发送邮件时,利用本域私钥加密邮件生成 DKIM 签名,将 DKIM 签名及其相关信息插入邮件头。邮件接收方接收邮件时,通过 DNS 查询获得公钥,验证邮件 DKIM 签名的有效性。从而确认在邮件发送的过程中,防止邮件被恶意篡改,保证邮件内容的完整性。
DKIM 标准的模糊性,缺乏安全默认值,以及 MIME 标准的实现的复杂性,灵活性都可以产生改变邮件的主要信息,比如主题,甚至改变整个邮件的内容。包括添加新的恶意附件,从而可以实现利用现有邮件创造欺诈邮件
而在正常情况下也会发生 DKIM 失效,传统的邮件只限于 ASCII 进行编码,MIME 可以进行拓展,在使用 8BITMIME 进行传输时,中间有服务器不支持将会转为 ASCII 编码,DKIM 就会被破坏
例子:
DKIM-Signature: v=1; a=rsa-sha256; d=example.net; s=brisbane;
c=simple; q=dns/txt; [email protected];
t=1117574938; x=1118006938;
h=from:to:subject:date;
z=From:[email protected]|To:[email protected]|Subject:demo=20run|Date:July=205,=202005=203:44:08=20PM=20-0700;
bh=MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=;
b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZVoG4ZHRNiYzR
解析:
v= 版本号(纯文本,必要的),值为1
格式:v=1*DIGIT
a= 生成签名的算法(纯文本,必要的),验证者必须支持“rsa-sha1”和“rsa-sha256”两种算法,签名者使用“rsa-sha256”签名。
格式:a=rsa-sha1或者a=rsa-sha256
b= 签名数据(base64,必要的)
格式:b=base64string
bh= 消息的规范化主体的哈希值,受“l=”标签限制(base64,必要的)。
格式:bh=base64string
c= 消息规范化算法(纯文本,可选的,默认为“simple/simple”),"/"两边分别对应头部和主体的规范化算法,当“c=simple”或者“c=relaxed”时,表示头部规范化算法使用simple或者relaxed,而主体规范化算法默认为simple。
格式:c=sig-c-tag-alg["/"sig-c-tag-alg]
sig-c-tag-alg="simple"/"relaxed"
d= Signing Domain Identifier ,即SDID (纯文本,必要的)
格式:d=domain-name
h= 签名的头字段(纯文本,必要的),提交给签名算法的头字段名称列表,用“:”分隔。
格式:h=hdr-name*(":"hdr-name)
i= Agent or User Identifier ,即AUID,值为@domain
格式:i=[Local-part]"@"domain-name
Local-part为空,domain-name与“d=”的值一样或者是其子域。
l= 主体长度数(纯文本无符号十进制整型,可选的,默认为整个主体)
格式:l=1*76DIGIT
q= 一个查询方式的列表,以冒号分隔,用于检索公钥(纯文本,可选的,默认为“dns/txt”),每个查询方式的形式为“type[/options]”。
格式:q=dns/txt
s= selector,(纯文本,必要的)
格式:s=selector
t= 签名时间戳(纯文本无符号十进制整型;推荐的,默认为一个未知的创建时间)。
格式:t=1*12DIGIT
x= 签名到期时间(纯文本无符号十进制整型;推荐的,默认永不过期)
格式:x=1*12DIGIT
z= 复制的头字段(dkim-quoted-printable,可选的,默认为null)
格式:z=sig-z-tag-copy*("|"sig-z-tag-copy)
sig-z-tag-copy= hdr-name":"qp-hdr-value
nslookup -qt=txt mail._domainkey.mail.vpgame.net
这里的第一个mail为DKIM中域名的selector,可以修改为不同的值,一个域名可以有多个selector,这样不同的Email server可以有不同的key,_domainkey 是固定格式(DKIM就是基于domainkeys的技术发展而来), mail.vpgame.net 是邮件域
参考:
https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=16&&no=1001507
https://www.freebuf.com/articles/web/138764.html
https://zhuanlan.zhihu.com/p/29965126
DMARC(Domain-based Message Authentication, Reporting & Conformance)基于域的消息认证,报告和一致性
DMARC 是一种基于现有的 SPF 和 DKIM 协议的可扩展电子邮件认证协议,在邮件收发双方建立了邮件反馈机制,便于邮件发送方和邮件接收方共同对域名的管理进行完善和监督。
DMARC 要求域名所有者在 DNS 记录中设置 SPF 记录和 DKIM 记录,并明确声明对验证失败邮件的处理策略。邮件接收方接收邮件时,首先通过 DNS 获取 DMARC 记录,再对邮件来源进行 SPF 验证和 DKIM 验证,对验证失败的邮件根据 DMARC 记录进行处理,并将处理结果反馈给发送方
例子:paypal.com的dmarc记录
_dmarc.paypal.com text = "v=DMARC1\; p=reject\; rua=mailto:[email protected]\; ruf=mailto:[email protected],mailto:[email protected]"
DMARC记录中常用参数:
adkim:(纯文本;可选的;默认为“r”)表明域名所有者要求使用严格的或者宽松的DKIM身份校验模式,有效值如下:
r: relaxed mode
s: strict mode
aspf:(纯文本;可选的;默认为“r”)表明域名所有者要求使用严格的或者宽松的SPF身份校验模式,有效值如下:
r: relaxed mode
s: strict mode
fo:故障报告选项(纯文本;可选的;默认为0),以冒号分隔的列表,如果没有指定“ruf”,那么该标签的内容将被忽略。
0:如果所有身份验证机制都不能产生“pass”结果,那么生成一份DMARC故障报告;
1:如果任一身份验证机制产生“pass”以外的结果,那么生成一份DMARC故障报告;
d:如果消息的签名验证失败,那么生成一份DKIM故障报告;
s:如果消息的SPF验证失败,那么生成一份SPF故障报告。
p:要求的邮件接收者策略(纯文本;必要的)表明接收者根据域名所有者的要求制定的策略。
none:域名所有者要求不采取特定措施
quarantine:域名所有者希望邮件接收者将DMARC验证失败的邮件标记为可疑的。
reject:域名所有者希望邮件接收者将DMARC验证失败的邮件拒绝。
pct:(纯文本0-100的整型;可选的,默认为100)域名所有者邮件流中应用DMARC策略的消息百分比。
rf:用于消息具体故障报告的格式(冒号分隔的纯文本列表;可选的;默认为“afrf”)
ri:汇总报告之间要求的间隔(纯文本32位无符号整型;可选的;默认为86400).表明要求接收者生成汇总报告的间隔不超过要求的秒数。
rua:发送综合反馈的邮件地址(逗号分隔的DMARC URI纯文本列表;可选的)
ruf:发送消息详细故障信息的邮件地址(逗号分隔的DMARC URI纯文本列表;可选的)
sp:要求邮件接收者对所有子域使用的策略(纯文本;可选的),若缺省,则“p”指定的策略将应用到该域名和子域中。
v:版本(纯文本;必要的)值为“DMARC1”,必须作为第一个标签。
DMARC 可用 RFC-1342 编码绕过,包括 “From” 区域在内所有的头信息都必须是 ASCII 字符,主要问题在于用以区分 MTA 处理机制的非 ASCII 字符编码表示协议 RFC-1342 上,很多邮件客户端和 Web 登录接口在采用 RFC-1342 对非 ASCII 字符编码后,都不会对用来伪造电邮身份的编码字符进行有效检查
Base64 和 QUOTED-PRINTABLE(可打印字符引用编码)两种表示方式都可行,但使用新行或空字节等控制字符组合,可以让我们隐藏或删除原始电邮的域名后缀部分,如果 RFC-1342 解析的邮件字符中包含空字节或两个或更多电邮地址,邮件客户端最终只会显示空字节或有效电邮地址之前的伪造地址
例子如下
From: =?utf-8?b?${base64_encode('[email protected]')}?==?utf-8?Q?=00?==?utf-8?b?${base64_encode('([email protected])')}?[email protected]
编码后变为:
From: =?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?==?utf-8?Q?=00?==?utf-8?b?cG90dXNAd2hpdGVob3VzZS5nb3Y=?[email protected]
该 From 信息被邮件客户端解析后就变为这个:From: [email protected]\0([email protected])@mailsploit.com
邮件客户端经过解析后只会显示第一个电邮地址 [email protected],而忽略了真实的电邮域名 @mailsploit.com
查询命令:
% dig +short TXT _dmarc.example.com.
"v=DMARC1; p=none; rua=mailto:dmarc-[email protected];
ruf=mailto:auth-[email protected]"
参考:
https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=16&&no=1001508
https://www.freebuf.com/news/156501.html
spf、dkim、dmarc在线检查:https://dmarcly.com/tools/
其他参考:
https://tmr.js.org/p/b1092e4e/
通过 SPF 对电子邮件发件人进行授权:https://support.google.com/a/answer/33786
使用 DKIM 对电子邮件进行身份验证:https://support.google.com/a/answer/174124
添加 DMARC 记录:https://support.google.com/a/answer/2466563
我这里使用kali自带的swaks,或者官网下载地址:http://www.jetmore.org/john/code/swaks/
使用如下命令测试邮箱是否连通
swaks -to [email protected]
swaks --to [email protected] --from [email protected] --ehlo haha.com --body hello --header "Subject: hello"
说明:
–from <要显示的发件人邮箱>
–ehlo <伪造的邮件ehlo头>
–body <邮件正文>
–header <邮件头信息,subject为邮件标题>
–data <源邮件>
ehlo是对helo的扩展,即extend helo,可以支持authorization,即用户认证
待续。。。