用于 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)。
| 数据类型 | 来源 | 目标位置 |
|---|---|---|
| 日志 | /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 |
| 代码 | 含义 |
|---|---|
| 0 | 未发现 HIGH 或 MEDIUM 级别结果 |
| 1 | 检测到 HIGH 或 MEDIUM 级别结果 |
| 2 | 错误(缺少依赖、无数据等) |
该工具根据所有可用证据提供综合置信度判定:
| 置信度 | 判定标准 | 解释 |
|---|---|---|
| HIGH | 检测到 FTDC 峰值 且 同一时间窗口内存在可疑日志 | 漏洞利用的强有力指标 |
| MEDIUM | 检测到 FTDC 峰值 或 存在可疑日志(但未关联) | 建议开展调查 |
| LOW | 仅有累积断言计数,无激增 | 检测到异常,证据较弱 |
| INFO | 未发现显著结果 | 活动正常 |
对于日志关联分析(模块 A),各个 IP 被分类为:
| 风险 | 判定标准 |
|---|---|
| HIGH | 连接数 ≥ 阈值,元数据率 < 10%,突发速率 ≥ 400/分钟 |
| MEDIUM | 连接数 ≥ 阈值,元数据率 < 10%,突发速率 < 400/分钟 |
| LOW | 连接数 ≥ 阈值,元数据率 ≥ 10% |
| INFO | 连接数 < 阈值 |
INFO: Auto-discovery mode: analyzing ./collected-data/
INFO: Module A: Analyzing 3 log file(s)...
INFO: Module B1: Analyzing assert-counts...