РАЗБОР
Статья
Утечка данных Elasticsearch: разбор LimeLeads
[ обложка статьи ]
Режим чтения
Понедельник, 09:15. Алерт в Slack от Shodan-монитора: на ASN организации обнаружен Elasticsearch с открытым портом 9200. Через двадцать минут - подтверждение: staging-нода с копией production-индексов, 17 тысяч записей клиентов без аутентификации. Нода висела в открытом доступе 11 дней. Мы поймали вовремя.
B2B-брокеру данных LimeLeads повезло меньше: в 2019 году 17 838 396 записей - email-адреса, должности, работодатели, телефоны, геолокация - ушли в даркнет через точно такую же misconfiguration. По данным ZDNet и Have I Been Pwned, записи LimeLeads были выставлены на продажу. Сервис компании с тех пор не работает.
Не zero-day, не APT-группировка. Дефолтный конфиг, который никто не проверил после деплоя. Разберём kill chain этого инцидента, дам пошаговый аудит собственных ES-нод и покажу detection-правила для SIEM, которые ловят экспозицию до того, как данные уйдут наружу.
Kill chain утечки LimeLeads: от сканирования открытых портов до продажи данных
Бизнес-логика атаки: зачем атакующему открытый Elasticsearch
Открытые базы данных в сети - конвейер. Атакующий не выбирает конкретную компанию. Автоматизированный скрипт через Shodan или Censys находит ES-инстансы с открытым портом 9200, проверяет отсутствие auth и выгружает индексы. Два сценария монетизации: Подробнее - в нашем обзоре asset management пентест.Продажа дампов. Записи LimeLeads содержали business email, job title, employer, phone - готовая база для spear-phishing кампаний. Аналогичная утечка Data & Leads (ноябрь 2018, 44 млн записей через незащищённый Elasticsearch) была обнаружена Бобом Дьяченко при рутинном Shodan-аудите - база просто валялась открытой в интернете, пока кто-то не обратил внимание.
Вымогательство. Кампании вымогательства через незащищённый Elasticsearch фиксировались неоднократно: атакующие сносят содержимое индексов и оставляют записку с требованием выкупа - как правило, несколько сотен долларов за индекс. Фокус в том, что данные просто удаляются, резервных копий атакующий не хранит. Платить бессмысленно, и реальных выплат крайне мало.
TTPs по MITRE ATT&CK
Цепочка атаки на незащищённый Elasticsearch укладывается в шесть техник:| Этап | Техника MITRE ATT&CK | Что происходит |
|---|---|---|
| Разведка | Scanning IP Blocks (T1595.001, Reconnaissance) | Массовое сканирование диапазонов на порт 9200/9300 |
| Разведка | Scan Databases (T1596.005, Reconnaissance) | Поиск открытых ES через Shodan, Censys, BinaryEdge |
| Начальный доступ | Exploit Public-Facing Application (T1190, Initial Access) | Подключение к ES API без аутентификации |
| Обнаружение | File and Directory Discovery (T1083, Discovery) | Перечисление индексов через _cat/indices |
| Сбор | Databases (T1213.006, Collection) | Выгрузка содержимого через _search API с пагинацией |
| Эксфильтрация | Exfiltration to Cloud Storage (T1567.002, Exfiltration) | Отправка дампов на внешнее хранилище |
Если в индексах хранятся учётные данные - дополнительно срабатывает Credentials In Files (T1552.001, Credential Access). Вся цепочка от сканирования до эксфильтрации занимает минуты, а не часы - у атакующего всё автоматизировано. По OWASP Top 10 (2021) корневая причина - A05: Security Misconfiguration. Не уязвимость кода, не слабый алгоритм шифрования (хотя A02: Cryptographic Failures тоже актуален, когда данные в индексах лежат без шифрования at rest) - просто незакрытый дефолт.
Аудит безопасности Elasticsearch: проверка экспозиции базы данных
Аудит экспозиции сводится к трём вопросам: слушает ли ES внешний интерфейс, доступен ли порт извне, включена ли аутентификация.
Проверка binding и аутентификации изнутри
Откройтеelasticsearch.yml и найдите network.host. Значение 0.0.0.0 или внешний IP - нода принимает соединения на всех интерфейсах. Для production допустимы только localhost или адрес из приватной подсети (10.x.x.x, 172.16.x.x, 192.168.x.x).
Bash:
# 1. На каком интерфейсе слушает ES
ss -tlnp | grep -E '9200|9300'
# Норма: 127.0.0.1:9200 - Проблема: 0.0.0.0:9200
# 2. Аутентификация включена?
curl -s -o /dev/null -w "%{http_code}" http://localhost:9200/
# Норма: 401 - Проблема: 200
# 3. X-Pack Security активен?
curl -s http://localhost:9200/_cat/indices/.security*
# Пусто = модуль не активирован
curl возвращает HTTP 200 и JSON с именем кластера без запроса credentials - аутентификация Elasticsearch отключена. Точка. Дополнительно проверьте ответ на GET /_cluster/settings и GET /_xpack/security - оба должны требовать авторизацию.Shodan: поиск уязвимых серверов снаружи
Проверьте собственные IP через Shodan. Запросport:9200 "elastic indices" org:"YOUR_ORG" покажет, видны ли ваши ноды извне. Censys-эквивалент: services.port=9200 AND services.software.product="Elasticsearch".Внутренняя проверка может показать, что
network.host настроен на приватный IP, но Security Group в облаке или ошибка в firewall-правилах пропускает трафик снаружи. Классический сценарий misconfiguration базы данных: инженер разворачивает ES на EC2-инстансе без auth для тестирования в staging, конфигурацию копируют в production - и забывают включить аутентификацию. Внешний скан через Shodan ловит именно такие случаи.На практике я настраивал cron-задачу с Shodan CLI (
shodan search --fields ip_str,port,org 'port:9200 org:"YOUR_ORG"'), которая раз в сутки сканирует ASN организации и кидает алерт в Slack при обнаружении открытых портов 9200/9300. Так мы нашли ту самую «забытую» тестовую ноду из начала статьи - staging с копией production-индексов.Hardening Elasticsearch: защита от утечки данных через misconfiguration
После применения -
elasticsearch-setup-passwords interactive для установки паролей встроенных учёток (elastic, kibana_system, logstash_system). Генерация TLS-сертификатов - через elasticsearch-certutil ca для CA и elasticsearch-certutil cert для нод. Transport TLS (порт 9300) обязателен для кластера. HTTP TLS (порт 9200) обязателен для production - без него credentials летят в открытом виде.На уровне firewall: порт 9200 открыт только для приватной подсети приложений через
firewall-cmd --zone=work --add-rich-rule='rule family="ipv4" source address="10.0.1.0/24" port port="9200" protocol="tcp" accept' --permanent, затем firewall-cmd --reload. Порт 9300 - только для IP других нод кластера.RBAC. Создайте роли с минимальными привилегиями. Приложение для записи логов не должно иметь доступа к
_cluster/settings. Kibana-пользователь для дашбордов - read-only на конкретные index patterns. Это защита не только от внешней утечки данных, но и от скомпрометированного легитимного хоста внутри периметра.Detection: правила корреляции для мониторинга незащищённого Elasticsearch
Без detection-правил misconfiguration останется незамеченной. В кейсе Data & Leads точная длительность экспозиции неизвестна. В случае утечки LimeLeads - тоже: компания узнала постфактум.
Правила для SIEM
Правило 1: внешний доступ к порту 9200. Входящее TCP-соединение на 9200 с IP вне whitelist. Severity: Critical.
YAML:
title: External Access to Elasticsearch API
logsource:
category: firewall
# NB: добавьте product (e.g. paloalto) или custom field mapping для корректной конвертации sigma-cli
detection:
selection:
dst_port: 9200
filter_internal:
src_ip|cidr:
- '10.0.0.0/8'
- '172.16.0.0/12'
- '192.168.0.0/16'
condition: selection and not filter_internal
level: critical
_search или scroll API с одного IP за 5 минут. Источник - ES audit log, включённый параметром xpack.security.audit.enabled: true.Правило 3: разведка служебных endpoint'ов. Запросы к
_cat/indices, _cluster/health, _nodes с нового IP. Это первое, что делает атакующий после обнаружения открытого инстанса - перечисляет индексы и оценивает, стоит ли возиться с выгрузкой.Правило 4: удаление или перезапись индексов.
DELETE /<index> или PUT /<index> с источника вне CI/CD-пайплайна. Характерный IOC вымогательских кампаний: атакующий сносит данные и создаёт индекс с запиской о выкупе.Insider threat и скомпрометированные легитимные хосты
Firewall-правила и фильтры на внешний IP не спасут от скомпрометированного хоста внутри доверенной сети. Тут нужна корреляция ES audit log с CMDB:- Аномальный источник. Рабочая станция бухгалтера делает
_searchпо индексу с клиентскими данными - это аномалия. Baseline строится по паре "source IP / target index" за 30 дней. - Нехарактерный объём. Легитимное приложение выгружает N документов в час. Резкий рост - алерт. Audit log фиксирует количество запросов и объём ответов.
- Доступ вне рабочего времени. Запросы к production-индексам с 02:00 до 06:00 с внутреннего IP - повод копнуть глубже.
Мониторинг экспозиции снаружи
Помимо SIEM-правил, три дополнительных слоя:- Shodan/Censys-скан ASN раз в сутки через API с алертом при обнаружении порта 9200
- Wazuh SCA-модуль для проверки
elasticsearch.ymlна соответствие hardening-baseline - IaC-проверки при деплое: Terraform plan или Ansible lint блокируют
network.host: 0.0.0.0в production workspace
Правовой контекст: оборотные штрафы за экспозицию базы данных в интернет
Для российских компаний экспозиция Elasticsearch с персональными данными - прямое нарушение ФЗ-152. С декабря 2024 года действуют оборотные штрафы за утечку ПДн: до 3% годовой выручки при повторном нарушении, минимум 25 млн рублей. Утечка масштаба LimeLeads 2019 года (17,8 млн записей) - это верхняя планка.Согласно ст. 22 ФЗ-152, оператор обязан уведомить Роскомнадзор перед началом обработки ПДн. На практике команды разворачивают ES-кластер для "временного" хранения логов с email и IP пользователей - и не классифицируют это как обработку персональных данных. Когда данные утекают через открытый порт, включается полный набор санкций. Для международных компаний добавляется GDPR: утечка Decathlon через незащищённый ES в 2020 году затронула данных граждан ЕС - штраф по GDPR мог бы составить до 4% глобальной выручки, потенциально десятки миллионов евро.
Девять из десяти утечек Elasticsearch, которые я разбирал в post-mortem отчётах, имели одну корневую причину - дефолтный конфиг после деплоя.
network.host: 0.0.0.0 и отсутствие xpack.security.enabled: true. Проблема не техническая - процессная.Hardening-чеклист для ES занимает полстраницы и выполняется за час, но в большинстве организаций его нет в pipeline деплоя. До версии 7.1 X-Pack Security был платным - и тысячи инсталляций работали без аутентификации годами. Модуль давно бесплатен, а привычка "сначала развернём - потом закроем" осталась.
Единственное надёжное решение - проверка конфигурации как кода. Terraform plan не пропускает
0.0.0.0 в production. Ansible после деплоя дёргает curl без credentials и фейлит билд при HTTP 200. Shodan-скан ASN раз в сутки ловит то, что пролетело мимо CI. Три автоматических слоя, каждый работает без участия человека.Без автоматизации всё держится на памяти и дисциплине конкретного инженера. А люди ошибаются. LimeLeads, Decathlon, Data & Leads - одна и та же ошибка, повторяемая годами с одними и теми же последствиями. Если интересно, как другие SOC-команды строят мониторинг экспозиции ES и NoSQL-баз - на codeby.net ведётся тематический разбор с конфигами детекции и свежими инцидентами.
AI-выжимка
по разделам
Тезисы статьи скоро
Статья читается полностью. Тезисы со ссылками на разделы появятся позже.
Содержание
Codeby Academy
Практика и мастерство
От основ до продвинутого — программы для практиков Codeby.
Перейти к курсу →
Продолжить чтение
Следующий разбор
Карта архитектуры, поверхности атаки и точек входа
Комментарии
0