Communitygithub.com

钓鱼邮件调查之邮件头分析

解析和分析邮件头(Received 链、Return-Path、Message-ID 等),用于调查可疑的钓鱼邮件并确定其真实来源。

钓鱼邮件调查之邮件头分析 是什么?

该技能提供了一套系统化的方法,用于分析原始邮件头以调查钓鱼攻击。它涵盖了从提取原始邮件头开始的全流程:使用 Python 的 email 库解析邮件头链,验证 SPF、DKIM 和 DMARC 记录以检测邮件伪造,分析发件人域名和基础设施的年龄及声誉,以及检查邮件正文和附件中的 URL 及哈希值。该技能适用于 EML 或 MSG 格式的邮件,并可在命令行环境(如 Linux/macOS)中通过 dig、nslookup 等工具以及 Python 脚本实现。其核心价值在于帮助安全分析人员快速确定邮件的真实来源、识别疑似钓鱼邮件中的关键告警指标(如域名仿冒、From/Reply-To 不匹配、身份验证失败等),并输出结构化的分析报告。该技能兼容 Cursor 和 Claude Code 等 AI 编码工具,用户可将其用作自定义指令或代理技能。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mukul975/Anthropic-Cybersecurity-Skills/tree/main/skills/analyzing-email-headers-for-phishing-investigation

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

钓鱼邮件调查之邮件头分析 是做什么的?

适用场景

  • 调查疑似钓鱼邮件,确定其真实来源
  • 验证发件人真实性并检测邮件欺骗(Spoofing)
  • 在用户点击了钓鱼链接后的应急响应中
  • 追踪可疑邮件的投递路径和转发服务器
  • 验证 SPF、DKIM 和 DMARC 对齐情况,识别伪造邮件

前提条件

  • 来自可疑邮件的原始邮件头(EML 或 MSG 格式)
  • 了解 SMTP 协议和邮件头字段
  • 能够使用 DNS 查询工具(dig、nslookup)验证 SPF/DKIM/DMARC
  • 邮件头分析工具(MHA、emailheaders.net 等概念)
  • 安装了用于自动分析的 Python 邮件解析库
  • 能够访问威胁情报平台查询 IP/域名声誉

工作流程

步骤 1:提取原始邮件头

# 从 Outlook 导出:打开邮件 > 文件 > 属性 > Internet 邮件头
# 从 Gmail 导出:打开邮件 > 三点菜单 > 显示原始邮件
# 从 Thunderbird 导出:查看 > 消息源代码

# 如果从取证镜像中获得 EML 文件
cp /mnt/evidence/Users/suspect/AppData/Local/Microsoft/Outlook/phishing_email.eml \
   /cases/case-2024-001/email/

# 如果处理的是 PST 文件,提取单个邮件
pip install pypff
python3 << 'PYEOF'
import pypff

pst = pypff.file()
pst.open("/cases/case-2024-001/email/outlook.pst")
root = pst.get_root_folder()

def extract_messages(folder, path=""):
    for i in range(folder.get_number_of_sub_messages()):
        msg = folder.get_sub_message(i)
        headers = msg.get_transport_headers()
        subject = msg.get_subject()
        if headers:
            filename = f"/cases/case-2024-001/email/msg_{i}_{subject[:30]}.txt"
            with open(filename, 'w') as f:
                f.write(headers)
    for i in range(folder.get_number_of_sub_folders()):
        extract_messages(folder.get_sub_folder(i))

extract_messages(root)
PYEOF

步骤 2:解析邮件头链

# 使用 Python 的 email 库解析邮件头
python3 << 'PYEOF'
import email
from email import policy

with open('/cases/case-2024-001/email/phishing_email.eml', 'r') as f:
    msg = email.message_from_file(f, policy=policy.default)

print("=== 关键邮件头字段 ===")
print(f"发件人(From):          {msg['From']}")
print(f"收件人(To):            {msg['To']}")
print(f"主题(Subject):         {msg['Subject']}")
print(f"日期(Date):            {msg['Date']}")
print(f"消息ID(Message-ID):    {msg['Message-ID']}")
print(f"回复地址(Reply-To):    {msg['Reply-To']}")
print(f"退信地址(Return-Path): {msg['Return-Path']}")
print(f"X-Mailer:              {msg['X-Mailer']}")
print(f"X-Originating-IP:      {msg['X-Originating-IP']}")

print("\n=== 接收头(Received) (从下到上 = 时间顺序) ===")
received_headers = msg.get_all('Received')
if received_headers:
    for i, header in enumerate(reversed(received_headers)):
        print(f"\n跳数 {i+1}: {header.strip()}")

