
Detection Script for MongoBleed Exploitation
Офлайн-инструмент анализа MongoDB для CVE-2025-14847 (MongoBleed)
Автономный инструмент командной строки для Linux, который анализирует данные MongoDB для выявления вероятной эксплуатации уязвимости CVE-2025-14847 с использованием нескольких модулей обнаружения.
MongoBleed (CVE-2025-14847) — это уязвимость раскрытия памяти в декомпрессии zlib MongoDB, позволяющая злоумышленникам извлекать конфиденциальные данные — учётные данные, токены сессий, PII — напрямую из памяти сервера без аутентификации.
Этот инструмент помогает специалистам по реагированию на инциденты обнаруживать попытки эксплуатации, используя несколько источников доказательств:
Анализирует JSON-журналы MongoDB для выявления шаблонов эксплуатации:
| ID события | Тип | Описание |
|---|---|---|
| 22943 | Соединение принято | Регистрируется при подключении клиента |
| 51800 | Метаданные клиента | Регистрируется, когда клиент отправляет информацию о драйвере/приложении |
Ключевое наблюдение: Легитимные драйверы MongoDB всегда отправляют метаданные клиента. Эксплойт MongoBleed подключается, извлекает память и отключается, но никогда не отправляет метаданные.
Анализирует снимки db.serverStatus().asserts для обнаружения необычных паттернов в счётчике asserts.user:
asserts.user с другими типами assertов. Если пользовательские assertы непропорционально высоки (отношение ≥250x) или все остальные типы равны нулю, помечается как подозрительный (СРЕДНИЙ уровень уверенности)Примечание: Кумулятивные счётчики могут давать ложные срабатывания. Для наилучших результатов используйте в комбинации с модулем FTDC (Модуль B2).
Анализирует файлы полного диагностического сбора данных (FTDC) MongoDB для выявления локализованных по времени всплесков счётчиков assert. FTDC периодически снимает показания serverStatus, что позволяет точно определить время потенциальной атаки.
jq — обработчик JSONawk (рекомендуется gawk)gzip — поддержка сжатых журналовpymongo — декодирование файлов FTDCssh, 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/ # JSON-журналы MongoDB
│ ├── 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/ # Содержимое diagnostic.data FTDC
├── 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: Файлы FTDC в
/var/lib/mongodb/diagnostic.data/обычно принадлежат пользователюmongodbи не читаются обычными пользователями. Если вы видите предупреждения о "Проблемах с правами FTDC", используйте флаг--sudo. Для этого требуется, чтобы удалённый пользователь имел доступ sudo без пароля (NOPASSWD в sudoers).
| Код | Значение |
|---|---|
| 0 | Обнаружения с ВЫСОКИМ или СРЕДНИМ уровнем не найдены |
| 1 | Обнаружены нарушения с ВЫСОКИМ или СРЕДНИМ уровнем |
| 2 | Ошибка (отсутствуют зависимости, нет данных и т.д.) |
Инструмент предоставляет комбинированный вердикт на основе всех доступных доказательств:
Для корреляции журналов (Модуль A) отдельные IP-адреса классифицируются:
| Риск | Критерии |
|---|---|
| ВЫСОКИЙ | Соединений ≥ порог, доля метаданных < 10%, частота всплесков ≥ 400/мин |
| СРЕДНИЙ |
ИНФО: Режим автообнаружения: анализ ./collected-data/
ИНФО: Модуль A: Анализ 3 файла(ов) журналов...
ИНФО: Модуль B1: Анализ счётчиков assert...
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ Результаты обнаружения MongoBleed (CVE-2025-14847) ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
Состояние модулей:
[✓] Модуль A (Корреляция журналов): 3 файла(ов) журналов найдено
[✓] Модуль B1 (Счётчики assert): 4 снимка(ов) найдено
[−] Модуль B2 (Всплески FTDC): Нет файлов FTDC или декодер недоступен
Параметры анализа:
Временное окно: 4320 минут
Порог соединений: 100
Порог всплесков: 400/мин
Доля метаданных: 0.10
Порог всплесков: 100
Порог отношения: 250x
Модуль A - Корреляция журналов:
Риск IP-источник Кол-во подкл. Кол-во мета Кол-во откл. Доля мета% Всплески/мин Первый сеанс (UTC) Последний сеанс (UTC)
-------- ---------------------------------------- ------------ ----------- ------------ ------------ -------------- ---------------------- ----------------------
ВЫСОКИЙ 137.137.137.137 8172 0 8172 0.00% 490.32 2025-12-27T12:55:52Z 2025-12-27T13:12:32Z
Модуль B1 - Анализ счётчиков assert:
Проанализировано 4 снимка с 2025-01-01T10:00:00Z по 2025-01-01T11:30:00Z
asserts.user: 100 -> 860 (дельта: 760)
ОБНАРУЖЕН ВСПЛЕСК: 2025-01-01T10:30:00Z по 2025-01-01T11:00:00Z
Дельта: +740 пользовательских assert`ов (110 -> 850)
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════
Комбинированный вердикт:
СРЕДНИЙ УРОВЕНЬ УВЕРЕННОСТИ - Рекомендуется расследование
- Подозрительные паттерны соединений, но данные FTDC недоступны для корреляции
⚠ ВАЖНО: Если эксплуатация подтверждена, одного исправления недостаточно.
- Смените все учётные данные, которые могли быть раскрыты
- Проверьте доступ к данным на предмет раскрытия конфиденциальной информации
- Проверьте наличие бокового перемещения с затронутых систем
- Сохраните журналы для криминалистического анализа
Предостережения:
- Отсутствие метаданных соединения является особенностью PoC и может быть обойдено
- Счётчики assert`ов кумулятивны — возможны ложные срабатывания без базовой линии
- FTDC предоставляет привязку по времени, но не точную атрибуцию
- Исправление + смена секретов остаётся обязательным независимо от результатов обнаружения
Репозиторий включает набор тестов для проверки детектора.
Каталог example-data/ содержит реальные данные экземпляра MongoDB 8.0.16, который был атакован с использованием PoC MongoBleed:
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 ║
╚════════════════════════════════════════════════════════╝
Тесты модуля A (Корреляция журналов):
✓ ПРОЙДЕН: Код завершения 1 (обнаружены нарушения)
✓ ПРОЙДЕН: Обнаружен IP-источник 137.137.137.137
...
Тесты модуля B1 (Счётчики assert):
✓ ПРОЙДЕН: Отображается статус модуля B1
✓ ПРОЙДЕН: Обнаружен всплеск assert`ов
...
Тесты режима автообнаружения:
✓ ПРОЙДЕН: Отображается статус модуля A
✓ ПРОЙДЕН: Отображается комбинированный вердикт
...
Результаты:
Пройдено: 24
Провалено: 0
Все тесты пройдены!
⚠️ Важные ограничения
Специфичность для PoC: Обнаружение отсутствия метаданных основано на известном поведении PoC MongoBleed. Искушённый злоумышленник может изменить эксплойт для отправки поддельных метаданных, хотя это снизит скорость эксплуатации.
Кумулятивные счётчики: asserts.user является кумулятивным с момента перезапуска mongod. Без базовых снимков высокие значения могут быть нормальными для долго работающих экземпляров. Несколько снимков во времени значительно повышают точность.
Привязка по времени FTDC: FTDC предоставляет информацию о времени, но не точную атрибуцию. Используйте совместно с корреляцией журналов для наилучших результатов.
Хранение журналов: Можно анализировать только те журналы, которые существуют. Агрессивная ротация или удаление журналов злоумышленником уничтожат доказательства.
Необходимость JSON-журналов: MongoDB 4.4+ по умолчанию использует JSON-журналы. Устаревшие текстовые журналы не поддерживаются.
Декодер FTDC: Декодирование FTDC требует Python 3 с pymongo. Без него модуль B2 недоступен.
Доступ к mongosh: Для сбора счётчиков assert требуется mongosh с соответствующими правами.
Если подтверждены находки с ВЫСОКИМ или СРЕДНИМ уровнем:
Логика обнаружения в этом инструменте основана на исследованиях Эрика Капуано и Тамира Цимермана:
См. файл LICENSE.
Приветствуются вклады! Пожалуйста, оставляйте проблемы и пулл-реквесты.
Если вы тестируете этот инструмент на реальных данных, мы будем особенно благодарны за отзывы о:
| 22944 |
| Соединение закрыто |
| Регистрируется при отключении клиента |
| Тип данных | Источник | Назначение |
|---|
| Журналы | /var/log/mongodb/mongod.log* | <output-dir>/<hostname>/logs/ |
| Счётчики assert | Команда mongosh | <output-dir>/<hostname>/assert-counts/ |
| Файлы FTDC | /var/lib/mongodb/diagnostic.data/metrics.* | <output-dir>/<hostname>/ftdc-files/ |
| Параметр | Описание | По умолчанию |
|---|
-d, --data-dir <путь> | Каталог с собранными данными (режим автообнаружения) | - |
-p, --path <glob> | Дополнительный путь/маска журналов (повторяемый) | - |
-t, --time <минуты> | Окно ретроспективы в минутах | 4320 (3 дня) |
-c, --conn-threshold | Порог количества соединений | 100 |
-b, --burst-threshold | Порог частоты всплесков в минуту | 400 |
-m, --metadata-rate | Порог доли метаданных (0.0-1.0) | 0.10 |
--spike-threshold | Порог всплеска assert`ов | 100 |
--user-ratio-threshold | Отношение пользовательских/других assert`ов для обнаружения по одному снимку | 250 |
--no-default-paths | Пропустить пути журналов по умолчанию | false |
--forensic-dir <путь> | Анализировать подкаталоги как отдельные хосты | - |
| Параметр | Описание | По умолчанию |
|---|
-H, --host <hostname> | Удалённый хост для сканирования (повторяемый) | - |
-f, --hosts-file <файл> | Файл со списком хостов (по одному на строку) | - |
-u, --user <пользователь> | SSH-пользователь | Текущий пользователь |
-k, --key <файл> | SSH-ключ (файл) | ssh-agent |
-P, --port <порт> | SSH-порт | 22 |
-o, --ssh-options <опция> | Дополнительные SSH-опции (повторяемые) | - |
--sudo | Использовать sudo для доступа к привилегированным файлам (FTDC) | false |
-O, --output-dir <путь> | Каталог для сохранения собранных данных | ./collected-data |
--log-path <путь> | Удалённый путь к журналам для сбора (повторяемый) | Стандартные пути |
--ftdc-path <путь> | Удалённый путь к каталогу FTDC (повторяемый) | Стандартные пути |
--skip-logs | Пропустить сбор журналов | false |
--skip-asserts | Пропустить сбор serverStatus().asserts | false |
--skip-ftdc | Пропустить сбор файлов FTDC | false |
--collect-only | Только сбор данных, без анализа | false |
-j, --parallel <n> | Количество параллельных соединений | 5 |
--timeout <секунды> | Тайм-аут SSH-команд | 300 |
-d, --debug | Включить отладочный вывод (показывать SSH-команды) | false |
-q, --quiet | Подавлять сообщения о ходе выполнения | false |
| Уверенность | Критерии | Интерпретация |
|---|
| ВЫСОКИЙ | Обнаружены пики FTDC И подозрительные журналы в том же временном окне | Сильный индикатор эксплуатации |
| СРЕДНИЙ | Пики FTDC ИЛИ подозрительные журналы (не коррелированы) | Рекомендуется расследование |
| НИЗКИЙ | Только кумулятивные счётчики assert без всплесков | Обнаружена аномалия, слабое доказательство |
| ИНФО | Значимых находок нет | Нормальная активность |
| Соединений ≥ порог, доля метаданных < 10%, частота всплесков < 400/мин |
| НИЗКИЙ | Соединений ≥ порог, доля метаданных ≥ 10% |
| ИНФО | Соединений < порог |
| Версия | Уязвима | Исправлено в |
|---|
| 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+ | Нет исправления |