analyzing-outlook-pst-for-email-forensics
分析 Microsoft Outlook PST 和 OST 文件,提取电子邮件取证证据,包括邮件内容、邮件头、附件、已删除邮件及元数据,使用 libpff、pst-utils 和取证电子邮件分析工具,适用于法律调查和事件响应。
Best use case
analyzing-outlook-pst-for-email-forensics is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
分析 Microsoft Outlook PST 和 OST 文件,提取电子邮件取证证据,包括邮件内容、邮件头、附件、已删除邮件及元数据,使用 libpff、pst-utils 和取证电子邮件分析工具,适用于法律调查和事件响应。
Teams using analyzing-outlook-pst-for-email-forensics should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/analyzing-outlook-pst-for-email-forensics/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How analyzing-outlook-pst-for-email-forensics Compares
| Feature / Agent | analyzing-outlook-pst-for-email-forensics | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
分析 Microsoft Outlook PST 和 OST 文件,提取电子邮件取证证据,包括邮件内容、邮件头、附件、已删除邮件及元数据,使用 libpff、pst-utils 和取证电子邮件分析工具,适用于法律调查和事件响应。
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# 分析 Outlook PST 进行电子邮件取证
## 概述
Microsoft Outlook PST(个人存储表,Personal Storage Table)和 OST(离线存储表,Offline Storage Table)文件是数字取证调查中的关键证据来源。PST 文件以基于 MAPI(消息应用程序编程接口,Messaging Application Programming Interface)属性系统的专有二进制格式存储电子邮件、日历事件、联系人、任务和备注。对这些文件进行取证分析,可以恢复已删除的邮件(来自"可恢复邮件"文件夹)、提取邮件头以追踪邮件路由、分析附件中的恶意软件或外泄数据,以及重建通信模式。现代 PST 文件使用 Unicode 格式,页面大小 4KB,最大可达 50GB;而旧版 ANSI 格式限制为 2GB。
## 前置条件
- libpff/pffexport(开源 PST 解析器)
- Python 3.8+,附带 pypff 或 libratom 库
- MailXaminer、Forensic Email Collector 或 SysTools PST Forensics(商业工具)
- Microsoft Outlook(可选,用于原生 PST 访问)
- 足够的磁盘空间用于存放提取内容
## PST 文件位置
| 来源 | 路径 |
|------|------|
| Outlook 2016+ 默认位置 | %USERPROFILE%\Documents\Outlook Files\*.pst |
| Outlook 旧版 | %LOCALAPPDATA%\Microsoft\Outlook\*.pst |
| OST 缓存 | %LOCALAPPDATA%\Microsoft\Outlook\*.ost |
| 归档文件 | %USERPROFILE%\Documents\Outlook Files\archive.pst |
## 使用开源工具分析
### libpff / pffexport
```bash
# 从 PST 文件导出所有项目
pffexport -m all evidence.pst -t exported_pst
# 仅导出电子邮件
pffexport -m items evidence.pst -t exported_emails
# 导出已恢复/已删除项目
pffexport -m recovered evidence.pst -t recovered_items
# 获取 PST 文件信息
pffinfo evidence.pst
```
### Python PST 分析
```python
import pypff
import os
import json
import hashlib
import email
import sys
from datetime import datetime
from collections import defaultdict
class PSTForensicAnalyzer:
"""Outlook PST/OST 文件的取证分析器。"""
def __init__(self, pst_path: str, output_dir: str):
self.pst_path = pst_path
self.output_dir = output_dir
os.makedirs(output_dir, exist_ok=True)
self.pst = pypff.file()
self.pst.open(pst_path)
self.messages = []
self.attachments = []
self.stats = defaultdict(int)
def process_folder(self, folder, folder_path: str = ""):
"""递归处理 PST 文件夹并提取邮件。"""
folder_name = folder.name or "Root"
current_path = f"{folder_path}/{folder_name}" if folder_path else folder_name
for i in range(folder.number_of_sub_messages):
try:
message = folder.get_sub_message(i)
msg_data = self.extract_message(message, current_path)
if msg_data:
self.messages.append(msg_data)
self.stats["total_messages"] += 1
except Exception as e:
self.stats["parse_errors"] += 1
for i in range(folder.number_of_sub_folders):
try:
subfolder = folder.get_sub_folder(i)
self.process_folder(subfolder, current_path)
except Exception:
continue
def extract_message(self, message, folder_path: str) -> dict:
"""从单封邮件中提取取证元数据。"""
msg_data = {
"folder": folder_path,
"subject": message.subject or "",
"sender": message.sender_name or "",
"sender_email": "",
"creation_time": str(message.creation_time) if message.creation_time else None,
"delivery_time": str(message.delivery_time) if message.delivery_time else None,
"modification_time": str(message.modification_time) if message.modification_time else None,
"has_attachments": message.number_of_attachments > 0,
"attachment_count": message.number_of_attachments,
"body_size": len(message.plain_text_body or b""),
"html_size": len(message.html_body or b""),
}
# 提取传输头用于路由分析
headers = message.transport_headers
if headers:
msg_data["headers_present"] = True
msg_data["headers_size"] = len(headers)
# 解析关键头字段
parsed = email.message_from_string(headers)
msg_data["from_header"] = parsed.get("From", "")
msg_data["to_header"] = parsed.get("To", "")
msg_data["date_header"] = parsed.get("Date", "")
msg_data["message_id"] = parsed.get("Message-ID", "")
msg_data["x_originating_ip"] = parsed.get("X-Originating-IP", "")
msg_data["received_headers"] = parsed.get_all("Received", [])
# 处理附件
for j in range(message.number_of_attachments):
try:
attachment = message.get_attachment(j)
att_data = {
"message_subject": msg_data["subject"],
"name": attachment.name or f"attachment_{j}",
"size": attachment.size,
"content_type": "",
}
self.attachments.append(att_data)
self.stats["total_attachments"] += 1
except Exception:
continue
return msg_data
def save_attachments(self, max_size_mb: int = 100):
"""将附件导出到磁盘进行分析。"""
att_dir = os.path.join(self.output_dir, "attachments")
os.makedirs(att_dir, exist_ok=True)
root = self.pst.get_root_folder()
self._save_attachments_recursive(root, att_dir, max_size_mb)
def _save_attachments_recursive(self, folder, att_dir, max_size_mb):
for i in range(folder.number_of_sub_messages):
try:
message = folder.get_sub_message(i)
for j in range(message.number_of_attachments):
att = message.get_attachment(j)
if att.size and att.size < max_size_mb * 1024 * 1024:
name = att.name or f"unknown_{i}_{j}"
safe_name = "".join(c if c.isalnum() or c in ".-_" else "_" for c in name)
path = os.path.join(att_dir, safe_name)
try:
data = att.read_buffer(att.size)
with open(path, "wb") as f:
f.write(data)
except Exception:
continue
except Exception:
continue
for i in range(folder.number_of_sub_folders):
try:
self._save_attachments_recursive(folder.get_sub_folder(i), att_dir, max_size_mb)
except Exception:
continue
def generate_report(self) -> str:
"""生成综合 PST 取证分析报告。"""
root = self.pst.get_root_folder()
self.process_folder(root)
report = {
"analysis_timestamp": datetime.now().isoformat(),
"pst_file": self.pst_path,
"pst_size_bytes": os.path.getsize(self.pst_path),
"statistics": dict(self.stats),
"messages": self.messages[:500],
"attachments": self.attachments[:200],
}
report_path = os.path.join(self.output_dir, "pst_forensic_report.json")
with open(report_path, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"[*] 邮件总数: {self.stats['total_messages']}")
print(f"[*] 附件总数: {self.stats['total_attachments']}")
print(f"[*] 解析错误: {self.stats['parse_errors']}")
return report_path
def close(self):
self.pst.close()
def main():
if len(sys.argv) < 3:
print("用法: python process.py <pst_file> <output_dir>")
sys.exit(1)
analyzer = PSTForensicAnalyzer(sys.argv[1], sys.argv[2])
analyzer.generate_report()
analyzer.close()
if __name__ == "__main__":
main()
```
## 电子邮件头分析
取证调查的关键头字段:
| 头字段 | 取证价值 |
|--------|---------|
| Received | 邮件路由链(从下到上阅读) |
| X-Originating-IP | 发件人实际 IP 地址 |
| Message-ID | 用于关联的唯一标识符 |
| Date | 发送时间戳 |
| Return-Path | 退信地址(可能与 From 不同) |
| DKIM-Signature | 域名认证签名 |
| Authentication-Results | SPF、DKIM、DMARC 验证结果 |
| X-Mailer | 使用的邮件客户端 |
## 参考资料
- MailXaminer PST 取证: https://www.mailxaminer.com/blog/outlook-pst-file-forensics/
- libpff 文档: https://github.com/libyal/libpff
- PST 文件格式规范: https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-pst/
- SANS 电子邮件取证: https://www.sans.org/blog/email-forensics/Related Skills
testing-for-email-header-injection
测试 Web 应用程序邮件功能中的 SMTP 头部注入漏洞,这些漏洞允许攻击者注入额外的邮件头部、修改收件人,并通过联系表单实施垃圾邮件中继。
performing-sqlite-database-forensics
对 SQLite 数据库执行取证分析,从空闲列表(Freelist)和 WAL 文件中恢复已删除记录,解码编码时间戳,并从浏览器历史、即时通讯应用和移动设备数据库中提取证据。
performing-network-forensics-with-wireshark
使用 Wireshark 和 tshark 捕获并分析网络流量,重建网络事件、提取制品并识别恶意通信。
performing-mobile-device-forensics-with-cellebrite
使用 Cellebrite UFED 和开源工具获取和分析移动设备数据,提取通信记录、位置数据和应用程序制品。
performing-memory-forensics-with-volatility3
使用 Volatility 3 分析易失性内存转储,以提取运行中的进程、网络连接、加载的模块以及恶意活动的证据。
performing-memory-forensics-with-volatility3-plugins
使用 Volatility3 插件分析内存转储,检测 Windows、Linux 和 macOS 内存镜像中的注入代码、Rootkit、凭据窃取和恶意软件痕迹。
performing-linux-log-forensics-investigation
对 Linux 系统日志(包括 syslog、auth.log、systemd journal、kern.log 和应用程序日志)进行取证调查,以重建用户活动、检测未授权访问并在被入侵的 Linux 系统上建立事件时间线。
performing-endpoint-forensics-investigation
对受损端点执行数字取证调查,包括内存获取、磁盘镜像、工件分析和时间线重建。 适用于调查安全事件、为法律诉讼收集证据或分析端点受损范围的场景。 适用于涉及端点取证、内存分析、磁盘取证或事件调查的请求。
performing-disk-forensics-investigation
使用取证镜像、文件系统分析、产物恢复和时间线重建进行磁盘取证调查,以支持事件响应案例。 使用 FTK Imager、Autopsy 和 The Sleuth Kit 等工具进行证据采集、已删除文件恢复和产物检查。 适用于磁盘取证、硬盘分析、取证镜像、文件恢复、证据采集或数字取证调查等请求场景。
performing-cloud-native-forensics-with-falco
使用 Falco YAML 规则在容器和 Kubernetes 中进行运行时威胁检测,监控系统调用以检测 shell 生成、文件篡改、网络异常和权限提升。通过 Falco gRPC API 管理 Falco 规则并解析 Falco 告警输出。适用于构建容器运行时安全或调查 k8s 集群入侵。
performing-cloud-forensics-with-aws-cloudtrail
使用 CloudTrail 日志对 AWS 环境执行取证调查,重建攻击者活动、识别受损凭据并分析 API 调用模式。
performing-cloud-forensics-investigation
通过收集和分析来自 AWS、Azure 和 GCP 服务的日志、快照和元数据,在云环境中开展取证调查。