print("\n=== 认证结果 ===")
auth_results = msg.get_all('Authentication-Results')
if auth_results:
    for result in auth_results:
        print(result)

print(f"\nARC-Authentication-Results: {msg.get('ARC-Authentication-Results', '未出现')}")
print(f"Received-SPF: {msg.get('Received-SPF', '未出现')}")
print(f"DKIM-Signature: {msg.get('DKIM-Signature', '未出现')}")
PYEOF

步骤 3:验证 SPF、DKIM 和 DMARC 记录

# 提取信封发件人域名
SENDER_DOMAIN="example-corp.com"

# 检查 SPF 记录
dig TXT $SENDER_DOMAIN +short | grep "v=spf1"
# 示例输出:"v=spf1 include:_spf.google.com include:sendgrid.net ~all"

# 检查 DKIM 记录(选择器来自 DKIM-Signature 头,例如 "s=selector1")
DKIM_SELECTOR="selector1"
dig TXT ${DKIM_SELECTOR}._domainkey.${SENDER_DOMAIN} +short

# 检查 DMARC 记录
dig TXT _dmarc.${SENDER_DOMAIN} +short
# 示例输出:"v=DMARC1; p=reject; rua=mailto:[email protected]; pct=100"

# 验证发送 IP 是否符合 SPF
# 从第一个 Received 头中提取 IP
SENDING_IP="203.0.113.45"

# 使用 Python 进行 SPF 手动检查
python3 << 'PYEOF'
import spf  # pip install pyspf

result, explanation = spf.check2(
    i='203.0.113.45',
    s='[email protected]',
    h='mail.example-corp.com'
)
print(f"SPF 结果: {result}")
print(f"说明: {explanation}")
# 可能的结果:pass, fail, softfail, neutral, none, temperror, permerror
PYEOF

# 检查发送 IP 是否在已知恶意 IP 列表中
# 查询 AbuseIPDB 或 VirusTotal
curl -s "https://api.abuseipdb.com/api/v2/check?ipAddress=${SENDING_IP}" \
   -H "Key: YOUR_API_KEY" -H "Accept: application/json" | python3 -m json.tool

步骤 4:分析发件人域名和基础设施

# WHOIS 查询发件人域名
whois $SENDER_DOMAIN | grep -iE '(registrar|creation|expiration|registrant|nameserver)'

# 检查域名年龄(最近注册的域名可疑)
# DNS 记录调查
dig A $SENDER_DOMAIN +short
dig MX $SENDER_DOMAIN +short
dig NS $SENDER_DOMAIN +short

# 发送 IP 的反向 DNS
dig -x $SENDING_IP +short

# 检查是否存在仿冒/钓鱼域名(视觉相似)
# 与合法域名对比
python3 << 'PYEOF'
import Levenshtein  # pip install python-Levenshtein

legitimate = "microsoft.com"
suspicious = "micr0soft.com"

distance = Levenshtein.distance(legitimate, suspicious)
ratio = Levenshtein.ratio(legitimate, suspicious)
print(f"编辑距离: {distance}")
print(f"相似度: {ratio:.2%}")
if ratio > 0.8:
    print("警告:极有可能是拼写诈骗/仿冒域名!")
PYEOF

# 在 VirusTotal 上检查域名声誉
curl -s "https://www.virustotal.com/api/v3/domains/${SENDER_DOMAIN}" \
   -H "x-apikey: YOUR_VT_API_KEY" | python3 -m json.tool

# 检查 Reply-To 是否与 From 不同(常见的钓鱼指标)
python3 -c "
import email
with open('/cases/case-2024-001/email/phishing_email.eml') as f:
    msg = email.message_from_file(f)
from_addr = email.utils.parseaddr(msg['From'])[1]
reply_to = email.utils.parseaddr(msg.get('Reply-To', msg['From']))[1]
if from_addr != reply_to:
    print(f'警告:发件人({from_addr}) != 回复地址({reply_to})')
else:
    print('发件人和回复地址匹配')
"

步骤 5:检查邮件正文和附件

# 从邮件正文中提取 URL
python3 << 'PYEOF'
import email
import re
from email import policy

with open('/cases/case-2024-001/email/phishing_email.eml', 'r') as f:
    msg = email.message_from_file(f, policy=policy.default)

