
Script de détection pour l'exploitation de MongoBleed
Outil d'analyse MongoDB hors ligne pour CVE-2025-14847 (MongoBleed)
Un outil Linux autonome en ligne de commande qui analyse les données MongoDB afin d'identifier une exploitation probable de CVE-2025-14847 à l'aide de multiples modules de détection.
MongoBleed (CVE-2025-14847) est une vulnérabilité de divulgation de mémoire dans la décompression zlib de MongoDB qui permet aux attaquants d'extraire des données sensibles — identifiants, jetons de session, données personnelles — directement depuis la mémoire du serveur sans authentification.
Cet outil aide les répondants aux incidents à détecter les tentatives d'exploitation à partir de multiples sources de preuves :
Analyse les journaux JSON MongoDB pour détecter les schémas d'exploitation :
| ID d'événement | Type | Description |
|---|---|---|
| 22943 | Connexion acceptée | Journalisé lorsqu'un client se connecte |
| 51800 | Métadonnées client | Journalisé lorsqu'un client envoie les informations pilote/application |
Point clé : Les pilotes MongoDB légitimes envoient toujours des métadonnées client. L'exploit MongoBleed se connecte, extrait la mémoire et se déconnecte — mais n'envoie jamais de métadonnées.
Analyse les instantanés de db.serverStatus().asserts pour détecter des schémas inhabituels dans les compteurs asserts.user :
asserts.user aux autres types d'assertions. Si les assertions utilisateur sont disproportionnellement élevées (ratio ≥250x) ou si tous les autres types sont à zéro, signale comme suspect (confiance MOYENNE)Remarque : Les compteurs cumulés peuvent produire des faux positifs. À utiliser en combinaison avec FTDC (module B2) pour de meilleurs résultats.
Analyse les fichiers de capture de données de diagnostic en continu (FTDC) de MongoDB pour détecter des pics localisés dans le temps des compteurs d'assertions. FTDC échantillonne l'état du serveur périodiquement, permettant un minutage précis des attaques potentielles.
jq - Processeur JSONawk (gawk recommandé)gzip - Pour la prise en charge des journaux compresséspymongo - Pour le décodage des fichiers 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
Analysez les données collectées manuellement à partir des hôtes MongoDB.
Collectez automatiquement les données de plusieurs hôtes via SSH, puis analysez-les localement.
Collectez les données de vos hôtes MongoDB et organisez-les selon cette structure :
./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/
Exécutez cette commande sur l'hôte MongoDB (nécessite un accès 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
Copiez le fichier JSON résultant dans ./collected-data/assert-counts/.
Astuce : Exécutez cette commande plusieurs fois (par exemple, toutes les heures) pour établir une référence et détecter les pics.
Les fichiers FTDC se trouvent à :
<storage.dbPath>/diagnostic.data/ (généralement /var/lib/mongodb/diagnostic.data/)systemLog.path (par exemple, /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
Pour la compatibilité ascendante, vous pouvez toujours analyser les journaux directement :
# 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/
Collectez automatiquement les données de plusieurs hôtes et analysez-les :
# 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
Remarque sur les permissions FTDC : Les fichiers FTDC dans
/var/lib/mongodb/diagnostic.data/appartiennent généralement à l'utilisateurmongodbet ne sont pas lisibles par les utilisateurs ordinaires. Si vous voyez des avertissements « Problèmes de permission FTDC », utilisez l'option--sudo. Cela nécessite que l'utilisateur distant dispose d'un accès sudo sans mot de passe (NOPASSWD dans sudoers).
| Code | Signification |
|---|---|
| 0 | Aucun résultat ÉLEVÉ ou MOYEN |
| 1 | Résultats ÉLEVÉ ou MOYEN détectés |
| 2 | Erreur (dépendances manquantes, absence de données, etc.) |
L'outil fournit un verdict de confiance combiné basé sur toutes les preuves disponibles :
Pour la corrélation de journaux (module A), les IP individuelles sont classées :
| Risque | Critères |
|---|---|
| ÉLEVÉ | Connexions ≥ seuil, taux de métadonnées < 10 %, taux de rafale ≥ 400/min |
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
Le répertoire example-data/ contient des données réelles provenant d'une instance MongoDB 8.0.16 attaquée à l'aide du PoC 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.*
Ces données montrent :
./test/generate-test-logs.sh
Cela crée des données de test synthétiques supplémentaires avec divers schémas :
./test/test-detector.sh
Sortie attendue :
╔════════════════════════════════════════════════════════╗
║ 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!
⚠️ Limitations importantes
asserts.user est cumulé depuis le redémarrage de mongod. Sans instantanés de référence, des valeurs élevées peuvent être normales pour des instances fonctionnant depuis longtemps. Plusieurs instantanés dans le temps améliorent considérablement la précision.Si des résultats ÉLEVÉ ou MOYEN sont confirmés :
La logique de détection de cet outil est basée sur les recherches d'Eric Capuano et de Tamir Zimerman :
Voir le fichier LICENSE.
Les contributions sont les bienvenues ! N'hésitez pas à soumettre des issues et des pull requests.
Si vous testez cet outil sur des données de production, nous apprécierions particulièrement vos retours sur :
| 22944 | Connexion fermée | Journalisé lorsqu'un client se déconnecte |
| Type de données | Source | Destination |
|---|
| Journaux | /var/log/mongodb/mongod.log* | <output-dir>/<hostname>/logs/ |
| Compteurs d'assertions | commande mongosh | <output-dir>/<hostname>/assert-counts/ |
| Fichiers FTDC | /var/lib/mongodb/diagnostic.data/metrics.* | <output-dir>/<hostname>/ftdc-files/ |
| Option | Description | Défaut |
|---|
-d, --data-dir <path> | Répertoire contenant les données collectées (mode découverte automatique) | - |
-p, --path <glob> | Chemin/glob de journal supplémentaire (répétable) | - |
-t, --time <minutes> | Fenêtre de rétrospection en minutes | 4320 (3 jours) |
-c, --conn-threshold | Seuil de nombre de connexions | 100 |
-b, --burst-threshold | Seuil de taux de rafale par minute | 400 |
-m, --metadata-rate | Seuil de taux de métadonnées (0.0-1.0) | 0.10 |
--spike-threshold | Seuil de pic d'assertions | 100 |
--user-ratio-threshold | Ratio assertions utilisateur/autres pour la détection par instantané unique | 250 |
--no-default-paths | Ignorer les chemins de journaux par défaut | false |
--forensic-dir <path> | Analyser les sous-répertoires comme des hôtes distincts | - |
| Option | Description | Défaut |
|---|
-H, --host <hostname> | Hôte distant à scanner (répétable) | - |
-f, --hosts-file <file> | Fichier contenant les noms d'hôtes (un par ligne) | - |
-u, --user <user> | Nom d'utilisateur SSH | Utilisateur actuel |
-k, --key <file> | Fichier de clé privée SSH | ssh-agent |
-P, --port <port> | Port SSH | 22 |
-o, --ssh-options <opt> | Options SSH supplémentaires (répétables) | - |
--sudo | Utiliser sudo pour l'accès aux fichiers privilégiés (FTDC) | false |
-O, --output-dir <path> | Répertoire pour stocker les données collectées | ./collected-data |
--log-path <path> | Chemin de journal distant à collecter (répétable) | Chemins standard |
--ftdc-path <path> | Chemin du répertoire FTDC distant (répétable) | Chemins standard |
--skip-logs | Ignorer la collecte des journaux | false |
--skip-asserts | Ignorer la collecte de serverStatus().asserts | false |
--skip-ftdc | Ignorer la collecte des fichiers FTDC | false |
--collect-only | Collecter uniquement les données, ne pas exécuter l'analyse | false |
-j, --parallel <n> | Nombre de connexions parallèles | 5 |
--timeout <seconds> | Délai d'expiration des commandes SSH | 300 |
-d, --debug | Activer la sortie de débogage (afficher les commandes SSH) | false |
-q, --quiet | Supprimer les messages de progression | false |
| Confiance | Critères | Interprétation |
|---|
| ÉLEVÉE | Pics FTDC détectés ET journaux suspects dans la même fenêtre temporelle | Indicateur fort d'exploitation |
| MOYENNE | Pics FTDC OU journaux suspects (non corrélés) | Investigation recommandée |
| FAIBLE | Uniquement des compteurs d'assertions cumulés sans pics | Anomalie détectée, preuves faibles |
| INFO | Aucun résultat significatif | Activité normale |
| Connexions ≥ seuil, taux de métadonnées < 10 %, taux de rafale < 400/min |
| FAIBLE | Connexions ≥ seuil, taux de métadonnées ≥ 10 % |
| INFO | Connexions < seuil |
| Version | Vulnérable | Corrigée dans |
|---|
| 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+ | Aucun correctif |
| 4.0.x | 4.0.0+ | Aucun correctif |
| 3.6.x | 3.6.0+ | Aucun correctif |