Ответ 1
Ошибка
CVE-2014-7169 - ошибка в парсе bash. bash анализатор использует переменную eol_ungetc_lookahead
для вывода символов через строки. Эта переменная не была должным образом reset из функции reset_parser
, которая называется, например. на некоторые синтаксические ошибки. Используя эту ошибку, можно ввести символ в начало следующей строки ввода bash.
Таким образом, тестовый код заставляет синтаксическую ошибку, используя либо (a)=
, либо function a a
, добавляет символ перенаправления для добавления к следующей строке >
и добавляет продолжение строки \
, что приводит к любой версии тестового кода:
() { (a)=>\
() { function a a>\
Когда выполняется bash, он обрабатывает переменные из среды, обнаруживает, что переменная X
является экспортируемой функцией и оценивает ее для импорта функции. Но оценка не выполняется с ошибкой синтаксического анализа, оставляя символ >
в переменной eol_ungetc_lookahead
. Затем при анализе аргумента команды echo date
он добавляет символ >
, приводящий к >echo date
, который запускает date
, перенаправленный в файл с именем echo
.
Его отношение к предыдущей ошибке
Вышеупомянутая ошибка, очевидно, очень отличается от исходной ошибки shellshock. На самом деле существует несколько проблем:
- Bash полностью оценивает переменную, которая выглядит как экспортированная функция (начинается с четырех символов
() {
). CVE-2014-6271. - При некоторых условиях можно ввести символ в переменную ungetc, которая будет добавлена к следующей строке ввода. CVE-2014-7169.
- Bash позволяет обрабатывать каждую переменную среды как экспортированную функцию, если она начинается с четырех символов
() {
. CVE-2014-6271, CVE-2014-7169, все другие CVE, где ошибка запускается в парсере bash. - Существует ограниченный стек для перенаправления здесь-doc, и нет проверки на переполнение. CVE-2014-7186, что приводит к повреждению памяти и, вероятно, может быть использовано для произвольного выполнения кода.
- Существует ограниченный стек для вложенных структур управления (
select
/for
/while
) с проверками на переполнение. Этот стек все еще поврежден. CVE-2014-7187.
Исправления
- первый патч ограничивает bash оценкой определения одной функции в каждой переменной, которая выглядит как экспортированная функция.
- второй патч корректно сбрасывает
eol_ungetc_lookahead
наreset_parser
. - Третий патч изменяет способ экспорта функций: теперь они экспортируются в переменные с именем
BASH_FUNC_functionname%%
.
Поверхность атаки
Большая проблема здесь заключалась в том, что каждая переменная среды может использоваться как вектор для атаки. Как правило, злоумышленники не могут контролировать произвольные переменные среды, иначе уже есть другие известные атаки (подумайте о LD_PRELOAD
, PATH
, IFS
,...).
sudo
не влияет на то, что он отключает экспортированные функции bash из среды, как указано Gilles на security.SE.
ssh
. Типичные установки sshd позволяют экспортировать только ограниченный набор переменных среды, как указано в AcceptEnv в sshd_config
, например: LANG
и LC_*
. Даже при этом агрессивном подходе к whitelisting, в shellshock любая переменная может быть вектором атаки.
Мало того, что каждая переменная окружения была потенциальным вектором атаки, они выставляли парсеp → 6000 строк.
Занятые уроки
system
, popen
, а другие потенциально опасны. Вы должны не только заботиться о своих аргументах: даже когда аргументы фиксируются во время компиляции, среда является потенциальным вектором атаки. Используйте fork()/execve()
, предпочтительно с чистой средой (но, по крайней мере, ограничивайте среду переменными, перечисленными в белом списке, предпочтительно с их проверенными значениями). Помните, что система хорошего качества делает то, что она должна делать, в то время как защищенная система делает то, что она должна делать и не более. Вызов полномасштабной оболочки делает ничего более сложным.
Сложность - это враг безопасности. В эти дни вы можете легко найти людей, рекомендующих более простые оболочки. Большинство оболочек свободны от shellshock, не поддерживая экспортированные функции вообще. И наоборот, bash на протяжении многих лет получал множество функций безопасности (вам нужно вызывать его с помощью -p
, чтобы избежать сброса привилегий при запуске, он санирует IFS,...), поэтому не предполагайте, что я сторонник переключение оболочек, это более общий совет.
Некоторые отрывки из древней книги Дэвида Уилера "Безопасное программирование для Linux и UNIX HOWTO" глава по переменным окружения по-прежнему заслуживают пересмотра.
§5.2.3 ¶1:
Для защищенных программ setuid/setgid короткий список окружения переменные, необходимые для ввода (если они есть), должны быть тщательно извлечены. затем следует удалить всю среду, а затем сбросить набор необходимых переменных среды для безопасных значений. Там действительно не лучший способ, если вы делаете какие-либо вызовы для подчиненных программ; нет практического метода перечисления "всех опасных значений".
§5.2.3 ¶6:
Если вам действительно нужны пользовательские значения, сначала проверьте значения (на убедитесь, что значения соответствуют шаблону для юридических значений и что они находятся в пределах некоторой разумной максимальной длины).