body = msg.get_body(preferencelist=('html', 'plain'))
if body:
    content = body.get_content()
    urls = re.findall(r'https?://[^\s<>\"\']+', content)
    print("=== 邮件正文中发现的 URL ===")
    for url in set(urls):
        print(f"  {url}")

    # 检查 URL 混淆(显示文本 != href)
    href_pattern = re.findall(r'<a[^>]*href=[\"\']([^\"\']+)[\"\'][^>]*>(.*?)</a>', content, re.DOTALL)
    print("\n=== 超链接分析 ===")
    for href, text in href_pattern:
        display_url = re.findall(r'https?://[^\s<]+', text)
        if display_url and display_url[0] != href:
            print(f"  不匹配:显示='{display_url[0]}' -> 实际='{href}'")

# 提取并计算附件哈希
print("\n=== 附件 ===")
for part in msg.walk():
    if part.get_content_disposition() == 'attachment':
        filename = part.get_filename()
        content = part.get_payload(decode=True)
        import hashlib
        sha256 = hashlib.sha256(content).hexdigest()
        print(f"  文件: {filename}, 大小: {len(content)}, SHA-256: {sha256}")
        with open(f'/cases/case-2024-001/email/attachments/{filename}', 'wb') as af:
            af.write(content)
PYEOF

# 将附件哈希提交到 VirusTotal
# 将 URL 提交到 URLhaus 或 PhishTank 进行声誉检查

关键概念

概念描述
SPF(发件人策略框架)指定域名的授权邮件服务器的 DNS 记录
DKIM(域名密钥识别邮件)验证邮件内容完整性的加密签名
DMARC结合 SPF 和 DKIM 进行发件人认证的策略框架
Received 头服务器添加的头部,显示投递链中的每一跳(从下到上阅读)
Return-Path用于退信的信封发件人地址;可能与 From 不同
Message-ID由原始邮件服务器分配的唯一标识符
X-Originating-IP原始发件人 IP 地址(由某些邮件服务添加)
头伪造攻击者可以伪造 From、Reply-To 等头,但无法伪造 Received 链

工具与系统

工具用途
MXToolbox在线邮件头分析器和 DNS 查询
dig/nslookup用于 SPF、DKIM、DMARC 验证的 DNS 记录查询
pyspfPython SPF 记录验证库
dkimpyPython DKIM 签名验证库
PhishTool专门的钓鱼邮件分析平台
VirusTotalURL 和文件信誉检查服务
AbuseIPDBIP 地址信誉数据库
whois域名注册信息查询

常见场景

场景 1:CEO 欺诈 / 商业邮件入侵 (BEC) 邮件声称来自 CEO,但 Reply-To 指向一个 Gmail 地址,SPF 验证失败(因为发送 IP 未被授权用于被欺骗的域名),DKIM 缺失,From 域是一个仿冒域名(ceo-company.com 对比 company.com)。

场景 2:凭证收集钓鱼 邮件包含一个链接,显示为 "login.microsoft.com" 但 href 指向一个仿冒域名;附件是一个 HTML 文件,包含带有凭证窃取 JavaScript 的虚假登录页面;发送域名是在 3 天前注册的。

场景 3:通过附件传递恶意软件 邮件包含带有宏的 Office 文档附件;发件人域名通过了 SPF 验证(但账户已被入侵);DKIM 签名有效(通过合法基础设施发送);附件 SHA-256 与 VirusTotal 上的已知恶意软件匹配。

场景 4:使用合法服务的鱼叉式钓鱼 攻击者使用合法的邮件营销服务发送钓鱼邮件;SPF 和 DKIM 都通过验证(因为该服务已获得授权);钓鱼内容隐藏在邮件正文中,而非基础设施层面;需要 URL 和内容分析,而非邮件头身份验证检查。

输出格式

邮件头分析报告:
  主题(Subject):      "紧急:发票付款请求"
  发件人(From):       [email protected] (伪造)
  回复地址(Reply-To): [email protected] (不匹配)
  退信地址(Return-Path): <[email protected]>
  日期(Date):         2024-01-15 09:23:45 UTC

  投递路径(4 跳):
    跳 1:mail-server.xyz [203.0.113.45] -> relay1.isp.com
    跳 2:relay1.isp.com -> mx.target-company.com
    跳 3:mx.target-company.com -> internal-filter.target.com
    跳 4:internal-filter.target.com -> mailbox

  身份验证:
    SPF:    失败 (203.0.113.45 未被授权用于 examp1e-corp.com)
    DKIM:   无 (未出现签名)
    DMARC:  失败 (p=none, 未强制执行)

  钓鱼指标:
    - 仿冒域名 (examp1e-corp.com vs example-corp.com, 96% 相似)
    - From/Reply-To 不匹配
    - 域名在邮件发送前 2 天注册
    - 正文中的 URL 指向凭证收集页面
    - 附件:invoice.xlsm (SHA-256: a3f2...) - VT 上已知恶意软件

  风险等级:高

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

