邮件系统取证分析 邮件系统取证分析 邮件系统是企业环境中最核心的通信基础设施之一,也是高级持续性威胁(APT)、勒索软件和商业电子邮件欺诈(BEC)攻击中最常被利用的攻击面。根据 Verizon 2026 DBIR 报告,36% 的数据泄露事件与钓鱼邮件直接相关,邮件系统已经成为威胁行为者获取初始访问权限的首要入口。
与文件系统取证、内存取证不同,邮件系统取证面对的是一个分布式、多节点、多协议 的复杂系统。一封邮件从发件人到收件人,可能经过多个 MTA(邮件传输代理)、邮件网关、反垃圾邮件系统和归档系统,每个节点都可能产生日志和元数据。取证分析师需要理解邮件系统的完整架构,才能在海量日志中定位关键证据。
本文系统性地梳理邮件系统取证的完整技术体系,涵盖 Exchange/Microsoft 365 日志分析、邮件头溯源、邮件附件分析、钓鱼邮件取证、邮件网关日志分析、DKIM/SPF/DMARC 验证、邮件系统持久化检测等核心技术。
0x01 邮件系统架构与安全模型 邮件传输协议 邮件系统基于多层协议栈构建,每层协议都有明确的安全边界和取证价值:
SMTP(Simple Mail Transfer Protocol) 是邮件传输的基础协议,工作在端口 25(明文)或 465/587(加密)。SMTP 负责邮件从发件人 MTA 到收件人 MTA 的中继传输。取证中,SMTP 会话日志可以揭示邮件的真实来源 IP、中继路径和传输时间。SMTP 协议本身不提供身份验证机制,攻击者可以伪造发件人地址(Mail From),这也是钓鱼邮件泛滥的根本原因之一。
IMAP(Internet Message Access Protocol) 工作在端口 143(明文)或 993(TLS),用于邮件客户端从服务器读取邮件。IMAP 协议允许客户端在服务器端操作邮件(标记已读、移动文件夹、删除等),这些操作在 Exchange 和 Microsoft 365 中都会产生审计日志。取证中,IMAP 访问日志可以帮助判断攻击者是否通过 IMAP 协议窃取邮件数据。
POP3(Post Office Protocol) 工作在端口 110(明文)或 995(TLS),将邮件从服务器下载到客户端后通常会删除服务器端副本。POP3 的"下载即删除"特性使其在取证中更具挑战性——如果攻击者使用 POP3 协议读取邮件,服务器端的已读记录可能不够完整。
Exchange ActiveSync(EAS) 是微软专有的邮件同步协议,广泛用于移动设备访问 Exchange 邮箱。EAS 日志记录设备类型、同步时间和操作类型,是检测移动设备异常访问的重要取证来源。在 BEC 攻击中,攻击者常使用 EAS 协议在移动设备上建立持久访问。
邮件系统组件 一个完整的企业邮件系统由多个核心组件构成:
发件人客户端 → MTA(发送) → 邮件网关 → 互联网 → 邮件网关 → MTA(接收) → MDA → 邮件存储 → 收件人客户端MTA(Mail Transfer Agent) 负责邮件的中继和路由。常见的 MTA 包括 Postfix、Sendmail、Exim 和 Exchange Transport Service。每个 MTA 在处理邮件时都会生成传输日志,记录发件人、收件人、Message-ID、源 IP、目标 IP 和传输时间。
MDA(Mail Delivery Agent) 负责将邮件投递到收件人的邮箱存储。在 Exchange 中,MDA 功能由 Information Store 服务承担。MDA 日志可以确认邮件是否成功投递到目标邮箱。
邮件存储 是邮件在服务器上的持久化存储。Exchange 使用 EDB(Exchange Database)文件存储邮件,Microsoft 365 使用后端分布式存储。邮件存储的取证价值在于:即使邮件被用户删除,管理员仍可能通过数据库恢复或"已删除邮件保留"策略找回邮件内容。
邮件网关 部署在邮件系统的边界,负责反垃圾邮件、反病毒、内容过滤和 DLP(数据防泄漏)。邮件网关日志是邮件取证的重要来源之一,记录了每封邮件的扫描结果、分类标签和处理动作。
Exchange 架构概述 Microsoft Exchange Server 是企业环境中部署最广泛的邮件服务器。其架构包含以下核心组件:
Transport Service(传输服务) 负责邮件的路由和传输。Exchange 2019 的传输架构包括 Frontend Transport Service(前端传输服务,监听 25/587 端口)、Hub Transport Service(中心传输服务,负责邮件路由)和 Mailbox Transport Service(邮箱传输服务,与 Information Store 通信)。
Information Store(信息存储) 是 Exchange 的核心数据存储引擎,管理邮箱数据库(EDB 文件)。所有邮件、日历、联系人数据都存储在 Information Store 中。
Client Access Service(客户端访问服务) 提供 OWA(Outlook Web Access)、EWS(Exchange Web Services)、ActiveSync 和 MAPI over HTTP 等客户端访问协议。
Unified Messaging(统一消息) 提供语音邮件和传真功能。
从取证角度看,Exchange 的日志分布在多个位置:
传输日志:Exchange 安装目录\TransportRoles\Logs\Hub\ProtocolLog\
协议日志:Exchange 安装目录\TransportRoles\Logs\Frontend\ProtocolLog\
邮箱审计日志:Exchange 管理中心 → 合规性管理 → 审计
邮件跟踪日志:通过 Exchange Management Shell 的 Get-MessageTrackingLog 查询
IIS 日志:%SystemDrive%\inetpub\logs\LogFiles\(OWA/EWS/ActiveSync 访问日志)
Windows 事件日志:应用程序日志、安全日志 Microsoft 365 邮件架构 Microsoft 365(原 Office 365)将邮件系统迁移至云端,其架构与本地 Exchange 有显著差异:
Exchange Online 使用微软全球数据中心基础设施,用户无法直接访问底层服务器和文件系统。所有取证操作必须通过管理门户、PowerShell 远程连接或 Microsoft Graph API 完成。
统一审计日志(Unified Audit Log,UAL) 是 Microsoft 365 最核心的取证数据源。UAL 统一记录了 Exchange Online、SharePoint Online、OneDrive、Azure AD、Teams 等服务的操作日志。在 Microsoft 365 环境中,邮件取证的第一步通常是启用和查询统一审计日志。
Microsoft Defender for Office 365 提供邮件安全网关功能,包括 Safe Attachments(沙箱附件检测)、Safe Links(恶意链接检测)和反钓鱼策略。其告警和检测日志是邮件安全取证的重要补充。
Microsoft Purview 合规中心 提供电子发现(eDiscovery)和内容搜索功能,可以跨 Exchange Online、SharePoint、Teams 等服务进行全局搜索,是邮件取证中收集证据的关键工具。
邮件安全模型和攻击面 邮件系统的攻击面可以分为以下几个层面:
协议层攻击:SMTP 伪造、STARTTLS 降级、SMTP 中继滥用
认证层攻击:凭据窃取、OAuth 令牌滥用、MFA 绕过
内容层攻击:钓鱼邮件、恶意附件、恶意链接
应用层攻击:OWA 漏洞利用、EWS API 滥用、SSRF
持久化攻击:Inbox Rule、Transport Rule、邮箱委托、邮件转发
数据层攻击:邮箱数据导出、PST 文件窃取、邮件规则篡改 在实际入侵事件中,攻击者往往组合使用多种攻击手段。例如:先通过钓鱼邮件窃取用户凭据,然后使用窃取的凭据通过 EWS API 在目标邮箱中创建 Inbox Rule 实现持久化,同时利用邮箱委托权限横向访问其他高管邮箱。
0x02 邮件头深度分析 邮件头(Email Header)是邮件系统取证的基础数据源。每封邮件都包含一组标准化的头部字段,记录了邮件的元数据信息。
邮件头结构 一封典型邮件的头部包含以下关键字段:
From: "财务部" <finance@company-corp.com>
To: admin@company.com
Subject: =?UTF-8?B?6LSj5L2d6ZmE5rWP6K+V5L+h5oGv77yIMjAyNuacn+a1j+atgu+8iQ==?=
Message-ID: <CA+HVWsN5pDqFg9rZx3mOcT@company-corp.com>
Date: Mon, 30 Jun 2026 08:30:15 +0800
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_Part_001"
X-Mailer: Microsoft Outlook 16.0
X-Originating-IP: [198.51.100.23]
Authentication-Results: mx.company.com;
dkim=fail header.d=company-corp.com;
spf=fail (domain of finance@company-corp.com does not designate 198.51.100.23 as permitted sender);
dmarc=fail action=none header.from=company-corp.com From 字段 是最常被伪造的字段。显示名称(Display Name)可以包含任意 Unicode 字符,攻击者经常利用这一点进行显示名欺骗。例如,将显示名称设置为"财务部",实际发件人地址却是外部域名。取证时必须区分显示名称和实际邮件地址。
Received 字段 是邮件头中取证价值最高的字段,每经过一个 MTA 都会追加一条 Received 记录,形成邮件的传输路径。
Message-ID 字段 是每封邮件的全局唯一标识符,由生成该邮件的 MTA 分配。Message-ID 的格式通常为 <唯一标识@域名>,取证中用于精确追踪特定邮件。
X-Originating-IP 字段 记录了发件人的原始 IP 地址。该字段由 Outlook Web Access 或邮件服务器添加,但并非所有邮件系统都包含此字段。
Authentication-Results 字段 记录了 SPF、DKIM 和 DMARC 的验证结果,是判断邮件是否经过授权发送的关键证据。
Received 头追溯邮件路径 Received 头是邮件头中最重要的取证字段。邮件在传输过程中,每经过一个 MTA 都会在邮件头顶部追加一条 Received 记录。因此,最底部的 Received 头对应离发件人最近的 MTA,最顶部的 Received 头对应离收件人最近的 MTA 。
一个典型的 Received 头追溯示例:
Received: from mail.company-corp.com (unknown [198.51.100.23])
by mx.company.com with ESMTP id a1b2c3d4
for <admin@company.com>; Mon, 30 Jun 2026 08:30:16 +0800 (CST)
Received: from company-corp.com (localhost [127.0.0.1])
by mail.company-corp.com (Postfix) with ESMTP id x1y2z3
for <admin@company.com>; Mon, 30 Jun 2026 08:30:15 +0800 从下往上解读:
发件人客户端通过 localhost(127.0.0.1)连接到 mail.company-corp.com 的 Postfix MTA Postfix MTA 将邮件中继到收件方的 mx.company.com 源 IP 为 198.51.100.23,即发件方 MTA 的外部 IP 通过 Received 头可以还原邮件的完整传输路径,定位邮件的真实来源。在反钓鱼取证中,逐层分析 Received 头可以发现:
邮件是否来自预期的邮件服务器 中继路径中是否存在异常节点 IP 地址与域名解析是否一致 各节点之间的时间差是否合理 邮件头时间线重建 邮件头中的时间戳是重建事件时间线的关键。一封邮件可能包含多个时间字段,需要进行交叉比对:
Date: Mon, 30 Jun 2026 08:30:15 +0800 ← 发件人客户端声称的发送时间
Received: from ... Mon, 30 Jun 2026 08:30:16 +0800 ← 第一个 MTA 的接收时间
Received: from ... Mon, 30 Jun 2026 08:30:18 +0800 ← 第二个 MTA 的接收时间 在正常情况下,各节点之间的时间差应该在几秒到几十秒之间。如果出现以下异常,需要重点关注:
时间倒置 :后面的 Received 时间早于前面的 Received 时间,可能表示时钟不同步或邮件被篡改时间跨度异常大 :两个节点之间的时间差超过几分钟,可能表示邮件被队列延迟或被网关拦截后重新投递Date 字段与 Received 时间严重不一致 :可能表示发件人客户端的系统时间被篡改,或发件人使用了伪造的 Date 字段邮件头伪造检测 邮件头伪造是钓鱼邮件的常见特征。以下是几种常见的伪造检测方法:
发件人 IP 与域名不一致 :检查 Received 头中的 IP 地址是否能解析到发件人声称的域名。使用 nslookup 或 dig 进行反向 DNS 查询:
dig -x 198.51.100.23 +short
nslookup 198.51.100.23 Received 头格式异常 :合法的 MTA 生成的 Received 头通常有标准化的格式。如果 Received 头的格式不符合 RFC 2822 标准,或者包含异常字符,可能是手动构造的伪造邮件头。
Message-ID 域名不匹配 :检查 Message-ID 中的域名是否与发件人域名一致。攻击者可能在 Message-ID 中使用不同的域名,暴露其真实基础设施。
X-Mailer 字段伪造 :X-Mailer 字段可以被任意设置,攻击者可能伪造此字段来伪装邮件客户端类型。但在某些情况下,X-Mailer 的值可以作为辅助判断依据。
邮件头分析工具和实战 在取证实战中,以下工具可以辅助邮件头分析:
在线分析工具 :MXToolbox Header Analyzer、Google Admin Toolbox Messageheader 可以自动解析邮件头并可视化传输路径。
自定义解析脚本 :
import re
import sys
from datetime import datetime
def parse_email_header (header_file):
with open(header_file, 'r' , encoding= 'utf-8' ) as f:
content = f. read()
received_pattern = r 'Received:.*?from\s+(.+?)(?:\s+\((.+?)\))?\s*.*?by\s+(.+?)[\s;]'
received_matches = re. findall(received_pattern, content, re. DOTALL)
date_pattern = r 'Date:\s*(.+)'
date_match = re. search(date_pattern, content)
from_pattern = r '^From:\s*(.+)'
from_match = re. search(from_pattern, content, re. MULTILINE)
msgid_pattern = r 'Message-ID:\s*(<.*?>)'
msgid_match = re. search(msgid_pattern, content)
auth_pattern = r 'Authentication-Results:(.*?)(?=\n\S|\Z)'
auth_match = re. search(auth_pattern, content, re. DOTALL)
print("=" * 60 )
print("邮件头分析报告" )
print("=" * 60 )
if from_match:
print(f " \n 发件人: { from_match. group(1 ). strip()} " )
if date_match:
print(f "发件时间: { date_match. group(1 ). strip()} " )
if msgid_match:
print(f "Message-ID: { msgid_match. group(1 )} " )
print(f " \n 传输路径(共 { len(received_matches)} 跳):" )
print("-" * 40 )
for i, match in enumerate(received_matches):
print(f " [ { i+ 1 } ] From: { match[0 ]} " )
if match [1 ]:
print(f " 备注: { match[1 ]} " )
print(f " By: { match[2 ]} " )
if auth_match:
auth_result = auth_match. group(1 ). strip()
print(f " \n 认证结果:" )
print("-" * 40 )
spf_result = re. search(r 'spf=(\w+)' , auth_result)
dkim_result = re. search(r 'dkim=(\w+)' , auth_result)
dmarc_result = re. search(r 'dmarc=(\w+)' , auth_result)
if spf_result:
print(f " SPF: { spf_result. group(1 ). upper()} " )
if dkim_result:
print(f " DKIM: { dkim_result. group(1 ). upper()} " )
if dmarc_result:
print(f " DMARC: { dmarc_result. group(1 ). upper()} " )
print(" \n " + "=" * 60 )
if __name__ == "__main__" :
if len(sys. argv) < 2 :
print(f "用法: python { sys. argv[0 ]} <邮件头文件>" )
sys. exit(1 )
parse_email_header(sys. argv[1 ]) 0x03 Exchange 日志分析 Exchange Server 产生多种类型的日志,每种日志都有独特的取证价值。
Exchange 日志类型 传输日志(Transport Logs) 记录邮件在 Exchange 传输管道中的流转过程,包括连接日志、消息跟踪日志和协议日志。
协议日志(Protocol Logs) 记录 SMTP 会话的详细交互过程,包括 SMTP 命令序列、认证过程和传输内容。
审计日志(Audit Logs) 记录管理员和用户在邮箱上的操作,包括邮件访问、邮件移动、邮件删除和规则修改等。
IIS 日志 记录通过 Web 协议(OWA、EWS、ActiveSync、PowerShell)访问 Exchange 的请求。
Windows 事件日志 记录 Exchange 服务的启动/停止事件、认证事件和错误事件。
Exchange 传输日志分析 Exchange 的传输日志位于 Exchange 安装目录\TransportRoles\Logs\ 下,包括以下子目录:
\TransportRoles\Logs\Hub\ProtocolLog\SmtpSend\ ← SMTP 发送协议日志
\TransportRoles\Logs\Hub\ProtocolLog\SmtpReceive\ ← SMTP 接收协议日志
\TransportRoles\Logs\Frontend\ProtocolLog\SmtpReceive\ ← 前端 SMTP 接收日志
\TransportRoles\Logs\MailSubmissionService\ ← 邮件提交服务日志
\TransportRoles\Logs\Delivery\ ← 邮件投递日志
\TransportRoles\Logs\RetryQueueItems\ ← 重试队列日志 SMTP 协议日志的格式为固定的字段序列:
#Fields: time-localtime s-ip s-port s-hostname s-ip s-port s-connector-id s-remote-address s-remote端口
2026-06-30T08:30:15.123Z 10.0.0.1 25 mail01.company.com 10.0.0.1 25 - 198.51.100.23 54321 通过分析 SMTP 协议日志,可以提取以下关键信息:
每封邮件的 SMTP 会话详情(EHLO/HELO、MAIL FROM、RCPT TO) 邮件大小和附件大小 SMTP 认证用户名 传输时间和延迟 连接来源 IP 和目标 IP SMTP 响应代码(250 成功、550 拒绝等) Exchange 协议日志分析 使用 PowerShell 从 Exchange 传输日志中提取关键信息:
$logPath = "C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\Hub\ProtocolLog\SmtpReceive"
$targetDate = (Get-Date).AddDays(-1 ).ToString("yyyyMMdd" )
Get-ChildItem -Path $logPath -Filter "* $targetDate*" | ForEach-Object {
$content = Get-Content $_.FullName
foreach ($line in $content) {
if ($line -match "MAIL FROM:.*?<(.*?)>" ) {
[PSCustomObject ]@{
LogFile = $_.Name
Sender = $Matches[1 ]
Timestamp = ($line -split '\s+' )[0 ]
}
}
}
} | Sort-Object Timestamp | Format-Table -AutoSize Exchange 审计日志分析 Exchange 提供两种审计模式:
邮箱审计(Mailbox Audit) 记录非邮箱所有者对邮箱的操作。默认情况下,管理员访问其他用户邮箱、委托用户访问邮箱的操作会被审计。审计事件类型包括:
MailLogin ← 邮箱登录
MailSend ← 发送邮件
MailCreate ← 创建邮件
MailMove ← 移动邮件
MailHardDelete ← 永久删除邮件
MailSoftDelete ← 软删除邮件(移到已删除邮件)
MailUpdate ← 更新邮件(标记已读、修改标记等)
MailFolderBind ← 访问邮件文件夹 使用 PowerShell 查询邮箱审计日志:
$StartDate = (Get-Date).AddDays(-7 )
$EndDate = Get-Date
Search-MailboxAuditLog -Identity "admin@company.com" `
-StartDate $StartDate `
-EndDate $EndDate `
-LogonTypes Delegate `
-ShowDetails |
Select-Object LogonUserDisplayName, Operation, ItemSubject, LastAccessed, OperationDate |
Sort-Object OperationDate -Descending |
Format-Table -AutoSize 管理员审计(Administrator Audit) 记录管理员在 Exchange Management Shell 或 Exchange 管理中心执行的配置更改操作。
异常操作检测 在 Exchange 日志中,以下异常模式需要重点关注:
非工作时间的邮箱登录(特别是通过 EWS 或 ActiveSync 协议) 短时间内大量邮件被删除或移动到"已删除邮件"文件夹 新增的 Inbox Rule 将邮件自动转发到外部地址 管理员对非授权邮箱执行搜索或导出操作 非预期的邮箱委托权限变更 SMTP 认证日志中的异常用户名或来源 IP 0x04 Microsoft 365 审计日志分析 Microsoft 365 统一审计日志 Microsoft 365 统一审计日志(Unified Audit Log,UAL)是 Microsoft 365 环境中最重要的取证数据源。UAL 汇集了来自 Exchange Online、SharePoint Online、OneDrive、Azure AD、Teams、Power BI 等 50 多个服务的操作日志。
启用统一审计日志:
Set-AdminAuditLogConfig -UnifiedAuditLogIngestionEnabled $true 注意:审计日志默认可能未启用,且日志保留时间根据许可证类型不同(90 天到 10 年)。取证时应第一时间确认审计日志的启用状态和保留策略。
Exchange Online 审计日志 Exchange Online 的审计日志可以通过多种方式查询:
使用 Search-UnifiedAuditLog cmdlet :
$startDate = (Get-Date).AddDays(-30 )
$endDate = Get-Date
Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate `
-Operations "MailboxLogin" ,"Send" ,"SearchQueryInitiated" `
-RecordType ExchangeItem |
Select-Object CreationDate, UserIds, Operations, AuditData |
Format-Table -AutoSize 使用 Microsoft Graph API :
import requests
TENANT_ID = "your-tenant-id"
CLIENT_ID = "your-client-id"
CLIENT_SECRET = "your-client-secret"
token_url = f "https://login.microsoftonline.com/ { TENANT_ID} /oauth2/v2.0/token"
token_data = {
"grant_type" : "client_credentials" ,
"client_id" : CLIENT_ID,
"client_secret" : CLIENT_SECRET,
"scope" : "https://graph.microsoft.com/.default"
}
token_resp = requests. post(token_url, data= token_data)
access_token = token_resp. json()["access_token" ]
headers = {"Authorization" : f "Bearer { access_token} " }
audit_url = "https://graph.microsoft.com/v1.0/security/auditLog/auditLogs"
response = requests. get(audit_url, headers= headers)
logs = response. json(). get("value" , [])
for log in logs:
print(f "时间: { log. get('activityDateTime' )} " )
print(f "操作: { log. get('activityDisplayName' )} " )
print(f "用户: { log. get('initiatedBy' , {}). get('user' , {}). get('userPrincipalName' )} " )
print("---" ) 邮件操作审计 Exchange Online 审计日志记录的邮件操作事件包括:
Send ← 用户发送邮件
Create ← 创建邮件草稿
Move ← 移动邮件到其他文件夹
Copy ← 复制邮件
SoftDelete ← 软删除邮件(移到已删除邮件)
HardDelete ← 永久删除邮件
SearchQueryInitiated ← 在邮箱中执行搜索
ApplyMailboxPolicy ← 应用邮箱策略
AddMailboxPermissions ← 添加邮箱权限
UpdateInboxRules ← 修改收件箱规则 在安全事件调查中,以下操作模式需要高度关注:
SoftDelete 或 HardDelete 批量出现,可能表示攻击者在清除入侵痕迹UpdateInboxRules 创建了将邮件转发到外部地址的规则AddMailboxPermissions 为非授权用户添加了完全访问权限SearchQueryInitiated 中包含敏感关键词(如"password"、“confidential”、“salary”)邮箱登录审计 Azure AD 审计日志和 Exchange Online 登录日志共同构成邮箱登录审计的完整视图:
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-7 ) -EndDate (Get-Date) `
-Operations "MailboxLogin" |
ForEach-Object {
$data = $_.AuditData | ConvertFrom-Json
[PSCustomObject ]@{
时间 = $_.CreationDate
用户 = $_.UserIds
操作 = $data.Operation
IP地址 = $data.ClientIPAddress
客户端 = $data.ClientInfoString
协议 = $data.AuthMethod
}
} |
Sort-Object 时间 -Descending |
Format-Table -AutoSize 在检测异常邮箱登录时,需要关注以下维度:
地理位置异常 :用户从未登录过的国家或城市发起登录时间异常 :在非工作时间或非正常活跃时段登录客户端异常 :使用非正常的邮件客户端或协议(如正常使用 Outlook 的用户突然使用 IMAP/POP3 登录)IP 异常 :来自已知恶意 IP、VPN 出口或 Tor 节点的登录异常操作检测 以下 PowerShell 脚本用于检测 Microsoft 365 中的高风险邮件操作:
$days = 30
$startDate = (Get-Date).AddDays(-$days)
$endDate = Get-Date
$highRiskOps = @(
"UpdateInboxRules" ,
"AddMailboxPermissions" ,
"AddFolderPermissions" ,
"ApplyMailboxPolicy" ,
"New-InboxRule" ,
"Set-InboxRule"
)
$results = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate `
-Operations $highRiskOps -ResultSize 5000
$report = $results | ForEach-Object {
$audit = $_.AuditData | ConvertFrom-Json
[PSCustomObject ]@{
时间 = $_.CreationDate
用户 = $_.UserIds
操作 = $_.Operations
目标邮箱 = $audit.MailboxOwnerUPN
详情 = $audit.OperationProperties
IP地址 = $audit.ClientIPAddress
}
}
$report | Group-Object 操作 | Sort-Object Count -Descending | Format-Table Count, Name -AutoSize
$report | Format-Table -AutoSize 0x05 邮件附件分析 邮件附件是恶意软件投递的首要载体之一。根据 Proofpoint 2026 年报告,58% 的恶意邮件通过附件投递恶意载荷。
常见恶意附件类型 宏文档(.docm、.xlsm、.pptm) 是最常见的恶意附件类型。攻击者在文档中嵌入 VBA 宏代码,当用户启用宏后,宏代码自动执行下载并运行恶意载荷。典型的宏执行链为:
WINWORD.EXE → 启用宏 → VBA 宏执行 → cmd.exe /c powershell → 下载远程 Payload → 执行 可执行文件 经过伪装后投递。常见手段包括:双扩展名(invoice.pdf.exe)、利用 Windows 默认隐藏已知文件扩展名的特性、使用自定义图标伪装成 PDF 或 Word 文档。
脚本文件(.js、.vbs、.wsf、.ps1) 常被用于绕过基于文件扩展名的检测。攻击者将脚本文件封装在压缩包中(通常是 ZIP 或 ISO),利用 Windows 脚本宿主(wscript.exe 或 cscript.exe)执行。
压缩包(.zip、.rar、.7z、.iso、.img) 作为恶意载荷的容器,用于绕过邮件网关的内容扫描。多层嵌套压缩(zip 中嵌套 zip)是常见的规避手段。ISO 和 IMG 镜像文件是近年来新兴的投递载体,因为它们可以绕过 Mark of the Web(MotW)标记。
HTA 文件(.hta) 通过 Outlook 附件投递后,被 Internet Explorer/MSHTA 引擎执行,可以下载并运行任意恶意代码。
附件沙箱分析 沙箱分析是判断邮件附件恶意性的核心手段。以下是在沙箱环境中分析邮件附件的流程:
1. 提取附件原始文件
2. 计算文件哈希(MD5、SHA1、SHA256)
3. 提交到本地沙箱(Cuckoo、CAPE)或在线沙箱(VirusTotal、Any.Run)
4. 观察沙箱中的行为:
- 进程创建链
- 文件操作(释放文件、修改文件)
- 注册表操作
- 网络连接(C2 通信、下载)
- API 调用序列
5. 提取 IOC(域名、IP、文件路径、注册表键值) 附件静态分析 对于无法动态运行的附件样本,静态分析可以提取关键特征:
import hashlib
import os
import struct
def analyze_attachment (filepath):
with open(filepath, 'rb' ) as f:
data = f. read()
md5 = hashlib. md5(data). hexdigest()
sha1 = hashlib. sha1(data). hexdigest()
sha256 = hashlib. sha256(data). hexdigest()
print(f "文件: { os. path. basename(filepath)} " )
print(f "大小: { len(data)} bytes ( { len(data)/ 1024 : .1f } KB)" )
print(f "MD5: { md5} " )
print(f "SHA1: { sha1} " )
print(f "SHA256: { sha256} " )
magic_bytes = data[:4 ]
if magic_bytes == b 'PK \x03\x04 ' :
print("文件类型: ZIP 压缩包" )
import zipfile
import io
zf = zipfile. ZipFile(io. BytesIO(data))
print(f "包含文件 ( { len(zf. namelist())} 个):" )
for name in zf. namelist():
info = zf. getinfo(name)
print(f " { name} ( { info. file_size} bytes)" )
elif magic_bytes[:2 ] == b ' \xd0\xcf ' :
print("文件类型: OLE 文档(可能是 .doc/.xls)" )
elif data[:4 ] == b ' \x50\x4b\x03\x04 ' :
print("文件类型: OOXML 文档(.docx/.xlsx)" )
elif data[:2 ] == b 'MZ' :
print("文件类型: PE 可执行文件" )
pe_offset = struct. unpack_from('<I' , data, 0x3C )[0 ]
print(f "PE 签名偏移: 0x { pe_offset: X } " )
urls = []
import re
url_pattern = rb 'https?://[^\s<>" \' ]+'
for match in re. finditer(url_pattern, data):
url = match . group(). decode('utf-8' , errors= 'ignore' )
if url not in urls:
urls. append(url)
if urls:
print(f " \n 提取到的 URL ( { len(urls)} 个):" )
for url in urls:
print(f " { url} " )
ip_pattern = rb '\b(?:[0-9]{1,3}\.) {3} [0-9]{1,3}\b'
ips = []
for match in re. finditer(ip_pattern, data):
ip = match . group(). decode('utf-8' )
if ip not in ips:
ips. append(ip)
if ips:
print(f " \n 提取到的 IP ( { len(ips)} 个):" )
for ip in ips:
print(f " { ip} " ) 附件动态分析 动态分析在受控环境中执行附件样本,捕获其运行时行为。关键的动态分析维度包括:
进程树 :观察附件执行后创建的子进程链,识别 LOLBin(如 certutil、mshta、rundll32)的使用网络流量 :捕获 DNS 查询和 HTTP/HTTPS 请求,识别 C2 通信和载荷下载文件系统操作 :监控释放的文件路径、文件名和内容注册表操作 :观察持久化机制(自启动项、服务创建等)内存操作 :检测代码注入、进程镂空等规避技术取证特征提取 从邮件附件分析中提取的取证特征可以用于威胁情报关联和后续狩猎:
文件哈希:SHA256 哈希用于在 VirusTotal、MISP 等平台查询
C2 域名:用于 DNS 日志分析和网络流量关联
C2 IP:用于防火墙日志和代理日志搜索
文件路径:恶意软件释放的文件路径可用于终端检测
注册表键值:持久化机制涉及的注册表路径
User-Agent:HTTP 请求中的 User-Agent 字符串
JA3/JA3S 指纹:TLS 握手指纹用于 C2 通信识别 0x06 钓鱼邮件取证 钓鱼邮件特征分析 钓鱼邮件通常具有以下可识别特征,在取证分析中需要系统性地检查:
发件人特征 :显示名称与实际邮件地址不一致、使用与目标组织相似的域名(同形异义字攻击)、发件人域名是新注册的(WHOIS 注册时间小于 30 天)、SPF/DKIM/DMARC 验证失败。
内容特征 :紧迫性语言(“立即处理”、“账户将被冻结”)、要求提供凭据或敏感信息、包含伪装的超链接(显示文本与实际 URL 不一致)、语法或拼写错误、非正常的邮件格式或排版。
技术特征 :邮件头中包含异常的 Received 路径、Authentication-Results 显示认证失败、邮件编码异常、隐藏的 HTML 元素或 JavaScript 代码。
钓鱼邮件溯源方法 邮件溯源是将钓鱼邮件与攻击者基础设施关联的过程:
1. 邮件头溯源:
- 提取 Received 头中的源 IP
- 反向 DNS 查询确认 IP 归属
- 查询 IP 的威胁情报(VirusTotal、AbuseIPDB、OTX)
2. 域名溯源:
- WHOIS 查询发件人域名的注册信息
- 检查域名注册时间和注册商
- 查询域名的历史解析记录(PassiveDNS)
3. URL 溯源:
- 解析邮件中 URL 的真实目标地址
- 跟踪 URL 重定向链
- 查询 URL 托管平台和证书信息
4. 附件溯源:
- 计算文件哈希查询威胁情报
- 分析文件中的 C2 指标
- 通过数字签名或编译时间关联攻击者 钓鱼 URL 分析 钓鱼 URL 通常使用多种混淆技术来规避检测:
1. URL 编码混淆:
http://example.com/login?redirect=http%3A%2F%2Fevil.com%2Fsteal
2. 短链接跳转:
http://bit.ly/3xYzABc → http://evil.com/phish
3. 字符串相似度攻击:
http://micrоsoft.com(使用西里尔字母 "о" 替代拉丁字母 "o")
4. 子域名伪装:
http://login.microsoft.com.evil.com
5. IP 地址替代域名:
http://198.51.100.23/login
6. Base64 编码参数:
http://legit.com/redirect?url=aHR0cDovL2V2aWwuY29t 钓鱼邮件与 C2 关联 钓鱼邮件投递的恶意载荷通常会连接到 C2(Command & Control)服务器。通过将钓鱼邮件的技术指标与 C2 基础设施关联,可以构建完整的攻击链:
钓鱼邮件 → 恶意附件/URL → 用户执行 → C2 连接 → 横向移动 → 数据窃取
关键关联点:
- 邮件中的 URL 域名 ↔ C2 域名(同一注册者、同一 IP 段)
- 附件中的 C2 配置 ↔ 实际 C2 通信流量
- 邮件发送时间 ↔ C2 首次通信时间
- 邮件来源 IP ↔ C2 服务器 IP 钓鱼攻击时间线重建 完整的钓鱼攻击时间线应覆盖从投递到数据窃取的全过程:
T+00:00 钓鱼邮件发送到目标邮箱
T+05:00 邮件到达收件人邮箱(经过邮件网关扫描)
T+30:00 收件人打开邮件
T+31:00 收件人点击邮件中的链接 / 打开附件
T+32:00 恶意载荷执行 / 凭据提交到钓鱼页面
T+33:00 攻击者获取凭据 / 恶意软件建立 C2 连接
T+60:00 攻击者使用窃取的凭据登录邮箱
T+120:00 攻击者创建 Inbox Rule 实现邮件转发
T+240:00 攻击者访问敏感邮件和附件 0x07 邮件认证验证 — SPF/DKIM/DMARC SPF、DKIM 和 DMARC 构成邮件认证的三层防线,是判断邮件来源可信度的关键技术手段。
SPF 验证机制和分析 SPF(Sender Policy Framework)通过 DNS TXT 记录声明哪些 IP 地址被授权代表该域名发送邮件。
SPF 记录示例:
v=spf1 ip4:198.51.100.0/24 include:_spf.google.com include:spf.protection.outlook.com -all SPF 验证结果及其取证意义:
pass ← 发送 IP 在授权列表中,邮件来源可信
softfail ← 发送 IP 不在授权列表中,但域名策略较宽松,可能是配置问题
fail ← 发送 IP 不在授权列表中且策略严格,邮件来源不可信
neutral ← 域名所有者不对发送 IP 做出判断
none ← 域名未配置 SPF 记录
temperror ← SPF 查询临时失败
permerror ← SPF 记录格式错误或包含过多的 DNS 查询 在取证分析中,SPF fail 是判断钓鱼邮件的重要指标之一。但需要注意:SPF 仅验证 SMTP MAIL FROM 域名与发送 IP 的对应关系,攻击者可以通过注册相似域名来绕过 SPF 检查。
DKIM 验证机制和分析 DKIM(DomainKeys Identified Mail)通过在邮件头部插入数字签名,验证邮件在传输过程中是否被篡改。发件人使用私钥对邮件特定头部字段和正文进行签名,收件人使用发件人域名的 DNS TXT 记录中的公钥进行验证。
DKIM 签名头示例:
DKIM-Signature: v=1; a=rsa-sha256; d=company-corp.com; s=selector1;
c=relaxed/relaxed;
h=from:to:subject:date:message-id:mime-version:content-type;
bh=abc123...;
b=xyz789... DKIM 验证结果:
pass ← 签名验证通过,邮件未被篡改
fail ← 签名验证失败,邮件可能被篡改或来自未授权的发送者
none ← 邮件未包含 DKIM 签名
temperror ← DKIM 查询临时失败
permerror ← DKIM 记录格式错误 DKIM 的取证价值在于:即使攻击者注册了相似域名并通过了 SPF 验证,如果他们没有目标域名的 DKIM 私钥,邮件的 DKIM 签名将无法通过验证。
DMARC 验证机制和分析 DMARC(Domain-based Message Authentication, Reporting & Conformance)基于 SPF 和 DKIM 的验证结果,定义域名所有者对认证失败邮件的处理策略。
DMARC 策略示例:
_dmarc.company-corp.com TXT "v=DMARC1; p=reject; rua=mailto:dmarc-agg@company-corp.com; ruf=mailto:dmarc-forensics@company-corp.com; pct=100" DMARC 策略级别:
none ← 不对邮件采取任何处理动作,仅生成报告(用于监控阶段)
quarantine ← 将认证失败的邮件标记为可疑或放入垃圾邮件文件夹
reject ← 直接拒绝认证失败的邮件,不投递到收件人邮箱 DMARC 对齐验证是其核心特性。DMARC 要求 RFC 5322.From(邮件头中的显示发件人地址)的域名与 SPF 验证的 MAIL FROM 域名或 DKIM 签名的 d= 域名对齐:
SPF 对齐:RFC5322.From 域名 == MAIL FROM 域名(宽松模式允许子域名匹配)
DKIM 对齐:RFC5322.From 域名 == DKIM 签名的 d= 域名(宽松模式允许子域名匹配) 邮件认证失败的取证意义 在邮件安全事件调查中,邮件认证结果是判断邮件真实性的关键证据:
SPF=pass + DKIM=pass + DMARC=pass
→ 邮件通过所有认证,来源可信度高
SPF=fail + DKIM=fail + DMARC=fail
→ 邮件未通过任何认证,高度可疑的伪造邮件
SPF=pass + DKIM=fail + DMARC=fail
→ 发送 IP 被授权,但邮件内容可能被篡改或签名不匹配
SPF=fail + DKIM=pass + DMARC=fail
→ 发送 IP 未被授权,但 DKIM 签名有效,可能是邮件转发导致的 SPF 失败 实战分析案例 以下是一个完整的邮件认证分析案例:
场景:收到一封声称来自 IT 部门的密码重置邮件
邮件头关键信息:
From: IT Support <it-support@company-security.com>
Authentication-Results:
spf=fail (domain of it-support@company-security.com does not designate 10.0.0.1 as permitted sender)
dkim=fail (no key found for company-security.com in DNS)
dmarc=fail (dmarc=fail header.from=company-security.com)
分析步骤:
1. SPF 分析:
- MAIL FROM 域名: company-security.com
- 发送 IP: 10.0.0.1(来自公司内部网络,但域名不属于公司)
- 结果: FAIL — 发送 IP 未被授权代表该域名发送
2. DKIM 分析:
- DKIM 签名域: company-security.com
- DNS 中未找到该域名的 DKIM 公钥
- 结果: FAIL — 域名未配置 DKIM
3. DMARC 分析:
- RFC5322.From 域名: company-security.com
- SPF 和 DKIM 均失败
- 结果: FAIL
4. 域名分析:
- company-security.com 域名注册时间: 2026-06-28(2 天前)
- 注册商: 某境外注册商
- 与合法域名 company.com 仅差一个 "-" 和 "security" 后缀
结论:这是一封高度可疑的钓鱼邮件,发件人通过新注册的相似域名发送,企图仿冒 IT 部门诱导用户重置密码。 0x08 邮件网关日志分析 邮件网关架构和日志格式 邮件网关部署在邮件系统的边界,承担反垃圾邮件、反病毒、内容过滤和 DLP 功能。常见的邮件网关产品包括 Proofpoint Email Protection、Mimecast、Barracuda Email Security Gateway、Symantec Mail Security 和 Microsoft Defender for Office 365。
邮件网关日志通常包含以下字段:
时间戳 ← 邮件到达网关的时间
来源 IP ← 发送方 MTA 的 IP 地址
发件人 ← MAIL FROM 地址
收件人 ← RCPT TO 地址
邮件大小 ← 邮件总大小(含附件)
附件名 ← 附件文件名
附件类型 ← MIME 类型
附件大小 ← 单个附件的大小
垃圾邮件分数 ← 反垃圾邮件引擎的评分
病毒检测 ← 反病毒引擎的检测结果
URL 检测 ← URL 信誉检查结果
内容过滤 ← DLP 规则的匹配结果
处理动作 ← 放行 / 隔离 / 退信 / 拒绝
SMTP 响应码 ← 网关对邮件的处理响应 邮件网关拦截日志分析 邮件网关拦截日志是识别攻击尝试的重要来源。以下 PowerShell 脚本用于分析网关拦截日志:
$logPath = "C:\Proofpoint\Logs\maillog.csv"
$startDate = (Get-Date).AddDays(-7 )
$mailLogs = Import-Csv $logPath | Where-Object {
[datetime ]$_.Timestamp -ge $startDate
}
$blocked = $mailLogs | Where-Object { $_.Action -ne "Deliver" }
$blocked | Group-Object Reason | Sort-Object Count -Descending | Format-Table Count, Name -AutoSize
$malicious = $mailLogs | Where-Object { $_.VirusDetected -eq "True" }
$malicious | Select-Object Timestamp, SourceIP, Sender, Recipient, VirusName, FileName |
Sort-Object Timestamp -Descending | Format-Table -AutoSize
$phishing = $mailLogs | Where-Object { $_.PhishingScore -gt 0.8 }
$phishing | Select-Object Timestamp, SourceIP, Sender, Recipient, PhishingScore, URLs |
Sort-Object PhishingScore -Descending | Format-Table -AutoSize 邮件网关威胁情报关联 将邮件网关日志与威胁情报平台关联,可以提升检测准确率:
1. IP 信誉查询:
- VirusTotal:查询发送 IP 的历史恶意报告
- AbuseIPDB:查询 IP 的滥用历史和举报次数
- GreyNoise:查询 IP 是否属于互联网扫描器
2. 域名信誉查询:
- WHOIS 查询:检查域名注册时间和注册者
- PassiveTotal:查询域名的历史解析记录
- URLhaus:查询域名是否与已知恶意软件分发相关
3. 附件哈希查询:
- VirusTotal:查询文件哈希的检测结果
- Hybrid Analysis:查询沙箱分析结果
- MalwareBazaar:查询样本分类和家族信息
4. URL 信誉查询:
- Google Safe Browsing:查询 URL 的安全状态
- PhishTank:查询 URL 是否为已知钓鱼页面
- URLhaus:查询 URL 是否与恶意软件分发相关 邮件网关绕过检测 攻击者使用多种技术来绕过邮件网关的检测:
图片化邮件 :将钓鱼内容渲染为图片,绕过基于文本的内容检测。取证中需要对邮件中的图片进行 OCR 分析。
密码保护的压缩包 :使用密码保护的 ZIP/RAR 文件投递恶意附件,密码通过邮件正文或另一个渠道传递。邮件网关通常无法扫描加密的压缩包内容。
合法云服务投递 :使用 OneDrive、Google Drive、SharePoint 等合法云服务托管恶意文件,在邮件中仅包含云服务链接。这使得基于 URL 信誉的检测失效。
延迟投递 :在钓鱼邮件中嵌入延迟执行的 JavaScript 代码,或使用时间锁机制,使得沙箱分析时无法触发恶意行为。
信誉域名预热 :提前数周或数月注册域名并发送正常邮件,建立域名信誉后再发起钓鱼攻击。
检测网关绕过的日志分析策略:
1. 监控密码保护压缩包的投递
2. 分析邮件中嵌入的 Base64 编码内容
3. 检查短链接和重定向 URL 的最终目标
4. 关注新注册域名(<30 天)的邮件投递量
5. 分析同一发件人在不同时段的邮件内容差异
6. 检查 ISO/IMG 镜像文件的投递趋势 0x09 邮件系统持久化检测 攻击者在获取邮箱访问权限后,会建立多种持久化机制以维持长期访问。
邮件规则持久化 Inbox Rule(收件箱规则) 是最常见的邮件持久化方式。攻击者在受害者的邮箱中创建自动规则,实现邮件转发、删除或隐藏:
常见恶意 Inbox Rule 类型:
1. 自动转发规则:将包含特定关键词(如"发票"、"合同"、"密码")的邮件自动转发到攻击者邮箱
2. 自动删除规则:将包含"安全"、"告警"、"可疑登录"等关键词的邮件自动移到"已删除邮件"或永久删除
3. 自动移动规则:将邮件移动到不常访问的文件夹,减少被发现的概率
4. 自动标记规则:将钓鱼邮件标记为"已读"或"低重要性",降低收件人的警惕性 检测 Inbox Rule 持久化:
Get-InboxRule -Mailbox "victim@company.com" |
Select-Object Name, Description, Enabled, From, SubjectContainsWords,
ForwardTo, ForwardAsAttachmentTo, RedirectTo, MoveToFolder,
DeleteMessage, StopProcessingRules |
Format-Table -AutoSize 使用 Microsoft Graph API 检测 Inbox Rule:
import requests
def check_inbox_rules (access_token, user_id):
headers = {"Authorization" : f "Bearer { access_token} " }
url = f "https://graph.microsoft.com/v1.0/users/ { user_id} /mailFolders/inbox/messageRules"
response = requests. get(url, headers= headers)
rules = response. json(). get("value" , [])
suspicious_patterns = []
for rule in rules:
flags = []
if rule. get("forwardTo" ) or rule. get("forwardAsAttachmentTo" ):
flags. append("邮件转发" )
suspicious_patterns. append(rule)
if rule. get("redirectTo" ):
flags. append("邮件重定向" )
suspicious_patterns. append(rule)
if rule. get("deleteMessage" ):
flags. append("邮件删除" )
suspicious_patterns. append(rule)
if rule. get("stopProcessingRules" ):
flags. append("阻止后续规则" )
suspicious_patterns. append(rule)
if flags:
print(f "[!] 可疑规则: { rule. get('displayName' )} " )
print(f " 标记: { ', ' . join(flags)} " )
print(f " 条件: { rule. get('conditions' , {})} " )
print(f " 启用: { rule. get('isEnabled' , False )} " )
print()
return suspicious_patterns 邮箱委托持久化 攻击者通过 Exchange 管理工具或 PowerShell 为自己的账户添加对受害者邮箱的委托访问权限:
完全访问权限(FullAccess):允许访问邮箱中的所有邮件,但不会自动发送邮件
代表发送权限(SendAs):允许以受害者身份发送邮件
代理发送权限(SendOnBehalf):允许以"XXX 代表 YYY"的身份发送邮件 检测邮箱委托权限:
Get-MailboxPermission -Identity "victim@company.com" |
Where-Object {
$_.AccessRights -match "FullAccess" -and
$_.User -notmatch "NT AUTHORITY\\SYSTEM|Exchange Servers|Organization Management"
} |
Select-Object User, AccessRights, IsInherited, Deny |
Format-Table -AutoSize
Get-RecipientPermission -Identity "victim@company.com" |
Where-Object { $_.Trustee -ne "NT AUTHORITY\SELF" } |
Select-Object Trustee, AccessRights, Deny |
Format-Table -AutoSize 邮件转发持久化 Exchange Online 支持设置邮箱级别的邮件转发规则(不同于 Inbox Rule),将所有收到的邮件自动转发到外部地址:
Get-Mailbox -Identity "victim@company.com" |
Select-Object Name, ForwardingSmtpAddress, DeliverToMailboxAndForward |
Format-Table -AutoSize 如果 ForwardingSmtpAddress 不为空且 DeliverToMailboxAndForward 为 True,说明该邮箱的邮件被自动转发到指定地址,同时仍在原始邮箱中保留副本。
邮件系统后门检测 除了上述持久化方式外,还需要检测以下邮件系统后门:
Transport Rule 后门 :管理员级别的攻击者可以在 Exchange 传输管道中创建规则,对特定邮件进行自动处理。检测方法:
Get-TransportRule | Select-Object Name, State, Priority, Conditions, Actions | Format-Table -AutoSize OAuth 应用后门 :攻击者在 Azure AD 中注册恶意 OAuth 应用,获取对邮箱的持续访问权限:
Get-MgServicePrincipal -Filter "tags/any(t:t eq 'WindowsAzureActiveDirectoryIntegratedApp')" |
Select-Object DisplayName, AppId, CreatedDateTime, VerifiedPublisher |
Sort-Object CreatedDateTime -Descending |
Format-Table -AutoSize 恶意加载项或插件 :攻击者可能在 Outlook 中安装恶意 COM 加载项,实现邮件内容窃取。
0x10 证据强度分层 邮件系统取证的证据需要按可信度和确认程度进行分层,以指导后续调查和响应决策。
确认恶意(Confirmation Level) 以下证据可以确认邮件或邮件操作的恶意性:
■ 邮件头中 SPF=fail + DKIM=fail + DMARC=fail,且发件人域名是新注册的相似域名
■ 邮件附件在多个沙箱中均被检测为恶意,且文件哈希匹配已知恶意软件家族
■ 邮件中的 URL 经过多级跳转后指向已知的钓鱼页面或恶意下载站点
■ 邮件中嵌入的 VBA 宏代码包含典型的恶意行为模式(下载器、凭证窃取器)
■ Inbox Rule 将邮件自动转发到已知恶意外部邮箱
■ 邮箱委托权限被授予已知攻击者账户
■ 邮件发送时间与已知攻击活动的时间窗口匹配
■ 附件中提取的 C2 域名/IP 在威胁情报平台上标记为恶意 高度可疑(High Suspicion Level) 以下证据具有较高的可疑度,需要进一步验证:
△ 邮件头中 SPF=softfail 或 DKIM=fail(单项认证失败)
△ 发件人域名与目标组织域名相似但注册信息异常(新注册、隐私保护)
△ 邮件附件是加密压缩包,密码通过非邮件渠道传递
△ 邮件内容包含紧迫性语言和凭据收集意图
△ 邮件中的 URL 使用短链接或编码混淆
△ 用户在收到邮件后短时间内出现了异常的终端行为
△ 邮件发送时间在非工作时间但使用了合法的发送渠道
△ 同一发件人向多个用户发送了相似内容的邮件 需要关注(Attention Level) 以下证据需要纳入监控和持续分析:
○ 邮件中包含外部链接但未检测到明确的恶意行为
○ 发件人域名信誉较低但未确认恶意
○ 邮件网关将邮件标记为"可疑"但未拦截
○ 用户收到了来自合法云服务的异常共享链接
○ 邮件中的附件虽然通过了安全扫描但文件格式罕见
○ 邮件的 DKIM 签名通过但 DMARC 策略为 none
○ 同一来源 IP 在短时间内发送了大量相似邮件 0x11 公开案例中的邮件取证 案例一:APT29 — Microsoft 365 钓鱼攻击链 APT29(又名 Cozy Bear、NOBELIUM)是俄罗斯对外情报局(SVR)下属的高级威胁组织。2020-2021 年间,该组织针对多个政府机构和企业发起了大规模的 Microsoft 365 钓鱼攻击。
攻击链概述 :
1. 初始投递:向目标发送钓鱼邮件,邮件伪装成密码过期提醒
2. 凭据窃取:钓鱼页面仿冒 Microsoft 365 登录页面,收集用户凭据
3. 认证方式:使用窃取的凭据通过 ActiveSync 协议建立持久访问
4. OAuth 滥用:注册恶意 OAuth 应用,获取 EWS API 的完全访问权限
5. 邮件访问:通过 EWS API 批量读取目标邮箱中的敏感邮件
6. 数据外传:将窃取的邮件数据通过 C2 通道外传 取证要点 :
钓鱼邮件使用了合法的 SMTP 服务发送,SPF 验证通过,但 DKIM 签名域与发件人域名不一致 钓鱼页面使用了 Let’s Encrypt 证书,域名在攻击前数天注册 攻击者通过 ActiveSync 协议登录,Azure AD 日志中显示了来自非预期 IP 的 ActiveSync 请求 恶意 OAuth 应用的权限范围包含 EWS.AccessAsUser.All,允许以任意用户身份访问邮箱 EWS API 调用日志显示大量 GetFolder 和 GetItem 操作,短时间内访问了数千封邮件 关键日志证据 :
Azure AD 签名日志:
- 4625 失败登录 → 4624 成功登录(凭据填充攻击模式)
- 客户端应用: Exchange ActiveSync
- 来源国家: 攻击者控制的 VPN 出口
Microsoft 365 审计日志:
- Add OAuth2PermissionGrant(授予 OAuth 权限)
- GetFolder / GetItem(EWS API 批量读取邮件)
- New-InboxRule(创建隐蔽转发规则) 案例二:Emotet — 邮件投递与横向移动 Emotet 是全球最活跃的恶意软件即服务(MaaS)平台之一,其核心能力之一就是通过邮件进行大规模投递。
攻击链概述 :
1. 邮件投递:向目标发送伪装成发票、快递通知或催款单的钓鱼邮件
2. 附件投递:邮件包含恶意 Office 文档(宏文档)或 ZIP 压缩包
3. 宏执行:用户打开文档并启用宏,VBA 宏通过 PowerShell 下载 Emotet 载荷
4. 横向移动:Emotet 使用窃取的邮件凭据和地址簿,向受害者的联系人发送相同的钓鱼邮件
5. 二次投递:利用信任关系,来自同事的钓鱼邮件更容易被打开
6. 持续扩散:新感染的机器重复上述过程,形成链式传播 取证要点 :
Emotet 邮件通常使用被盗的真实邮件账户发送,因此 SPF/DKIM/DMARC 验证可能通过 邮件主题和内容来自被盗邮箱的历史邮件,具有高度的上下文相关性 附件通常为密码保护的 ZIP 文件,密码在邮件正文中提供(规避网关扫描) 恶意宏执行链使用 PowerShell 下载器,临时文件路径和下载 URL 是关键 IOC 被感染的邮箱中会新增 Inbox Rule,将安全告警邮件自动删除 关键检测指标 :
邮件特征:
- 发件人是组织内部的合法用户,但发送设备异常(非公司标准配置)
- 邮件中包含短链接或编码 URL
- 附件是密码保护的压缩包
终端特征:
- WINWORD.EXE 启动 cmd.exe → powershell.exe 进程链
- PowerShell 下载并执行远程脚本
- 新增计划任务或服务用于持久化
- 注册表中新增自启动项 案例三:SolarWinds — 邮件系统持久化 SolarWinds 供应链攻击(SUNBURST/NOBELIUM)展示了邮件系统持久化的高级手法。
攻击链中的邮件持久化 :
1. 初始入侵:通过 SolarWinds Orion 供应链后门获取域控权限
2. 凭据提取:从内存中提取邮箱管理员和目标用户的凭据
3. 邮箱访问:使用窃取的凭据通过 EWS/IMAP 协议访问目标邮箱
4. 持久化建立:
- 为攻击者控制的账户添加邮箱完全访问权限
- 创建 Inbox Rule 将包含关键词的邮件自动转发
- 使用邮箱委托权限以受害者身份发送邮件
5. 数据窃取:持续监控和窃取敏感邮件
6. 横向移动:利用窃取的邮件内容中的凭据和信息进一步扩展访问 取证要点 :
邮箱权限变更日志是关键证据:管理员审计日志记录了 AddMailboxPermissions 操作 攻击者使用 Exchange Management Shell 远程执行命令,PowerShell 远程管理日志中可找到异常会话 Inbox Rule 的条件通常非常具体(如 SubjectContainsWords 包含 “password”、“budget”、“confidential”) EWS API 的访问日志显示来自非标准客户端和非预期 IP 的请求 邮件导出操作在统一审计日志中记录为 SearchQueryInitiated 和 ExportMailbox 0x12 邮件系统取证检测自动化与狩猎 Exchange 日志分析脚本(PowerShell) 以下脚本用于自动化分析 Exchange 服务器的多类日志,生成综合取证报告:
param (
[string ]$ExchangeServer = $env:COMPUTERNAME,
[int ]$Days = 7
)
$startDate = (Get-Date).AddDays(-$Days)
$endDate = Get-Date
$report = @()
Write-Host "[*] Exchange 邮件取证分析报告" -ForegroundColor Cyan
Write-Host "[*] 分析时间范围: $startDate 至 $endDate" -ForegroundColor Cyan
Write-Host " `n [+] 邮件追踪日志分析..." -ForegroundColor Yellow
$trackingLogs = Get-MessageTrackingServer -Identity $ExchangeServer |
ForEach-Object {
Get-MessageTrackingLog -Server $_.Identity `
-Start $startDate -End $endDate `
-ResultSize Unlimited
}
$suspiciousSenders = $trackingLogs |
Where-Object { $_.EventId -eq "Receive" } |
Group-Object Sender |
Where-Object { $_.Count -gt 100 } |
Sort-Object Count -Descending
Write-Host " 高频发送者:" -ForegroundColor White
$suspiciousSenders | Select-Object Count, Name -First 10 | Format-Table -AutoSize
Write-Host " `n [+] 传输日志分析..." -ForegroundColor Yellow
$transportLogPath = "C:\Program Files\Microsoft\Exchange Server\V15\TransportRoles\Logs\Hub\ProtocolLog\SmtpReceive"
if (Test-Path $transportLogPath) {
$smtpConnections = Get-ChildItem -Path $transportLogPath -Filter "*.log" |
Where-Object { $_.LastWriteTime -ge $startDate } |
ForEach-Object {
$content = Get-Content $_.FullName
$content | Where-Object { $_ -match "^20" } | ForEach-Object {
$fields = $_ -split '\s+'
[PSCustomObject ]@{
Timestamp = $fields[0 ]
ClientIP = $fields[2 ]
ClientPort = $fields[3 ]
ServerFQDN = $fields[4 ]
Action = $fields[8 ]
Recipient = $fields[9 ]
}
}
}
$externalConnections = $smtpConnections |
Where-Object { $_.ClientIP -notmatch "^10\.|^172\.(1[6-9]|2[0-9]|3[01])\.|^192\.168\." }
Write-Host " 外部 SMTP 连接数: $($externalConnections.Count)" -ForegroundColor White
}
Write-Host " `n [+] 邮箱审计日志分析..." -ForegroundColor Yellow
$auditMailboxes = Get-Mailbox -ResultSize Unlimited | Select-Object -First 10
foreach ($mailbox in $auditMailboxes) {
$auditLogs = Search-MailboxAuditLog -Identity $mailbox.DistinguishedName `
-StartDate $startDate -EndDate $endDate `
-LogonTypes Delegate -ShowDetails -ErrorAction SilentlyContinue
$delegatedAccess = $auditLogs | Where-Object {
$_.LogonUserDisplayName -ne $mailbox.DisplayName
}
if ($delegatedAccess) {
Write-Host " 邮箱 $($mailbox.PrimarySmtpAddress) 存在委托访问:" -ForegroundColor Red
$delegatedAccess | Group-Object LogonUserDisplayName |
Select-Object Count, Name | Format-Table -AutoSize
}
}
Write-Host " `n [+] Transport Rule 审计..." -ForegroundColor Yellow
$transportRules = Get-TransportRule | Select-Object Name, State, Priority, Description
$transportRules | Format-Table -AutoSize
Write-Host " `n [*] 分析完成" -ForegroundColor Green Microsoft 365 审计日志查询脚本(PowerShell) param (
[int ]$Days = 30 ,
[string ]$OutputPath = ".\M365_EmailForensics_Report.csv"
)
$startDate = (Get-Date).AddDays(-$Days)
$endDate = Get-Date
Write-Host "[*] Microsoft 365 邮件安全审计" -ForegroundColor Cyan
Write-Host "[+] 查询高风险邮件操作..." -ForegroundColor Yellow
$operations = @(
"MailboxLogin" ,
"Send" ,
"SoftDelete" ,
"HardDelete" ,
"UpdateInboxRules" ,
"AddMailboxPermissions" ,
"AddFolderPermissions" ,
"New-InboxRule" ,
"Set-InboxRule" ,
"SearchQueryInitiated" ,
"ExportMailbox" ,
"ConnectToExchange"
)
$allLogs = @()
foreach ($op in $operations) {
$logs = Search-UnifiedAuditLog -StartDate $startDate -EndDate $endDate `
-Operations $op -ResultSize 5000 -ErrorAction SilentlyContinue
$allLogs += $logs
}
$parsedLogs = $allLogs | ForEach-Object {
$data = $_.AuditData | ConvertFrom-Json -ErrorAction SilentlyContinue
if ($data) {
[PSCustomObject ]@{
时间 = $_.CreationDate
用户 = $_.UserIds
操作 = $_.Operations
目标 = $data.MailboxOwnerUPN
IP地址 = $data.ClientIPAddress
客户端 = $data.ClientInfoString
}
}
}
Write-Host "[+] 操作统计:" -ForegroundColor Yellow
$parsedLogs | Group-Object 操作 | Sort-Object Count -Descending | Format-Table Count, Name -AutoSize
Write-Host "[+] 异常登录检测(非工作时间):" -ForegroundColor Yellow
$abnormalLogin = $parsedLogs | Where-Object {
$_.操作 -eq "MailboxLogin" -and
($_.时间.Hour -lt 6 -or $_.时间.Hour -gt 22 )
}
$abnormalLogin | Format-Table -AutoSize
Write-Host "[+] 批量删除检测:" -ForegroundColor Yellow
$bulkDelete = $parsedLogs | Where-Object { $_.操作 -match "Delete" } |
Group-Object 用户, 目标 |
Where-Object { $_.Count -gt 10 }
$bulkDelete | Sort-Object Count -Descending | Format-Table Count, Name -AutoSize
$parsedLogs | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8
Write-Host "[+] 报告已保存: $OutputPath" -ForegroundColor Green 邮件头分析脚本(Python) import re
import sys
import json
from datetime import datetime
def parse_received_headers (content):
received_blocks = re. findall(
r 'Received:(.+?)(?=\n\S|\Z)' ,
content,
re. DOTALL
)
path = []
for block in reversed(received_blocks):
from_match = re. search(r 'from\s+(\S+)' , block)
by_match = re. search(r 'by\s+(\S+)' , block)
with_match = re. search(r 'with\s+(\S+)' , block)
id_match = re. search(r 'id\s+(\S+)' , block)
date_match = re. search(
r '(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s+(\d+\s+\w+\s+\d+\s+[\d:]+)' ,
block
)
ip_match = re. search(r '\[(\d+\.\d+\.\d+\.\d+)\]' , block)
hop = {
'from' : from_match. group(1 ) if from_match else 'unknown' ,
'by' : by_match. group(1 ) if by_match else 'unknown' ,
'protocol' : with_match. group(1 ) if with_match else 'unknown' ,
'message_id' : id_match. group(1 ) if id_match else '' ,
'date' : date_match. group(1 ) if date_match else '' ,
'source_ip' : ip_match. group(1 ) if ip_match else ''
}
path. append(hop)
return path
def analyze_authentication (content):
auth_match = re. search(
r 'Authentication-Results:(.*?)(?=\n\S|\Z)' ,
content,
re. DOTALL
)
if not auth_match:
return {'spf' : 'unknown' , 'dkim' : 'unknown' , 'dmarc' : 'unknown' }
auth_text = auth_match. group(1 )
spf = re. search(r 'spf=(\w+)' , auth_text)
dkim = re. search(r 'dkim=(\w+)' , auth_text)
dmarc = re. search(r 'dmarc=(\w+)' , auth_text)
return {
'spf' : spf. group(1 ) if spf else 'not_found' ,
'dkim' : dkim. group(1 ) if dkim else 'not_found' ,
'dmarc' : dmarc. group(1 ) if dmarc else 'not_found'
}
def detect_anomalies (path, auth_results):
anomalies = []
if auth_results['spf' ] == 'fail' :
anomalies. append('SPF 验证失败 — 发送 IP 未被授权' )
if auth_results['dkim' ] == 'fail' :
anomalies. append('DKIM 验证失败 — 签名不匹配或密钥缺失' )
if auth_results['dmarc' ] == 'fail' :
anomalies. append('DMARC 验证失败 — 邮件认证不通过' )
external_ips = set()
internal_ips = set()
for hop in path:
ip = hop['source_ip' ]
if not ip:
continue
if re. match (r '^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.)' , ip):
internal_ips. add(ip)
else :
external_ips. add(ip)
if len(external_ips) > 5 :
anomalies. append(f '邮件经过 { len(external_ips)} 个外部节点,路径异常长' )
if len(path) > 0 :
first_hop = path[0 ]
if first_hop['source_ip' ] and first_hop['source_ip' ] not in external_ips:
anomalies. append('首个外部节点的来源 IP 不在已知外部 IP 集合中' )
return anomalies
def generate_report (header_file):
with open(header_file, 'r' , encoding= 'utf-8' ) as f:
content = f. read()
from_match = re. search(r '^From:\s*(.+)$' , content, re. MULTILINE)
to_match = re. search(r '^To:\s*(.+)$' , content, re. MULTILINE)
subject_match = re. search(r '^Subject:\s*(.+)$' , content, re. MULTILINE)
date_match = re. search(r '^Date:\s*(.+)$' , content, re. MULTILINE)
msgid_match = re. search(r '^Message-ID:\s*(.+)$' , content, re. MULTILINE)
path = parse_received_headers(content)
auth = analyze_authentication(content)
anomalies = detect_anomalies(path, auth)
report = {
'邮件基本信息' : {
'发件人' : from_match. group(1 ) if from_match else 'unknown' ,
'收件人' : to_match. group(1 ) if to_match else 'unknown' ,
'主题' : subject_match. group(1 ) if subject_match else 'unknown' ,
'日期' : date_match. group(1 ) if date_match else 'unknown' ,
'Message-ID' : msgid_match. group(1 ) if msgid_match else 'unknown'
},
'传输路径' : path,
'认证结果' : auth,
'异常检测' : anomalies,
'风险评估' : 'HIGH' if len(anomalies) >= 2 else ('MEDIUM' if anomalies else 'LOW' )
}
print(json. dumps(report, ensure_ascii= False , indent= 2 ))
return report
if __name__ == '__main__' :
if len(sys. argv) < 2 :
print(f '用法: python { sys. argv[0 ]} <邮件头文件>' )
sys. exit(1 )
generate_report(sys. argv[1 ]) Sigma 检测规则 以下 Sigma 规则用于检测邮件系统中的恶意操作:
规则一:检测 Inbox Rule 邮件转发
title : Suspicious Inbox Rule - Email Forwarding
id : a3f2e1c4-5b6d-7e8f-9a0b-c1d2e3f4a5b6
status : stable
description : 检测创建将邮件自动转发到外部地址的 Inbox Rule
references :
- https://attack.mitre.org/techniques/T1114/
author : Security Team
date : 2026 /07/01
tags :
- attack.defense_evasion
- attack.collection
- attack.t1114
logsource :
product : m365
service : exchange
detection :
selection :
EventId : 'UpdateInboxRules'
Operation :
- 'New-InboxRule'
- 'Set-InboxRule'
filter :
Properties|contains :
- 'ForwardTo'
- 'ForwardAsAttachmentTo'
- 'RedirectTo'
condition : selection and filter
level : high
falsepositives :
- 合法的邮件转发规则配置 规则二:检测非工作时间邮箱登录
title : Suspicious Off-Hours Mailbox Login
id : b4c3d2e1-f5a6-7b8c-9d0e-f1a2b3c4d5e6
status : stable
description : 检测在非工作时间段(凌晨 2 点至 6 点)的邮箱登录行为
references :
- https://attack.mitre.org/techniques/T1078/
author : Security Team
date : 2026 /07/01
tags :
- attack.initial_access
- attack.t1078
logsource :
product : m365
service : unified_audit_log
detection :
selection :
Operations : 'MailboxLogin'
timeframe : 2h
condition : selection and (time >= '02:00' and time <= '06:00')
level : medium
falsepositives :
- 值班人员的合法登录
- 跨时区用户的正常登录 规则三:检测邮箱权限异常变更
title : Suspicious Mailbox Permission Change
id : c5d4e3f2-a1b2-3c4d-5e6f-7a8b9c0d1e2f
status : stable
description : 检测向非管理员用户授予邮箱完全访问权限的操作
references :
- https://attack.mitre.org/techniques/T1098/
author : Security Team
date : 2026 /07/01
tags :
- attack.persistence
- attack.privilege_escalation
- attack.t1098
logsource :
product : m365
service : unified_audit_log
detection :
selection :
Operations :
- 'AddMailboxPermissions'
- 'AddFolderPermissions'
filter :
UserIds|contains :
- 'admin@company.com'
- 'security@company.com'
- 'exchange-admin@company.com'
condition : selection and not filter
level : high
falsepositives :
- IT 管理员的合法权限变更操作
- 新员工入职时的邮箱权限配置 规则四:检测批量邮件删除行为
title : Bulk Email Deletion Activity
id : d6e5f4a3-b2c3-4d5e-6f7a-8b9c0d1e2f3a
status : stable
description : 检测短时间内大量删除邮件的行为,可能是攻击者在清除入侵痕迹
references :
- https://attack.mitre.org/techniques/T1070/
author : Security Team
date : 2026 /07/01
tags :
- attack.defense_evasion
- attack.t1070
logsource :
product : m365
service : unified_audit_log
detection :
selection :
Operations :
- 'SoftDelete'
- 'HardDelete'
timeframe : 10m
condition : selection | count(UserIds) by TargetUserId > 20
level : high
falsepositives :
- 用户批量清理邮箱
- 邮箱管理员执行邮箱清理操作 规则五:检测 OAuth 应用权限授予
title : Suspicious OAuth Application Permission Grant
id : e7f6a5b4-c3d4-5e6f-7a8b-9c0d1e2f3a4b
status : stable
description : 检测授予 OAuth 应用邮箱访问权限的操作
references :
- https://attack.mitre.org/techniques/T1550/
author : Security Team
date : 2026 /07/01
tags :
- attack.defense_evasion
- attack.t1550
logsource :
product : m365
service : unified_audit_log
detection :
selection :
Operations : 'Add OAuth2PermissionGrant'
condition : selection
level : medium
falsepositives :
- 合法企业应用的权限配置
- 第三方集成应用的正常授权 0x13 参考资料 Microsoft. “Exchange Server security best practices.” Microsoft Learn, https://learn.microsoft.com/en-us/exchange/security-best-practices Microsoft. “Unified audit log enabled.” Microsoft 365 Documentation, https://learn.microsoft.com/en-us/microsoft-365/enterprise/enable-unified-audit-log NIST. “SP 800-177 Rev. 1: Trustworthy Email.” National Institute of Standards and Technology, https://csrc.nist.gov/publications/detail/sp/800-177/rev-1/final RFC 7208. “Sender Policy Framework (SPF).” Internet Engineering Task Force, https://datatracker.ietf.org/doc/html/rfc7208 RFC 6376. “DomainKeys Identified Mail (DKIM).” Internet Engineering Task Force, https://datatracker.ietf.org/doc/html/rfc6376 RFC 7489. “Domain-based Message Authentication, Reporting, and Conformance (DMARC).” Internet Engineering Task Force, https://datatracker.ietf.org/doc/html/rfc7489 MITRE ATT&CK. “T1566 - Phishing.” https://attack.mitre.org/techniques/T1566/ MITRE ATT&CK. “T1114 - Email Collection.” https://attack.mitre.org/techniques/T1114/ MITRE ATT&CK. “T1098 - Account Manipulation.” https://attack.mitre.org/techniques/T1098/ Microsoft. “Microsoft Defender for Office 365 documentation.” https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/ Mandiant. “UNC2630 MANGANESE Targets U.S. Government.” Mandiant Blog, 2021 CISA. “Alert (AA21-008A): Detecting Post-Compromise Threat Activity in Microsoft Cloud Environments.” Cybersecurity Advisory, 2021 Huntress. “SolarWinds Orion Incident Response: Email System Persistence.” Huntress Research, 2021