РАЗБОР Статья

Утечка данных Elasticsearch: разбор LimeLeads

Сергей Попов
Сергей Попов Red Team · 6,7 тыс. сообщений
Подписаться
1,2 тыс.
[ обложка статьи ]
Режим чтения
Светлый рабочий стол с планшетом, на экране которого видна таблица сканирования Shodan с результатом «PORT 9200 · LIMELEADS · 17.8M EXPOSED». Рядом фарфоровая чашка кофе, перьевая ручка и лист с че...


Понедельник, 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: от сканирования открытых портов до продажи данных​

1793507612195.webp

Бизнес-логика атаки: зачем атакующему открытый 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: проверка экспозиции базы данных​

1793507755647.webp

Аудит экспозиции сводится к трём вопросам: слушает ли 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​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

После применения - 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​

1793507830443.webp

Без 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
Правило 2: массовая выгрузка данных. Более 50 запросов _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
По NIST CSF v2.0 это покрывает DE.AE-01 (baseline сетевого трафика и ожидаемых потоков данных), PR.AA-01 (управление аутентификацией) и ID.AM-01 (инвентаризация активов, включая ES-инстансы).

Правовой контекст: оборотные штрафы за экспозицию базы данных в интернет​

Для российских компаний экспозиция 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 ведётся тематический разбор с конфигами детекции и свежими инцидентами.
Полезно

Комментарии

0