abusing-dpapi-for-credential-access

Extract and decrypt Windows DPAPI-protected secrets (Credential Manager, browser logins/cookies, Wi-Fi credentials, KeePass keys) online or offline using SharpDPAPI, SharpChrome, Mimikatz, or Impacket

abusing-shadow-credentials-for-privesc

Take over Active Directory accounts by writing attacker-controlled public keys to msDS-KeyCredentialLink (Shadow Credentials) with pyWhisker, Whisker, or Certipy, then authenticate via PKINIT to recover the target

achieving-cmmc-level-2-compliance

>-

acquiring-disk-image-with-dd-and-dcfldd

Create forensically sound bit-for-bit disk images with dd or dcfldd on a Linux forensic workstation, preserving evidence integrity through hash verification (MD5/SHA) during acquisition. Use when imaging a suspect drive, USB device, or memory card for investigation, preserving volatile disk evidence during incident response, or producing a verified copy for legal or law-enforcement proceedings before any destructive analysis.

analyzing-active-directory-acl-abuse

Detect dangerous ACL misconfigurations in Active Directory using ldap3

analyzing-android-malware-with-apktool

Perform static analysis of Android APK malware using apktool for resource decompilation, jadx for Java source recovery, and androguard for manifest inspection, dangerous permission-combination detection, and identification of obfuscated code, dynamic code loading, and reflection-based API calls. Use to statically triage a suspicious APK without executing it or to build mobile malware detection rules.

analyzing-api-gateway-access-logs

Parses API Gateway access logs (AWS API Gateway, Kong, Nginx) to detect

analyzing-apt-group-with-mitre-navigator

Query ATT&CK data with attackcti, mitreattack-python, and stix2, then build MITRE ATT&CK Navigator layers and multi-layer heatmap overlays mapping one or more APT groups

analyzing-azure-activity-logs-for-threats

Queries Azure Monitor activity logs and sign-in logs via azure-monitor-query

analyzing-bootkit-and-rootkit-samples

Analyzes bootkit and advanced rootkit malware infecting the Master

analyzing-browser-forensics-with-hindsight

Parse Chromium-based browser databases with Hindsight to extract and correlate browsing history, downloads, cookies, cached content, autofill data, saved passwords, and extensions from Chrome, Edge, Brave, Opera, and Vivaldi into a unified timeline (XLSX, JSON, or SQLite output). Use during incident response, insider-threat investigations, or criminal cases when you need to reconstruct a user

analyzing-campaign-attribution-evidence

Systematically evaluate cyber-campaign evidence to attribute an operation to a threat actor, using the Diamond Model and Analysis of Competing Hypotheses (ACH) to weigh infrastructure overlaps, TTP consistency, malware code similarity, and timing/language artifacts into confidence-weighted attribution assessments. Use when an incident investigation needs a defensible attribution confidence level.

analyzing-certificate-transparency-for-phishing

Monitor Certificate Transparency logs using crt.sh and Certstream to

analyzing-cloud-storage-access-patterns

Detect abnormal access in AWS S3, GCS, and Azure Blob Storage by analyzing CloudTrail Data Events, GCS audit logs, and Azure Storage Analytics for after-hours bulk downloads, new-IP access, and API-call spikes (e.g. GetObject) via statistical baselines and time-series anomaly detection. Use when investigating suspected cloud data exfiltration or building related detection rules.

analyzing-cobalt-strike-beacon-configuration

Extract and analyze Cobalt Strike beacon configuration from PE files

analyzing-cobaltstrike-malleable-c2-profiles

Parse and analyze Cobalt Strike Malleable C2 profiles with dissect.cobaltstrike (profiles and beacon-payload configs) and pyMalleableC2 (AST parsing) to extract HTTP/DNS transforms, URIs, headers, sleep/jitter, and injection behavior, then generate network detection signatures. Use when reverse-engineering a captured malleable profile or building detections against Cobalt Strike Beacon traffic.

analyzing-command-and-control-communication

Analyzes malware C2 communication over HTTP, HTTPS, DNS, and custom

analyzing-cyber-kill-chain

Analyzes intrusion activity against the Lockheed Martin Cyber Kill Chain

analyzing-disk-image-with-autopsy

Perform comprehensive forensic analysis of raw (dd), E01, or AFF disk images with Autopsy and The Sleuth Kit, recovering deleted files, examining metadata and embedded artifacts, keyword searching, and building investigation timelines with visual reports. Use for structured analysis of a forensic disk image or when stakeholders need visual reports from evidence.

analyzing-dns-logs-for-exfiltration

Analyzes DNS query logs to detect data exfiltration via DNS tunneling,

相关技能