【邮件伪造】SPF与DKIM验证原理及实战解析(上)
0x01 前言
大家好,我是VoltCary
本篇文章是系列邮件安全专题的第一篇,主要帮助大家掌握邮件安全的基础知识。
基础内容包括:
SMTP协议 邮件安全验证原理与过程 SPF验证与DKIM签名验证原理
掌握这些基础后,你将能够更好地理解邮件伪造的验证原理与绕过技巧,进而掌握邮件伪造的排查方式。如果没有彻底弄懂原理,很容易陷入困惑,只会照搬别人现成的方法。
0x02 SPF
SPF基础
SPF用于验证发件人的IP地址是否被授权发送该域名的邮件。
通过配置SPF记录,域名所有者可以指定哪些邮件服务器可以代表该域名发送邮件。当域名和IP一致,则SPF验证通过。
SPF是校验是由收件人邮件服务器,基于 MAIL FROM
字段(又叫 Envelope From
)、Return-Path
字段中的邮箱域名,并获取发件人的IP地址。
然后查询域名DNS的txt记录,判断此邮箱域名是授权哪些服务器IP发送邮件,如果发件人IP与DNS记录的授权服务器IP一致,那么SPF就会验证通过。
From 字段(显示发件人): 只用于显示给邮件收件人看的,通常作为邮件伪造攻击。收件人看到的是邮件的 From 地址,但它不会直接影响 SPF 校验,SPF 校验与 From 字段无关。 MAIL FROM:用于邮件的传输(即在 SMTP 会话中)标识发件人。 Return-Path:通常用于定义邮件退回的地址。在邮件传输过程中,如果邮件无法送达,退信会发到这个地址。
SPF 记录必须遵循一定的标准,以便服务器理解其内容。如下是SPF记录内容示例:
v=spf1 ip4:192.0.2.0 ip4:192.0.2.1 include:examplesender.email -all
v=spf1
:告诉服务器这里包含一条 SPF 记录。每一条 SPF 记录都必须以这个字符串开始。
ip4
:授权 IP 地址。在本例中,SPF 记录告诉服务器,ip4:192.0.2.0
和ip4:192.0.2.1
被授权代表该域发送电子邮件。
include:examplesender.net
:该标记告诉服务器,有哪些第三方组织被授权代表该域发送电子邮件。这个标记表示,被包含域(examplesender.net)的 SPF 记录内容应被检查,其中包含的 IP 地址也应被视为已授权。一条 SPF 记录中可包含多个域,但这个标记仅适用于有效的域。
-all
:严格的 SPF 失败处理策略,表示SPF 记录中未列出的地址没有被授权发送电子邮件并应被拒绝。
~all
:软失败,即宽松的SPF 配置,表示未列出的电子邮件将被标记为不安全邮件或垃圾邮件,但仍会被接受;
+all
:表示任何服务器都可以代表该域发送电子邮件。
查询SPF方式
nslookup -qt=txt qq.com
0x03 SPF校验邮箱伪造流程
校验关键点
校验关键点:SPF 校验关注的是邮件传输路径,即通过
MAIL FROM
和Return-Path
字段来验证发送邮件的服务器是否合法。From字段仅用于显示,不影响SPF校验。注意:SPF校验是针对
MAIL FROM
字段的,而非 From 字段。
SPF校验流程
说明:这里以中继服务发送伪造邮件的 SPF 校验作为示例。
因为直接本机发送过于简单,无需讲解。
假设:
中继服务邮箱为aaa@aaa.com
,
攻击者通过SMTP登录中继服务,
伪造bbb@bbb.com
,发送邮件给ccc@ccc.com
。
1、攻击者登录 SMTP 中继邮件服务器:使用aaa@aaa.com
登录,并伪造邮件的 From 地址为 bbb@bbb.com
,然后发送邮件到 ccc@ccc.com
。
2、From 字段(显示发件人)在邮件头中会显示为:
From: bbb@bbb.com
3、但是,实际的邮件头中会包含中继服务器的 MAIL FROM 字段,通常为:
MAIL FROM: aaa@aaa.com
这个 MAIL FROM
字段才是被用来进行SPF 校验。
4、收件人邮件服务器处理
收件人邮件服务器 ccc@ccc.com
会根据 aaa@aaa.com
域名的 SPF 记录来验证邮件是否来自合法的邮件服务器。
如果中继服务器的 IP 地址没有被列在 aaa.com
的 SPF 记录中,SPF 校验会失败。
注意:
这里收件人邮件服务器并不是验证 bbb@bbb.com
的 SPF 记录,而是验证 发送邮件的服务器(中继服务) 是否有权通过 aaa@aaa.com
发送邮件。
结论:
SPF 校验是针对 MAIL FROM
字段的。收件人邮件服务器会根据 aaa@aaa.com
域名的 SPF 记录来检查邮件是否由中继服务器的 IP 地址发送。如果中继服务器的 IP 地址不在 aaa.com
的 SPF 记录中,SPF 校验会失败。
收件人不会验证 bbb@bbb.com
的 SPF 记录,因为 SPF 校验关注的是邮件的 传输路径,即发件人邮件服务器的 IP 地址,而不是邮件的显示发件人。
SMTP 命令示例
如果攻击者通过中继服务发送伪造邮件,以下是一个基本的 SMTP 会话示例。攻击者通过登录到中继服务器,并在发送邮件时伪造 From 字段。
SMTP 命令过程:
1、攻击者连接到中继服务器
telnet relay.server.com 25
2、SMTP 会话开始
HELO attacker.com
3、发送 MAIL FROM
命令,伪造发件人地址为 bbb@bbb.com
,使用中继服务的邮箱 aaa@aaa.com
作为发送源
MAIL FROM:<aaa@aaa.com>
4、发送 RCPT TO 命令,指定收件人地址
RCPT TO:<ccc@ccc.com>
5、发送 DATA 命令,开始编写邮件内容:
DATA
6、邮件内容:
From: bbb@bbb.com
To: ccc@ccc.com
Subject: Fake Email
This is a fake email.
7、结束邮件并发送:
.
8、SMTP 会话结束:
QUIT
SPF 中继校验总结:
SPF
校验 是基于 MAIL FROM
或 Return-Path
字段进行的,而中继服务一般 MAIL FROM
中的邮箱域名与授权IP是一致的、或没有 SPF 记录或者被滥用。
收件人的邮件服务器无法检测到问题,只是校验SPF失败,但是也可能会继续接收。
因为收件人的邮件服务器如果没有严格配置 SPF 检查策略,或者它没有明确设置拒绝 SPF 检查失败的邮件。
重点:
在这个过程中,邮件头中的 From: bbb@bbb.com
是伪造的,MAIL FROM: aaa@aaa.com
是实际用于 SPF 校验的字段。
收件人邮件服务器 验证 aaa@aaa.com
的 SPF 记录,而不是 bbb@bbb.com
的 SPF。
0x04 DKIM签名验证过程
DKIM一般用来验证传输过程中是否被篡改,例如中间人攻击,包括开放中继,滥用邮件服务器,基于签名的有效性,来验证邮件头部和正文是否被篡改。
DKIM也可以达到拦截伪造邮箱的效果,因为伪造邮箱根本没有带上签名,就算带上假的签名,收件人邮件服务器去域名DNS查询公钥时,解密出来的结果也会不一致,除非攻击者知道私钥。
因此,虽然DKIM与SPF的验证原理不一致,但是单从拦截邮箱伪造来讲,当验证不通过,结果也会可能一致拒绝、或标记为垃圾邮件,也可以解决邮箱伪造的攻击。
DKIM 的验证基于 公钥加密机制。具体过程如下:
1、发件人邮件服务器生成 DKIM 签名
发件人邮件服务器(如
mail.example.com
)会在邮件发送前,对某些部分(如邮件头部和正文摘要)使用私钥进行加密,生成一个DKIM 签名。这个签名被添加到邮件的
DKIM-Signature
头部,常见字段如下:DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=example.com; s=default; bh=abc123...;
h=From:To:Subject;
b=signature_valueh=From:To:Subject
:指定DKIM 签名会记录哪些头部字段参与计算。d=example.com
:标明发送邮件的域名。s=default
:选择器,指向 DNS 中存储公钥的位置。b=signature_value
:签名值,签名的加密部分,由邮件正文和头部摘要加密生成。bh=
:表示正文的哈希摘要值(Body Hash
)。
2、收件人邮件服务器提取 DKIM 签名
收件人邮件服务器在收到邮件后,解析
DKIM-Signature
头部字段。它根据
d=
(域名)和s=
(选择器)字段,去 DNS 查询发件人的公钥记录:default._domainkey.example.com TXT "v=DKIM1; k=rsa; p=public_key_value"
p=public_key_value
是域名发布的公钥。
3、收件人邮件服务器验证签名
收件人邮件服务器使用 DNS 查询到的公钥,解密 DKIM-Signature
中的签名值。解密后得到的是邮件发送时计算的摘要值,接着,收件人邮件服务器会基于邮件头部和正文,经过组合并哈希算法处理(如 SHA-256
),生成邮件摘要。重新计算邮件的当前摘要值,并将两者进行比较。
0x05 总结
本文详细介绍了邮件安全的验证方式,以及验证过程。下一期将会实践邮箱伪造,并介绍邮件头,基于邮件头来识别邮箱伪造攻击,敬请期待!
【邮件伪造】SPF与DKIM验证原理及实战解析(上)的更多相关文章
- Swaks绕过SPF验证进行邮件伪造
0x00 swaks简介 Swaks是一个功能强大,灵活,可编写脚本,面向事务的SMTP测试工具,由John Jetmore编写和维护. 目前Swaks托管在私有svn存储库中.官方项目页面是http ...
- SPF难以解决邮件伪造的现状以及方案
邮件伪造的现状 仿冒域名 私搭邮服仿冒域名: 例如某公司企业的域名是example.com,那么攻击者可以搭建一个邮服,也把自己的域名配置为example.com,然后发邮件给真实的企业员工xxx@e ...
- SPF邮件伪造漏洞测试脚本
测试脚本: # -*- coding: utf-8 -*- import socket,select,base64,os,re,time,datetime class mail: def __init ...
- Amazon SES SPF和DKIM设置教程
SPF和DKIM设置是争对域名邮箱而言的(公共邮件也不会给你修改DNS的权限),主要作用就是防止邮箱伪造提升邮件信用度 首先到亚马逊添加域名并验证 添加后,给出了域名验证的方法,就是在dns记录里添加 ...
- 邮件伪造测试-Swaks
1. 前言 在kali中自带一个邮件伪造工具Swaks,工具项目主页为 http://jetmore.org/john/code/swaks 2.基本用法: swaks --to --from --e ...
- shopnc 支持 支付宝快捷登陆 shopnc权限验证原理说明
为目前使用的是shopnc商场二次开发,shopnc本身做了qq互联和微博快捷登陆的api,做成了集成通用的接口 首先说下基本的这种类型的api访问方式,首先,的有个配置文件,配置你申请的id和key ...
- Django中csrf token验证原理
我多年没维护的博客园,有一篇初学Django时的笔记,记录了关于django-csrftoekn使用笔记,当时几乎是照抄官网的使用示例,后来工作全是用的flask.博客园也没有维护.直到我的博客收到了 ...
- Django中csrf_token验证原理
我多年没维护的博客园,有一篇初学Django时的笔记,记录了关于django-csrftoekn使用笔记,当时几乎是照抄官网的使用示例,后来工作全是用的flask.博客园也没有维护.直到我的博客收到了 ...
- yii2的csrf验证原理分析及token缓存解决方案
本文主要分三个部分,首先简单介绍csrf,接着对照源码重点分析一下yii框架的验证原理,最后针对页面缓存导致的token被缓存提出一种可行的方案.涉及的知识点会作为附录附于文末. 1.CSRF描述 C ...
- asp.net core 3.x 身份验证-3cookie身份验证原理
概述 上两篇(asp.net core 3.x 身份验证-1涉及到的概念.asp.net core 3.x 身份验证-2启动阶段的配置)介绍了身份验证相关概念以及启动阶段的配置,本篇以cookie身份 ...
随机推荐
- Angular 18+ 高级教程 – Component 组件 の Control Flow
前言 Control Flow 是 Angular v17 版本后推出的新模板语法,用来取代 NgIf.NgForOf.NgSwitch 这 3 个 Structure Directive. Stru ...
- CSS – Tailwind CSS
前言 很多时候 CSS 未必是需要管理的, 比如做网站, Landing Page (类似宣传单). 很多时候做了 > 用了 > 丢 > 再做新的. 它没有 "维护&quo ...
- 阿里面试官常问的TCP和UDP,你真的弄懂了吗?
前 言 作为软件测试,大家都知道一些常用的网络协议是我们必须要了解和掌握的,面试的时候面试官也非常喜欢问一些协议相关的问题,其中有两个协议因为非常基础,出现的频率非常之高,分别是 "T ...
- C#|.net core 基础 - 扩展数组添加删除性能最好的方法
今天在编码的时候遇到了一个问题,需要对数组变量添加新元素和删除元素,因为数组是固定大小的,因此对新增和删除并不友好,但有时候又会用到,因此想针对数组封装两个扩展方法:新增元素与删除元素,并能到达以下三 ...
- fp16 的累加误差有多大
本文地址:https://wanger-sjtu.github.io/fp16-err/ 最近在项目中需要实现fp16的数据类型做FFN的计算,算子实现的同学反馈误差与x86上得到的golden数据有 ...
- .NET 开源 EF Core 批处理扩展工具,真好用
前言 Entity Framework Core(EF Core)作为 .NET 生态系统中受欢迎的对象关系映射器(ORM),其轻量级.可扩展性和支持多个数据库引擎而备受青睐. 本文将介绍一款.NET ...
- 04 Transformer 中的位置编码的 Pytorch 实现
1:10 点赞 16:00 我爱你 你爱我 1401 class PositionalEncoding(nn.Module): def __init__(self, dim, dropout, max ...
- kotlin基础——>基本数据类型、控制流、返回和跳转
1.对于数字的定义,支持java 8的下划线分割的方式 val a = 1_2_3 与 val a = 123 是相同的 2.如果要指定数字类型有两种方式 val a : Float = 1 或者 v ...
- fastjson序列化导致prometheus返回监控数据格式错乱
在springboot 中集成prometheus的监控时遇见问题. 因为项目里在StaticResourceConfig配置了fastjson 序列化,导致prometheus接口返回数据被转化为j ...
- 在 Kubernetes 中部署并使用 KubeEdge
作者:马伟,青云科技容器顾问,云原生爱好者,目前专注于云原生技术,云原生领域技术栈涉及 Kubernetes.KubeSphere.KubeKey 等. 边缘计算在广泛制造业.工业.零售和金融等行业, ...