用于 CVE-2025-14847(MongoBleed)的离线 MongoDB 分析工具
一款独立的 Linux 命令行工具,通过多种检测模块分析 MongoDB 数据,以识别可能存在的 CVE-2025-14847 漏洞利用行为。
MongoBleed(CVE-2025-14847)是 MongoDB zlib 解压过程中的一个内存泄露漏洞,攻击者无需认证即可直接从服务器内存中提取敏感数据——包括凭据、会话令牌、PII(个人身份信息)。
本工具可帮助应急响应人员利用多种证据来源检测漏洞利用尝试:
分析 MongoDB JSON 日志以检测漏洞利用模式:
| 事件 ID | 类型 | 描述 |
|---|---|---|
| 22943 | 连接已接受 | 客户端连接时记录 |
| 51800 | 客户端元数据 | 客户端发送驱动/应用信息时记录 |
| 22944 | 连接已关闭 | 客户端断开连接时记录 |
关键洞察:合法的 MongoDB 驱动总会发送客户端元数据。而 MongoBleed 漏洞利用程序连接、提取内存、然后断开——但从不发送元数据。
分析 db.serverStatus().asserts 的快照,以检测 asserts.user 计数器中的异常模式:
asserts.user 与其他断言类型进行比较来检测可疑模式。如果用户断言数异常偏高(比值 ≥250 倍)或所有其他类型均为零,则标记为可疑(MEDIUM 置信度)注意:累积计数器可能产生误报。请与 FTDC(模块 B2)结合使用以获得最佳效果。
分析 MongoDB 的全时诊断数据采集(FTDC)文件,以检测断言计数器在时间维度上的局部激增。FTDC 会周期性采样 serverStatus,从而能够精确定位潜在攻击的发生时间。
jq - JSON 处理器awk(建议使用 gawk)gzip - 用于支持压缩日志pymongo - 用于 FTDC 文件解码ssh、scp 命令)# Shell 脚本依赖
# Debian/Ubuntu
apt-get install jq gawk gzip
# RHEL/CentOS/Fedora
dnf install jq gawk gzip
# macOS
brew install jq gawk
# Python 依赖(用于 FTDC 解码)
pip install -r requirements.txt
# 克隆仓库
git clone https://github.com/your-org/mongobleed-detector.git
cd mongobleed-detector
# 赋予脚本可执行权限
chmod +x mongobleed-detector.sh
chmod +x mongobleed-remote.py
chmod +x ftdc-decode.py
# 安装 Python 依赖(可选,用于 FTDC 支持)
pip install -r requirements.txt
分析从 MongoDB 主机手动采集的数据。
通过 SSH 自动从多台主机采集数据,然后在本地进行分析。
从 MongoDB 主机采集数据,并按以下结构组织:
./collected-data/
├── logs/ # MongoDB JSON 日志
│ ├── mongod.log
│ ├── mongod.log.1
│ └── mongod.log.2.gz
├── assert-counts/ # serverStatus().asserts 快照
│ ├── asserts-2025-01-01.json
│ └── asserts-2025-01-02.json
└── ftdc-files/ # FTDC diagnostic.data 内容
├── metrics.2025-01-02T10-00-00Z-00000
└── metrics.interim
# 从远程主机复制
scp user@mongohost:/var/log/mongodb/mongod.log* ./collected-data/logs/
在 MongoDB 主机上运行以下命令(需要 mongosh 访问权限):
mongosh --quiet --eval 'JSON.stringify({
timestamp: new Date().toISOString(),
hostname: db.hostInfo().system.hostname,
asserts: db.serverStatus().asserts,
uptime: db.serverStatus().uptime
})' > asserts-$(date +%Y%m%d-%H%M%S).json
将生成的 JSON 文件复制到 ./collected-data/assert-counts/。
提示:多次运行此命令(例如每小时一次),以建立基线并检测激增。
FTDC 文件位于:
<storage.dbPath>/diagnostic.data/(通常为 /var/lib/mongodb/diagnostic.data/)systemLog.path 推导得出(例如 /var/log/mongodb/mongos.diagnostic.data/)# 复制 FTDC 文件(可能需要 sudo)
sudo cp /var/lib/mongodb/diagnostic.data/metrics.* ./collected-data/ftdc-files/
# 自动发现模式 - 分析所有可用数据
./mongobleed-detector.sh --data-dir ./collected-data/
# 使用自定义阈值
./mongobleed-detector.sh --data-dir ./collected-data/ \
-t 1440 \ # 24 小时回看窗口
-c 50 \ # 更低的连接阈值
--spike-threshold 50 # 更低的激增阈值
为保持向后兼容,您仍可直接分析日志:
# 扫描默认路径
./mongobleed-detector.sh
# 扫描特定日志文件
./mongobleed-detector.sh -p /path/to/logs/*.json
# 取证模式(分析多台主机)
./mongobleed-detector.sh --forensic-dir /evidence/
自动从多台主机采集数据并进行分析:
# 创建主机列表文件
cat > hosts.txt << EOF
mongo-prod-01.example.com
mongo-prod-02.example.com
mongo-staging.example.com
EOF
# 采集并分析
./mongobleed-remote.py --hosts-file hosts.txt --user admin --output-dir ./collected-data/
# 使用指定的 SSH 密钥
./mongobleed-remote.py --hosts-file hosts.txt --user admin --key ~/.ssh/mongodb_key
# 并行执行
./mongobleed-remote.py --hosts-file hosts.txt --user admin --parallel 10
# 跳过 FTDC 采集(更快)
./mongobleed-remote.py --hosts-file hosts.txt --user admin --skip-ftdc
# 仅采集,稍后分析
./mongobleed-remote.py --hosts-file hosts.txt --user admin --collect-only
# 传递 SSH 选项(例如跳板主机)
./mongobleed-remote.py --hosts-file hosts.txt --user admin \
-o "ProxyJump=bastion.example.com"
# 使用 sudo 访问受权限保护的文件(FTDC 文件通常受限)
./mongobleed-remote.py --hosts-file hosts.txt --user admin --sudo
# 调试模式,排查连接问题
./mongobleed-remote.py --hosts-file hosts.txt --user admin --debug
关于 FTDC 权限的说明:
/var/lib/mongodb/diagnostic.data/中的 FTDC 文件通常归mongodb用户所有,普通用户无法读取。如果看到 "FTDC Permission Issues" 警告,请使用--sudo标志。这要求远程用户具有免密码 sudo 访问权限(在 sudoers 中配置 NOPASSWD)。
| 代码 | 含义 |
|---|---|
| 0 | 未发现 HIGH 或 MEDIUM 级别结果 |
| 1 | 检测到 HIGH 或 MEDIUM 级别结果 |
| 2 | 错误(缺少依赖、无数据等) |
该工具根据所有可用证据提供综合置信度判定:
对于日志关联分析(模块 A),各个 IP 被分类为:
| 风险 | 判定标准 |
|---|---|
| HIGH | 连接数 ≥ 阈值,元数据率 < 10%,突发速率 ≥ 400/分钟 |
| MEDIUM | 连接数 ≥ 阈值,元数据率 < 10%,突发速率 < 400/分钟 |
| LOW | 连接数 ≥ 阈值,元数据率 ≥ 10% |
INFO: Auto-discovery mode: analyzing ./collected-data/
INFO: Module A: Analyzing 3 log file(s)...
INFO: Module B1: Analyzing assert-counts...
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ MongoBleed (CVE-2025-14847) Detection Results ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
Module Status:
[✓] Module A (Log Correlation): 3 log file(s) found
[✓] Module B1 (Assert Counts): 4 snapshot(s) found
[−] Module B2 (FTDC Spikes): No FTDC files or decoder unavailable
Analysis Parameters:
Time Window: 4320 minutes
Connection Thresh: 100
Burst Rate Thresh: 400/min
Metadata Rate: 0.10
Spike Threshold: 100
User Ratio Thresh: 250x
Module A - Log Correlation Findings:
Risk SourceIP ConnCount MetaCount DiscCount MetaRate% BurstRate/m FirstSeen (UTC) LastSeen (UTC)
-------- ---------------------------------------- ---------- ---------- ---------- ------------ -------------- ---------------------- ----------------------
HIGH 137.137.137.137 8172 0 8172 0.00% 490.32 2025-12-27T12:55:52Z 2025-12-27T13:12:32Z
Module B1 - Assert Counts Analysis:
Analyzed 4 snapshots from 2025-01-01T10:00:00Z to 2025-01-01T11:30:00Z
asserts.user: 100 -> 860 (delta: 760)
SPIKE DETECTED: 2025-01-01T10:30:00Z to 2025-01-01T11:00:00Z
Delta: +740 user asserts (110 -> 850)
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════
Combined Verdict:
MEDIUM CONFIDENCE - Investigation recommended
- Suspicious connection patterns but FTDC data unavailable for correlation
⚠ IMPORTANT: If exploitation is confirmed, patching alone is insufficient.
- Rotate all credentials that may have been exposed
- Review accessed data for sensitive information disclosure
- Check for lateral movement from affected systems
- Preserve logs for forensic analysis
Caveats:
- Connection metadata absence is PoC-specific and can be evaded
- Assertion counters are cumulative - false positives possible without baseline
- FTDC provides timing but not perfect attribution
- Patch + rotate secrets remains mandatory regardless of detection results
本仓库包含一套测试套件,用于验证检测器。
example-data/ 目录包含来自一台遭受 MongoBleed PoC 攻击的 MongoDB 8.0.16 实例的真实数据:
example-data/
├── logs/ # 包含攻击模式的真实 MongoDB 日志
│ ├── mongod.log
│ └── mongod.log.1.gz
├── assert-counts/ # 攻击后的 serverStatus().asserts 快照
│ └── asserts-post-attack.json
└── ftdc-files/ # 真实 FTDC 诊断数据文件
└── metrics.*
这些数据显示:
./test/generate-test-logs.sh
这会创建包含各种模式的额外合成测试数据:
./test/test-detector.sh
预期输出:
╔════════════════════════════════════════════════════════╗
║ MongoBleed Detector Test Suite ║
╚════════════════════════════════════════════════════════╝
Module A Tests (Log Correlation):
✓ PASS: Exit code is 1 (findings detected)
✓ PASS: Detected source IP 137.137.137.137
...
Module B1 Tests (Assert Counts):
✓ PASS: Shows Module B1 status
✓ PASS: Detected assert spike
...
Auto-Discovery Mode Tests:
✓ PASS: Shows Module A status
✓ PASS: Shows combined verdict
...
Results:
Passed: 24
Failed: 0
All tests passed!
⚠️ 重要局限
针对特定 PoC 的检测:元数据缺失检测基于已知 MongoBleed PoC 行为。老练的攻击者可能修改漏洞利用代码以发送伪造元数据,但这会降低利用速度。
累积计数器:asserts.user 自 mongod 重启以来是累积的。如果没有基线快照,较高的值对于长期运行的实例可能是正常的。随时间采集多个快照可显著提高准确性。
FTDC 时间信息:FTDC 提供时间信息,但无法做到完美归因。请与日志关联分析结合使用以获得最佳效果。
日志保留:只能分析现存日志。激进的日志轮转或攻击者清除日志将销毁证据。
需要 JSON 日志:MongoDB 4.4+ 默认输出 JSON 日志。不支持传统文本日志。
FTDC 解码器:FTDC 解码需要带 pymongo 的 Python 3。否则模块 B2 不可用。
mongosh 访问权限:采集断言计数需要具有相应权限的 mongosh。
如果确认存在 HIGH 或 MEDIUM 级别发现:
本工具的检测逻辑基于 Eric Capuano 和 Tamir Zimerman 的研究:
参见 LICENSE 文件。
欢迎贡献!请提交 issue 和 pull request。
如果您使用本工具对生产数据进行了测试,我们尤其希望获得以下方面的反馈:
| 数据类型 | 来源 | 目标位置 |
|---|
| 日志 | /var/log/mongodb/mongod.log* | <输出目录>/<主机名>/logs/ |
| 断言计数 | mongosh 命令 | <输出目录>/<主机名>/assert-counts/ |
| FTDC 文件 | /var/lib/mongodb/diagnostic.data/metrics.* | <输出目录>/<主机名>/ftdc-files/ |
| 选项 | 描述 | 默认值 |
|---|
-d, --data-dir <path> | 已采集数据的目录(自动发现模式) | - |
-p, --path <glob> | 额外的日志路径/通配符(可重复) | - |
-t, --time <minutes> | 回看窗口(分钟) | 4320(3 天) |
-c, --conn-threshold | 连接数阈值 | 100 |
-b, --burst-threshold | 每分钟突发速率阈值 | 400 |
-m, --metadata-rate | 元数据率阈值(0.0-1.0) | 0.10 |
--spike-threshold | 断言激增阈值 | 100 |
--user-ratio-threshold | 单一快照检测的用户/其他断言比值阈值 | 250 |
--no-default-paths | 跳过默认日志路径 | false |
--forensic-dir <path> | 将子目录作为独立主机进行分析 | - |
| 选项 | 描述 | 默认值 |
|---|
-H, --host <hostname> | 要扫描的远程主机(可重复) | - |
-f, --hosts-file <file> | 包含主机名的文件(每行一个) | - |
-u, --user <user> | SSH 用户名 | 当前用户 |
-k, --key <file> | SSH 私钥文件 | ssh-agent |
-P, --port <port> | SSH 端口 | 22 |
-o, --ssh-options <opt> | 额外的 SSH 选项(可重复) | - |
--sudo | 使用 sudo 访问受权限保护的文件(FTDC) | false |
-O, --output-dir <path> | 存放采集数据的目录 | ./collected-data |
--log-path <path> | 要采集的远程日志路径(可重复) | 标准路径 |
--ftdc-path <path> | 远程 FTDC 目录路径(可重复) | 标准路径 |
--skip-logs | 跳过日志采集 | false |
--skip-asserts | 跳过 serverStatus().asserts 采集 | false |
--skip-ftdc | 跳过 FTDC 文件采集 | false |
--collect-only | 仅采集数据,不运行分析 | false |
-j, --parallel <n> | 并行连接数 | 5 |
--timeout <seconds> | SSH 命令超时时间 | 300 |
-d, --debug | 启用调试输出(显示 SSH 命令) | false |
-q, --quiet | 抑制进度消息 | false |
| 置信度 | 判定标准 | 解释 |
|---|
| HIGH | 检测到 FTDC 峰值 且 同一时间窗口内存在可疑日志 | 漏洞利用的强有力指标 |
| MEDIUM | 检测到 FTDC 峰值 或 存在可疑日志(但未关联) | 建议开展调查 |
| LOW | 仅有累积断言计数,无激增 | 检测到异常,证据较弱 |
| INFO | 未发现显著结果 | 活动正常 |
| INFO | 连接数 < 阈值 |
| 版本 | 受影响版本 | 修复版本 |
|---|
| 8.2.x | 8.2.0 - 8.2.2 | 8.2.3 |
| 8.0.x | 8.0.0 - 8.0.16 | 8.0.17 |
| 7.0.x | 7.0.0 - 7.0.27 | 7.0.28 |
| 6.0.x | 6.0.0 - 6.0.26 | 6.0.27 |
| 5.0.x | 5.0.0 - 5.0.31 | 5.0.32 |
| 4.4.x | 4.4.0 - 4.4.29 | 4.4.30 |
| 4.2.x | 4.2.0+ | 无修复 |
| 4.0.x | 4.0.0+ | 无修复 |
| 3.6.x | 3.6.0+ | 无修复 |