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

Shellshock: аудит CGI на Apache после патча bash

После патча CVE-2014-6271 прошлись по всем хостам с mod_cgi. Нашли три CGI-скрипта с bash в shebang - два из них мёртвые. Описываем методику быстрого аудита.

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

Shellshock-эксплойты через CGI/Apache активно эксплуатируются в первые часы после публикации CVE-2014-6271

После экстренного патчинга bash мы не стали расходиться. Патч закрыл CVE-2014-6271, но вопрос «где у нас вообще крутится CGI с bash» оставался открытым. Ответ на него - это отдельная работа, и вот её мы и описываем.

Суть проблемы со стороны Apache: mod_cgi и mod_cgid при обработке запроса передают HTTP-заголовки в переменные окружения и запускают скрипт. Если скрипт вызывает bash - через shebang или явно, - уязвимый bash получает эти переменные и выполняет что угодно из заголовков. Пока bash не пропатчен, любой такой скрипт - открытая дверь.

После патча угроза снята, но список CGI-скриптов никуда не делся. Мы решили сделать полный аудит безопасности того, что вообще лежит под mod_cgi на клиентских серверах.

Шаг первый: найти серверы с активным mod_cgi

Первым делом собрали список хостов, где вообще включён Apache. Потом прошлись по каждому:

apache2ctl -M 2>/dev/null | grep -E 'cgi'
# или на CentOS/RHEL:
httpd -M 2>/dev/null | grep -E 'cgi'

Если в выводе есть cgi_module или cgid_module - сервер потенциально интересен. На нескольких хостах mod_cgi оказался включён по умолчанию ещё при установке Apache и никем не отключался - просто потому что «и так работает».

Шаг второй: найти CGI-скрипты

После того как определились с серверами, искали сами скрипты. Apache отдаёт CGI двумя способами: через ScriptAlias/ScriptAliasMatch или через Options +ExecCGI в конкретной директории. Смотрели в конфигах:

grep -rE 'ScriptAlias|ExecCGI' /etc/apache2/ 2>/dev/null
grep -rE 'ScriptAlias|ExecCGI' /etc/httpd/ 2>/dev/null

Потом шли в найденные директории и смотрели, что там живёт.

Шаг третий: проверить shebang

В каждом найденном скрипте смотрели первую строку:

find /var/www/cgi-bin/ -type f | xargs file | grep -i script
head -1 /var/www/cgi-bin/some-script.pl

Нас интересовало всё, где в shebang написано /bin/bash или /usr/bin/bash. Скрипты на /bin/sh или /usr/bin/perl - меньший приоритет, хотя тоже смотрели.

Что нашли

На трёх хостах обнаружилось суммарно три CGI-скрипта с bash в shebang. Одна находка - скрипт, который используется: небольшая внутренняя утилита, которую клиент написал несколько лет назад и периодически вызывает вручную. Его bash-зависимость была реальной: использовал массивы и подстановку переменных - синтаксис, который /bin/sh не поддерживает. Трогать не стали, но зафиксировали.

Два других скрипта - история классическая. Один оказался тестовым, написанным в 2009 году при первоначальной настройке сервера. Второй - деплойный хук от системы, которую клиент перестал использовать в 2011-м. Оба вызывались последний раз... не вызывались никогда в логах за доступный период. Просто лежали и ждали.

Удалили без переговоров - сначала уточнили у клиентов, получили подтверждение, что скрипты никому не нужны, и убрали. Заодно отключили mod_cgi на хосте, где никаких живых скриптов не осталось.

Пара наблюдений

Логи доступа - первый фильтр. Прежде чем тратить время на разбор скрипта, смотрели, когда он последний раз вызывался. Если в access.log нет обращений к этому пути за несколько месяцев - вопрос «нужен ли он вообще» задаётся сразу.

ScriptAlias без скриптов - не редкость. На одном сервере ScriptAlias /cgi-bin/ /var/www/cgi-bin/ был прописан в дефолтном конфиге Apache, сама директория существовала, но была пуста. mod_cgi включён, потенциально принимает запросы по этому пути - но скриптов нет. Формально не опасно, но зачем держать включённый модуль без цели - непонятно.

Bash через shebang vs. bash внутри скрипта. Мы смотрели на shebang, но есть ещё один вариант: скрипт на perl или python, который внутри вызывает system('/bin/bash ...') или открывает pipe в bash. Такие места тоже ловятся, но уже ручным просмотром кода, а не автоматически. В найденных скриптах такого не было, но иметь в виду стоит.

Состояние после аудита

Три проблемных скрипта - минус два (удалены), один остался под наблюдением. Один хост лишился mod_cgi полностью. На остальных хостах CGI-скриптов с bash не нашлось - либо CGI не используется вовсе, либо скрипты на perl.

Аудит занял несколько часов на несколько десятков серверов - не потому что сложно, а потому что нужно было ходить по конфигам руками и разбираться, что живое, а что артефакт. Автоматизировать можно, но написать скрипт для поиска быстрее, чем проверить находки.

Про дальнейшее hardening bash - отдельный пост, там есть что обсудить помимо обновления пакета.

Контакт

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

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