TL; DR
Уязвимость в снаряде полностью исправлена в
- На ветке bash-2.05b: 2.05b.10 и выше (исправление 10 включено)
- На ветке bash-3.0: 3.0.19 и выше (включая патч 19)
- На ветке bash-3.1: 3.1.20 и выше (исправление 20 включено)
- На ветке bash-3.2: 3.2.54 и выше (исправление 54 включено)
- На ветке bash-4.0: 4.0.41 и выше (включая патч 41)
- На ветке bash-4.1: 4.1.14 и выше (включая патч 14)
- На ветке bash-4.2: 4.2.50 и выше (исправление 50 включено)
- На ветке bash-4.3: 4.3.27 и выше (исправление 27 включено)
Если ваш bash показывает более старую версию, ваш поставщик ОС, возможно, все же исправил ее самостоятельно, поэтому лучше проверить.
Если:
env xx='() { echo vulnerable; }' bash -c xx
показывает "уязвимы", вы все еще уязвимы. Это единственный релевантный тест (все еще подвергается ли bash-анализатор коду в любой переменной среды).
Подробности.
Ошибка была в начальной реализации функции экспорта / импорта введен 5 - го августа 1989 года Брайан Фокс и первый выпущенный в Баш-1.03 около месяца спустя , в то время , когда баш не был в таком широко используется, прежде, чем безопасность была такая большая проблема, и HTTP и Интернет или Linux даже существовали.
Из ChangeLog в 1.05 :
Fri Sep 1 18:52:08 1989 Brian Fox (bfox at aurel)
* readline.c: rl_insert (). Optimized for large amounts
of typeahead. Insert all insertable characters at once.
* I update this too irregularly.
Released 1.03.
[...]
Sat Aug 5 08:32:05 1989 Brian Fox (bfox at aurel)
* variables.c: make_var_array (), initialize_shell_variables ()
Added exporting of functions.
Некоторые дискуссии в gnu.bash.bug и comp.unix.questions вокруг этого времени также упомянуть функцию.
Легко понять, как оно туда попало.
Bash экспортирует функции в ENV VARS, как
foo=() {
code
}
А при импорте все, что нужно сделать, это интерпретировать это с =
заменой пробела ... за исключением того, что он не должен интерпретировать это вслепую.
Это также нарушается тем, что bash
(в отличие от оболочки Борна) скалярные переменные и функции имеют другое пространство имен. На самом деле, если у вас есть
foo() { echo bar; }; export -f foo
export foo=bar
bash
удачно поместит оба в среду (да, записи с одинаковыми именами переменных), но многие инструменты (включая много оболочек) не будут их распространять.
Можно также утверждать, что bash должен использовать BASH_
префикс пространства имен для этого, поскольку это env vars имеет значение только от bash до bash. rc
использует fn_
префикс для аналогичной функции.
Лучший способ реализовать это - поместить определение всех экспортируемых переменных в переменную, такую как:
BASH_FUNCDEFS='f1() { echo foo;}
f2() { echo bar;}...'
Это все еще необходимо очистить, но по крайней мере это не может быть более пригодным для использования, чем $BASH_ENV
или $SHELLOPTS
...
Там есть патч, который запрещает bash
интерпретировать что-либо еще, кроме определения функции ( https://lists.gnu.org/archive/html/bug-bash/2014-09/msg00081.html ), и это тот, который имеет применялся во всех обновлениях безопасности из различных дистрибутивов Linux.
Тем не менее, bash все еще интерпретирует код, и любая ошибка в интерпретаторе может быть использована. Одна такая ошибка уже найдена (CVE-2014-7169), хотя ее влияние намного меньше. Так что скоро будет еще один патч.
До исправления, которое не позволяет bash интерпретировать код в любой переменной (как, например, с использованием BASH_FUNCDEFS
подхода, описанного выше), мы не будем знать наверняка, не уязвимы ли мы от ошибки в парсере bash. И я верю, что рано или поздно выйдет такое исправление.
Редактировать 2014-09-28
Обнаружены две дополнительные ошибки в синтаксическом анализаторе (CVE-2014-718 {6,7}) (обратите внимание, что большинство оболочек обязательно имеют ошибки в своем синтаксическом анализаторе для угловых случаев, что не было бы проблемой, если бы этот анализатор не имел не подвергались ненадежным данным).
В то время как все 3 ошибки 7169, 7186 и 7187 были исправлены в следующих исправлениях, Red Hat настаивала на исправлении проблемы с защитой. В своем патче они изменили поведение так, чтобы функции экспортировались в переменные, называемые BASH_FUNC_myfunc()
более или менее предвосхищающими решениями Чета.
Позднее Чет опубликовал это исправление в качестве официального патча bash для апстрима .
Это усиленное исправление или его варианты теперь доступны для большинства основных дистрибутивов Linux и в конечном итоге сделали его для Apple OS / X.
Теперь это вызывает обеспокоенность в связи с тем, что любой произвольный env var использует парсер через этот вектор, включая две другие уязвимости в парсере (CVE-2014-627 {7,8}), которые позже были раскрыты Михаилом Залевским (CVE-2014-6278 почти так же плохо, как CVE-2014-6271) к счастью, после того, как большинство людей успели установить исправление
Ошибки в синтаксическом анализаторе также будут исправлены, но теперь они больше не являются проблемой, так как синтаксический анализатор теперь не так легко подвергается ненадежному вводу.
Обратите внимание, что, хотя уязвимость безопасности была исправлена, вероятно, мы увидим некоторые изменения в этой области. В первоначальном исправлении для CVE-2014-6271 была нарушена обратная совместимость, поскольку он прекращает импорт функций с .
или :
или /
с их именем. Тем не менее, они могут быть объявлены bash, что приводит к противоречивому поведению. Поскольку обычно используются функции с их именами .
и :
их именами, вполне вероятно, что патч восстановит их, по крайней мере, из среды.
Почему его не нашли раньше?
Это также то, о чем я задумался. Я могу предложить несколько объяснений.
Во-первых, я думаю, что если бы исследователь безопасности (а я не профессиональный исследователь безопасности) специально искал уязвимости в bash, они, вероятно, нашли бы его.
Например, если бы я был исследователем безопасности, мои подходы могли бы быть следующими:
- Посмотрите, откуда
bash
берется информация и что она с ней делает. И окружающая среда очевидна.
- Посмотрите, в каких местах
bash
вызывается интерпретатор и на каких данных. Опять же, это будет выделяться.
- Импорт экспортируемых функций - это одна из функций, которая отключается, когда
bash
используется setuid / setgid, что делает его еще более очевидным местом для поиска.
Теперь я подозреваю, что никто не считал bash
(переводчика) угрозой или тем, что угроза могла возникнуть именно таким образом.
bash
Интерпретатор не предназначен для обработки ненадежного ввода.
Сценарии оболочки (не интерпретатор) часто рассматриваются с точки зрения безопасности. Синтаксис оболочки настолько неуклюж, и есть так много предостережений с написанием надежных сценариев (когда-либо видел, как я или другие упоминали оператор split + glob или почему вы должны указывать переменные, например?), Что довольно часто можно найти уязвимости безопасности в сценариях, которые обрабатывают ненадежные данные.
Вот почему вы часто слышите, что вам не следует писать сценарии оболочки CGI, или сценарии setuid отключены в большинстве Unices. Или, что вы должны быть особенно осторожны при обработке файлов в каталогах, доступных для записи во всем мире (см., Например, CVE-2011-0441 ).
Основное внимание уделяется сценариям оболочки, а не интерпретатору.
Вы можете открыть интерпретатор оболочки для ненадежных данных (передавая чужие данные в виде интерпретируемого кода оболочки) через eval
или .
или вызывая его для пользовательских файлов, но тогда вам не понадобится уязвимость bash
для их использования. Совершенно очевидно, что если вы передаете неанализованные данные для интерпретации оболочкой, она будет интерпретировать ее.
Таким образом, оболочка вызывается в доверенных контекстах. Ему даны фиксированные сценарии для интерпретации и чаще всего (потому что так сложно написать надежные сценарии) фиксированные данные для обработки.
Например, в веб-контексте оболочка может быть вызвана примерно так:
popen("sendmail -oi -t", "w");
Что может пойти не так с этим? Если что-то не так, то речь идет о данных, передаваемых в этот sendmail, а не о том, как анализируется сама командная строка оболочки или какие дополнительные данные передаются в эту оболочку. Нет причин, по которым вы хотели бы рассмотреть переменные среды, передаваемые в эту оболочку. И если вы это сделаете, вы поймете, что это все env-переменные, чьи имена начинаются с «HTTP_», или хорошо известные CGI-env-переменные, подобные SERVER_PROTOCOL
или QUERYSTRING
не имеющие отношения к оболочке или sendmail.
В контексте повышения привилегий, например при запуске setuid / setgid или через sudo, среда обычно рассматривается, и в прошлом было множество уязвимостей, опять же не против самой оболочки, а против вещей, которые повышают привилегии sudo
(см., Например, CVE -2011-3628 ).
Например, bash
не доверяет среде, когда setuid или mount
вызывается командой setuid ( например, вызывает помощников). В частности, он игнорирует экспортируемые функции.
sudo
делает очистку окружающей среды: все по умолчанию для белого списка , за исключением, и если не настроен на, по крайней мере черных списков несколько , которые , как известно, влияют на оболочку или другой (как PS4
, BASH_ENV
, SHELLOPTS
...). Он также помещает в черный список переменные среды, содержимое которых начинается с ()
(поэтому CVE-2014-6271 не позволяет повышение привилегий через sudo
).
Но опять же, это для контекстов, где среда не может быть доверенной: любая переменная с любым именем и значением может быть установлена злоумышленником в этом контексте. Это не относится к веб-серверам / ssh или ко всем векторам, использующим CVE-2014-6271, где контролируется среда (по крайней мере, имя переменных среды контролируется ...)
Важно блокировать переменную как echo="() { evil; }"
, но не так HTTP_FOO="() { evil; }"
, потому что HTTP_FOO
она не будет вызываться как команда каким-либо сценарием оболочки или командной строкой. И apache2 никогда не собирается устанавливать переменную echo
или BASH_ENV
.
Совершенно очевидно, что некоторые переменные окружения должны быть занесены в черный список в некоторых контекстах на основе их имени , но никто не думал, что они должны быть занесены в черный список на основе их содержимого (кроме sudo
). Иными словами, никто не думал, что произвольные переменные env могут быть вектором для внедрения кода.
Что касается того, могло ли расширенное тестирование при добавлении этой функции поймать ее, я бы сказал, что это маловероятно.
Когда вы проверяете функцию , вы проверяете ее функциональность. Функциональность работает отлично. Если вы экспортируете функцию в одном bash
вызове, она импортируется в другом. Очень тщательное тестирование могло бы выявить проблемы, когда и переменная, и функция с одинаковым именем экспортируются или когда функция импортируется в локаль, отличную от той, в которую она была экспортирована.
Но чтобы определить уязвимость, это не тест на функциональность, который вам пришлось бы делать. Аспект безопасности должен был быть в центре внимания, и вы бы не проверяли функциональность, но механизм и способы его использования.
Это не то, что разработчики (особенно в 1989 году) часто забывают, и разработчик оболочки может быть оправдан, полагая, что его программное обеспечение вряд ли пригодно для использования в сети.