
Script de Detecção para Exploração do MongoBleed
Ferramenta offline de análise do MongoDB para CVE-2025-14847 (MongoBleed)
Uma ferramenta autônoma de linha de comando para Linux que analisa dados do MongoDB para identificar provável exploração de CVE-2025-14847 usando múltiplos módulos de detecção.
MongoBleed (CVE-2025-14847) é uma vulnerabilidade de divulgação de memória na descompactação zlib do MongoDB que permite a atacantes extrair dados sensíveis — credenciais, tokens de sessão, PII — diretamente da memória do servidor sem autenticação.
Esta ferramenta ajuda respondedores a incidentes a detectar tentativas de exploração usando múltiplas fontes de evidência:
Analisa logs JSON do MongoDB para detectar padrões de exploração:
| ID do Evento | Tipo | Descrição |
|---|---|---|
| 22943 | Conexão Aceita | Registrado quando um cliente conecta |
| 51800 | Metadados do Cliente | Registrado quando um cliente envia informações de driver/aplicativo |
| 22944 |
Insight-chave: Drivers legítimos do MongoDB sempre enviam metadados do cliente. O exploit MongoBleed conecta, extrai memória e desconecta — mas nunca envia metadados.
Analisa snapshots de db.serverStatus().asserts para detectar padrões incomuns nos contadores asserts.user:
asserts.user a outros tipos de assert. Se os asserts de usuário forem desproporcionalmente altos (proporção ≥250x) ou todos os outros tipos forem zero, sinaliza como suspeito (confiança MÉDIA)Nota: Contadores cumulativos podem produzir falsos positivos. Use em combinação com FTDC (Módulo B2) para melhores resultados.
Analisa arquivos de Captura de Dados de Diagnóstico em Tempo Integral (FTDC) do MongoDB para detectar picos localizados no tempo nos contadores de assert. O FTDC amostra o serverStatus periodicamente, permitindo a cronometragem precisa de possíveis ataques.
jq - processador de JSONawk (gawk recomendado)gzip - Para suporte a logs compactadospymongo - Para decodificação de arquivos FTDCssh, scp)# Shell script dependencies
# Debian/Ubuntu
apt-get install jq gawk gzip
# RHEL/CentOS/Fedora
dnf install jq gawk gzip
# macOS
brew install jq gawk
# Python dependencies (for FTDC decoding)
pip install -r requirements.txt
# Clone the repository
git clone https://github.com/your-org/mongobleed-detector.git
cd mongobleed-detector
# Make scripts executable
chmod +x mongobleed-detector.sh
chmod +x mongobleed-remote.py
chmod +x ftdc-decode.py
# Install Python dependencies (optional, for FTDC support)
pip install -r requirements.txt
Analise dados que foram coletados manualmente de hosts MongoDB.
Colete automaticamente dados de múltiplos hosts via SSH e depois analise localmente.
Colete dados de seus hosts MongoDB e organize-os nesta estrutura:
./collected-data/
├── logs/ # MongoDB JSON logs
│ ├── mongod.log
│ ├── mongod.log.1
│ └── mongod.log.2.gz
├── assert-counts/ # serverStatus().asserts snapshots
│ ├── asserts-2025-01-01.json
│ └── asserts-2025-01-02.json
└── ftdc-files/ # FTDC diagnostic.data contents
├── metrics.2025-01-02T10-00-00Z-00000
└── metrics.interim
# Copy from remote host
scp user@mongohost:/var/log/mongodb/mongod.log* ./collected-data/logs/
Execute este comando no host MongoDB (requer acesso ao 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
Copie o arquivo JSON resultante para ./collected-data/assert-counts/.
Dica: Execute este comando várias vezes (ex.: a cada hora) para estabelecer uma linha de base e detectar picos.
Os arquivos FTDC estão localizados em:
<storage.dbPath>/diagnostic.data/ (comumente /var/lib/mongodb/diagnostic.data/)systemLog.path (ex.: /var/log/mongodb/mongos.diagnostic.data/)# Copy FTDC files (may require sudo)
sudo cp /var/lib/mongodb/diagnostic.data/metrics.* ./collected-data/ftdc-files/
# Auto-discovery mode - analyzes all available data
./mongobleed-detector.sh --data-dir ./collected-data/
# With custom thresholds
./mongobleed-detector.sh --data-dir ./collected-data/ \
-t 1440 \ # 24-hour lookback
-c 50 \ # Lower connection threshold
--spike-threshold 50 # Lower spike threshold
Para compatibilidade reversa, você ainda pode analisar logs diretamente:
# Scan default paths
./mongobleed-detector.sh
# Scan specific log files
./mongobleed-detector.sh -p /path/to/logs/*.json
# Forensic mode (analyze multiple hosts)
./mongobleed-detector.sh --forensic-dir /evidence/
Colete automaticamente dados de múltiplos hosts e analise:
# Create hosts file
cat > hosts.txt << EOF
mongo-prod-01.example.com
mongo-prod-02.example.com
mongo-staging.example.com
EOF
# Collect and analyze
./mongobleed-remote.py --hosts-file hosts.txt --user admin --output-dir ./collected-data/
# Use specific SSH key
./mongobleed-remote.py --hosts-file hosts.txt --user admin --key ~/.ssh/mongodb_key
# Parallel execution
./mongobleed-remote.py --hosts-file hosts.txt --user admin --parallel 10
# Skip FTDC collection (faster)
./mongobleed-remote.py --hosts-file hosts.txt --user admin --skip-ftdc
# Collect only, analyze later
./mongobleed-remote.py --hosts-file hosts.txt --user admin --collect-only
# Pass SSH options (e.g., jump host)
./mongobleed-remote.py --hosts-file hosts.txt --user admin \
-o "ProxyJump=bastion.example.com"
# Use sudo for privileged file access (FTDC files are often restricted)
./mongobleed-remote.py --hosts-file hosts.txt --user admin --sudo
# Debug mode to troubleshoot connection issues
./mongobleed-remote.py --hosts-file hosts.txt --user admin --debug
Nota sobre Permissões de FTDC: Os arquivos FTDC em
/var/lib/mongodb/diagnostic.data/normalmente pertencem ao usuáriomongodbe não podem ser lidos por usuários comuns. Se você vir avisos de "FTDC Permission Issues", use a flag--sudo. Isso exige que o usuário remoto tenha acesso sudo sem senha (NOPASSWD no sudoers).
| Código | Significado |
|---|---|
| 0 | Nenhum achado ALTO ou MÉDIO |
| 1 | Achados ALTO ou MÉDIO detectados |
| 2 | Erro (dependências ausentes, sem dados, etc.) |
A ferramenta fornece um veredito de confiança combinado com base em todas as evidências disponíveis:
Para correlação de logs (Módulo A), IPs individuais são classificados:
| Risco | Critérios |
|---|---|
| ALTO | Conexões ≥ limite, taxa de metadados < 10%, taxa de rajada ≥ 400/min |
| MÉDIO |
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
O repositório inclui um conjunto de testes para validar o detector.
O diretório example-data/ contém dados reais de uma instância MongoDB 8.0.16 que foi atacada usando o PoC do MongoBleed:
example-data/
├── logs/ # Real MongoDB logs with attack patterns
│ ├── mongod.log
│ └── mongod.log.1.gz
├── assert-counts/ # Post-attack serverStatus().asserts snapshot
│ └── asserts-post-attack.json
└── ftdc-files/ # Real FTDC diagnostic data files
└── metrics.*
Estes dados mostram:
./test/generate-test-logs.sh
Isso cria dados de teste sintéticos adicionais com vários padrões:
./test/test-detector.sh
Saída esperada:
╔════════════════════════════════════════════════════════╗
║ 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!
⚠️ Limitações Importantes
Detecção Específica de PoC: A detecção de ausência de metadados é baseada no comportamento conhecido do PoC do MongoBleed. Um atacante sofisticado poderia modificar o exploit para enviar metadados falsos, embora isso reduzisse a velocidade de exploração.
Contadores Cumulativos: asserts.user é cumulativo desde a reinicialização do mongod. Sem snapshots de linha de base, valores altos podem ser normais para instâncias de longa duração. Múltiplos snapshots ao longo do tempo melhoram significativamente a precisão.
Temporização do FTDC: O FTDC fornece informações de temporização, mas não atribuição perfeita. Use em conjunto com a correlação de logs para melhores resultados.
Retenção de Logs: Só é possível analisar logs que existem. Rotação agressiva ou limpeza de logs pelo atacante destruirá as evidências.
Registro em JSON Obrigatório: MongoDB 4.4+ usa logs JSON por padrão. Logs de texto legados não são suportados.
Decodificador FTDC: A decodificação de FTDC requer Python 3 com pymongo. Sem isso, o Módulo B2 fica indisponível.
Acesso ao mongosh: Coletar contadores de assert requer mongosh com permissões apropriadas.
Se achados ALTO ou MÉDIO forem confirmados:
A lógica de detecção desta ferramenta é baseada em pesquisa de Eric Capuano e Tamir Zimerman:
Consulte o arquivo LICENSE.
Contribuições são bem-vindas! Envie issues e pull requests.
Se você testar esta ferramenta com dados de produção, apreciaríamos especialmente feedback sobre:
| Conexão Fechada |
| Registrado quando um cliente desconecta |
| Tipo de Dado | Origem | Destino |
|---|
| Logs | /var/log/mongodb/mongod.log* | <output-dir>/<hostname>/logs/ |
| Contadores de Assert | comando mongosh | <output-dir>/<hostname>/assert-counts/ |
| Arquivos FTDC | /var/lib/mongodb/diagnostic.data/metrics.* | <output-dir>/<hostname>/ftdc-files/ |
| Opção | Descrição | Padrão |
|---|
-d, --data-dir <path> | Diretório com dados coletados (modo de descoberta automática) | - |
-p, --path <glob> | Caminho/glob de log adicional (repetível) | - |
-t, --time <minutes> | Janela de retrospectiva em minutos | 4320 (3 dias) |
-c, --conn-threshold | Limite de contagem de conexões | 100 |
-b, --burst-threshold | Limite de taxa de rajada por minuto | 400 |
-m, --metadata-rate | Limite de taxa de metadados (0.0-1.0) | 0.10 |
--spike-threshold | Limite de pico de assert | 100 |
--user-ratio-threshold | Proporção de assert usuário/outros para detecção de snapshot único | 250 |
--no-default-paths | Ignorar caminhos de log padrão | false |
--forensic-dir <path> | Analisar subdiretórios como hosts separados | - |
| Opção | Descrição | Padrão |
|---|
-H, --host <hostname> | Host remoto para escanear (repetível) | - |
-f, --hosts-file <file> | Arquivo contendo hostnames (um por linha) | - |
-u, --user <user> | Nome de usuário SSH | Usuário atual |
-k, --key <file> | Arquivo de chave privada SSH | ssh-agent |
-P, --port <port> | Porta SSH | 22 |
-o, --ssh-options <opt> | Opções SSH adicionais (repetível) | - |
--sudo | Usar sudo para acesso privilegiado a arquivos (FTDC) | false |
-O, --output-dir <path> | Diretório para armazenar dados coletados | ./collected-data |
--log-path <path> | Caminho de log remoto para coletar (repetível) | Caminhos padrão |
--ftdc-path <path> | Caminho do diretório FTDC remoto (repetível) | Caminhos padrão |
--skip-logs | Ignorar coleta de logs | false |
--skip-asserts | Ignorar coleta de serverStatus().asserts | false |
--skip-ftdc | Ignorar coleta de arquivos FTDC | false |
--collect-only | Apenas coletar dados, não executar análise | false |
-j, --parallel <n> | Número de conexões paralelas | 5 |
--timeout <seconds> | Tempo limite do comando SSH | 300 |
-d, --debug | Habilitar saída de depuração (mostrar comandos SSH) | false |
-q, --quiet | Suprimir mensagens de progresso | false |
| Confiança | Critérios | Interpretação |
|---|
| ALTO | Picos de FTDC detectados E logs suspeitos na mesma janela de tempo | Forte indicador de exploração |
| MÉDIO | Picos de FTDC OU logs suspeitos (não correlacionados) | Investigação recomendada |
| BAIXO | Apenas contadores cumulativos de assert sem picos | Anomalia detectada, evidência fraca |
| INFO | Nenhum achado significativo | Atividade normal |
| Conexões ≥ limite, taxa de metadados < 10%, taxa de rajada < 400/min |
| BAIXO | Conexões ≥ limite, taxa de metadados ≥ 10% |
| INFO | Conexões < limite |
| Versão | Vulnerável | Corrigida Em |
|---|
| 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+ | Sem correção |
| 4.0.x | 4.0.0+ | Sem correção |
| 3.6.x | 3.6.0+ | Sem correção |