ADG Оставить заявку
Блог Информационная безопасность 5 мин чтения

DROWN и SSLv2: инвентаризируем серверы и отключаем протокол до публичного раскрытия CVE

Получили оповещение о DROWN (CVE-2016-0800): SSLv2 позволяет расшифровать TLS-сессии. Проводим инвентаризацию всех серверов и публикуем скрипт проверки через openssl и nmap NSE.

Контекст момента

Публикация DROWN-атаки (CVE-2016-0800) показала, что SSLv2 на любом сервере с общим ключом позволяет расшифровать TLS-сессии

В начале третьей недели февраля нам пришло оповещение через один из закрытых каналов по уязвимостям - что-то серьёзное готовится к публичному раскрытию, связано с SSL, и до официального анонса есть несколько дней. Детали пока под NDA исследователей, но рекомендация однозначная: проверьте, у вас где-нибудь работает SSLv2? Если да - отключите немедленно, не ждите подробностей.

Это называется coordinated disclosure, и работает именно так: крупные вендоры и часть сервисных компаний получают предупреждение раньше публики, чтобы успеть закрыть окно до того, как детали атаки станут общедоступны.

SSLv2 в 2016 году - это вообще реально?

Первая реакция - «ну кто у нас вообще держит SSLv2, мы его отключали ещё сто лет назад». Вторая реакция - проверить. И вот тут начинается интересное, потому что проверка показала, что «отключали» и «отключено» - не одно и то же.

SSLv2 в современных конфигурациях выглядит примерно так: nginx собранный из пакета несколько лет назад с дефолтным ssl_protocols, старый Apache с httpd.conf времён «когда-то ставил и не трогал», почтовый Postfix с Dovecot где starttls настроен минималистично, и - отдельный привет - железные балансировщики и VPN-концентраторы, которые живут своей жизнью и у которых web-интерфейс показывает «всё хорошо». Плюс несколько Windows Server с IIS, которые до 2008 R2 включают SSLv2 из коробки и требуют отдельного registry-патча.

Как проверяли

Инвентаризацию делали в два прохода. Первый - по собственным и клиентским серверам, где у нас есть ssh-доступ. Второй - снаружи, через nmap и openssl, как это сделает сканнер атакующего.

Проверка через openssl. Самый прямой способ - попытаться установить соединение по SSLv2:

openssl s_client -ssl2 -connect TARGET:443

Если рукопожатие прошло - SSLv2 включён. Если ошибка вида no protocols available или ssl handshake failure - отключён или не поддерживается клиентом. Проблема в том, что современные сборки OpenSSL (1.0.2+) уже скомпилированы без поддержки SSLv2 - openssl s_client -ssl2 просто не сработает на машине с актуальной версией. Приходится либо держать старую версию под рукой, либо использовать другие инструменты.

Проверка через nmap NSE. Надёжнее и не требует старого OpenSSL:

nmap --script ssl-enum-ciphers -p 443 TARGET

Вывод покажет все поддерживаемые протоколы и шифры с оценкой A/B/C/F. SSLv2 будет явно виден в списке если включён. Для массового сканирования можно передать список хостов через -iL:

nmap --script ssl-enum-ciphers -p 443,8443,465,993,995 -iL hosts.txt -oN ssl-audit.txt

Порты выбраны не случайно: HTTPS, альтернативный HTTPS, SMTPS, IMAPS, POP3S. Почтовые порты особенно важны - там SSLv2 живёт тихо и незаметно чаще, чем на веб.

Проверка конфигурации изнутри. Параллельно с внешним сканом - быстрый скрипт по серверам через Ansible:

ansible all -m shell -a "openssl version; nginx -T 2>/dev/null | grep ssl_protocols; \
  apache2ctl -t -D DUMP_RUN_CFG 2>/dev/null | head -20"

Не универсально, но быстро даёт общую картину по серверам под управлением.

Что нашли

Результаты оказались предсказуемо неприятными для нескольких позиций:

  • Два почтовых сервера Postfix+Dovecot - SSLv2 включён, конфигурация не менялась с момента установки несколько лет назад.
  • Один старый Apache на клиентском сервере - SSLv2 и SSLv3 оба живы, плюс RC4-шифры в наборе.
  • Два железных устройства - VPN-концентратор и балансировщик старой модели. Тут хуже всего: web-интерфейс настройки SSL либо не показывает SSLv2 как отдельный пункт, либо показывает «выключено», но реально протокол отвечает. Пришлось проверять снаружи и лезть в поддержку вендора.
  • Nginx и Apache на основных веб-серверах - в порядке, SSLv2 отключён, ssl_protocols явно задан.

Что отключали и как

Для Linux-серверов это в основном правка конфигурации и рестарт службы - дело минут. Для nginx: ssl_protocols TLSv1 TLSv1.1 TLSv1.2; без SSLv2 и SSLv3. Для Dovecot: ssl_protocols = !SSLv2 !SSLv3 в 10-ssl.conf. Для Postfix: smtpd_tls_protocols = !SSLv2,!SSLv3 в main.cf.

Железо - отдельная история. По одному устройству обновление прошивки закрыло вопрос. По второму - прошивка с исправлением ещё не вышла на момент написания, временное решение - ограничить доступ к этому устройству на уровне firewall до выхода патча.

О чём на самом деле говорит эта история

DROWN (подробности появятся в начале марта) - не уязвимость в конкретном продукте, а атака на протокол. Смысл в том, что SSLv2 не нужно быть включённым на том же сервере, что обслуживает TLS-соединения. Достаточно, чтобы где-то использовался тот же приватный ключ - например, на почтовом сервере, о котором все забыли. Атакующий может провести атаку через старый протокол и расшифровать трафик нового.

Это делает задачу инвентаризации шире обычного: нужно смотреть не только на конкретный веб-сервер, но на все сервисы, где используется тот же сертификат или тот же приватный ключ. А это уже требует аккуратного учёта того, где и какие ключи применяются - чего у большинства нет в явном виде.

Мы проводим подобные проверки как часть технического аудита ИБ. Если после публичного раскрытия DROWN нужна быстрая проверка - знаете где нас найти.

Официальный анонс ожидается через несколько дней. Подробности по механике атаки будут в отдельном посте.

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.