Из чрута — на поверхность: как, почему и что делать?

Основано на реальных событиях.

Представьте себе, что у вас есть крупный проект, для которого необходимо собирать софт. А ещё у вас есть желание замутить сборочную ферму, на которой ваши подчинённые будут собирать нужный софт. А ещё это всё происходит под Linux-ом, и каждому надо организовать «чистое» окружение с минимумом затрат. Как это сделать?

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

А через неделю после интеграции этого решения и после увольнения сотрудника «икс» вы просыпаетесь — а на сервере девственно чистый жёсткий диск. Злодей уничтожил труды разработчиков, работа встала.

Почему же он сумел удалить всё, если был в «защищённом» «запертом» чруте?


Вся суть — в том, что злодей мог ставить в чрут программы. Или же просто обладал в чруте правами root.

Начнём издалека. В Linux помимо реальных файловых систем существуют виртуальные. Одной из таких систем является /proc/ — файловая система информации ядра. Например, команда

$ zcat /proc/config.gz


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

mount -t proc proc /mnt/chrootme/proc/


и, что важно, она содержит информацию и о хостовой системе!

В /proc существуют папки вида /proc/$pid/cwd, в которых можно посмотреть содержимое папки, которая является текущей для данного процесса (а для текущего процесса существует также шорткат /proc/self/pid). Существуют такие папки для всех запущенных процессов, в том числе — для init.

А какая папка является текущей для init? Верно, /! А так как init у нас — хостовой, то задача «выбраться наверх» сводится к проделыванию

# chroot /proc/1/cwd/


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

Как же не попасть в такую ситуацию?



  • Никогда не давать chroot-окружения незнакомцам!
  • Использовать для построения сборочных ферм виртуализацию. Медленно, зато безопасно (а с технологиями svm/vtx — и не медленно).
  • Не давать root-а (или хотя бы малейшей возможности его получить) в chroot-е даже тем, кому доверяешь.
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 34

    +4
    Ну или linux-vserver и OpenVZ как замену chroot.
      +2
      уж лучше тогда linux containers (lxc), в убунте 12.04 очень приятно все реализовано.
        0
        А какие там новости в области LXC по сравнению с 11.10? Где почитать порекомендуете именно про это?
          +1
          Вы написали, что лучше, а почему не написали.
          Мы используем Proxmox для таких целей. Проблем почти нет )
            0
            Не я, а lolipop комментом выше :-)
              0
              Да, простите, не углядел с телефона ))
            0
            launchpad.net/ubuntu/+source/lxc/+changelog
            тут хорошо виден прогресс
            0
            С lxc не всё так гладко в плане безопасности. В зависимости от настроек, контейнер либо может перемонтировать родительскую fs в read-only, либо не может установить свой hostname, например. Т.к. это регулируется с помощью одного capability CAP_SYS_ADMIN. И я не удивлюсь, если и LXC подвержен такой атаке (правда, есть ещё CAP_SYS_CHROOT, который тоже можно отобрать).
              0
              А в lxc нет такой проблемы, то есть не общий /proc?
                0
                proc по-умолчанию точно не общий.
              0
              самое главное — chroot barrier.
              0
              М-м… Интересно, как обстоят дела с зонами Solaris и BSD Jail, просто ни когда с ними не работал и понятия не имею как они устроены.
                0
                Зоны в Солярке — полноценные виртуальные машины со своими дисками
                +2
                Я так думаю, что достаточно не давать рута в chroot-е. «Использовать для построения сборочных ферм виртуализацию» не обязательно в таком случае.
                  +1
                  Вообще говоря давно есть lxc.
                    0
                    А классика — cd / & mkdir /tmp & chroot /tmp & cd ../../../../../… & chroot. (или как-то так, точно уже не помню) не работает больше?
                      +1
                      Работает:
                      fd = open(".", O_RDONLY);
                      mkdir("./tmp", 0700);
                      chroot("./tmp");
                      fchdir(fd);
                      while (...) chdir("..");
                        0
                        А кто-нибудь может обьяснить смысл этого? Я не понимаю, каким образом происходит переход на host'вый / простым cd ../ в chroot'овом окружении.
                          +6
                          chroot делает dot-dot в новом корне эквивалентным просто dot, т.е. лишает возможности подняться из-под нового корня наверх. Если процесс каким-то образом получил текущую директорию, которая _не_ под новым корнем, то chroot не помешает подняться из этой директории до настоящего корня. Есть несколько способов получить такую текущую директорию. Один основан на том, что согласно POSIX, chroot не меняет текущую директорию, поэтому если мы из-под chroot сделаем еще один chroot на поддиректорию текущей, то наша текущая директория будеи выше корня и см. выше. Второй способ (приведенный мной) работает для тех старых UNIX-ов, где chroot «улучшили», чтобы он менял текующую директорию на новый корень. Идея остается той же: делаем новый chroot и возвращаемся наверх при помощи fchdir. Как сказал по этому поводу Алан Кокс «If you have the ability to use chroot() you are root. If you are root you can walk happily out of any chroot by a thousand other means».
                            0
                            Спасибо, весьма познавательно.
                            +1 к карме. ;)
                      +3
                      может и не злодей вовсе, rm -fr /, кто-же знал о /proc/1/cwd :)
                        +2
                        Интересно… что такое chroot они знают, а что такое бекапы, version control и прочие фишки для хранения кода для разработчиков они не в курсе?
                          +1
                          Всё это на отдельных серверах.
                          +21
                          Если бы герой вашей статьи, вместо бредовых рассуждений на 3 страницы, набрал в консоли man chroot и узрел строки:

                          > This call does not change the current working directory, so that after the call '.' can be outside the tree rooted at '/'. In particular, the superuser can escape from a «chroot jail» by doing:
                          > mkdir foo; chroot foo; cd…

                          он бы сэкономил немало времени и себе, и читателям.
                            +1
                            Во FreeBSD этого предупреждения нет — это значит, что ман неполон или что FreeBSD к этому устойчива?
                              0
                              Там просто менее разжёвано.
                            +1
                            Почему бы не использовать vagrantup.com/?
                              +6
                              >… и после увольнения сотрудника «икс» вы просыпаетесь — а на сервере девственно >чистый жёсткий диск. Злодей уничтожил труды разработчиков, работа встала.
                              Я одного не понял. Его что, после увольнения от ресурсов не отключили???
                                0
                                Про это часто забывают :) Помню, когда я увольнялся с одной компании, три месяца (!) никто даже не дернулся поменять пароль рута на всех машинах, подконтрольных мне… Поменяли только после того, когда я зашел на консоль со своей домашней машины, соответственно, светанув IP — и не придумав ничего умнее, удалил last access IP :)) я это к тому, что человеческий фактор и беспечность, к сожалению, никуда не деваются. Просто взяли и забыли его отключить :)
                                +3
                                Если не секрет, что подвигло уволенного работника на такие действия?
                                  –2
                                  А SELinux? Он как?
                                    0
                                    А если uid в chroot будет такой же как uid вне chroot, то выйдя так из chroot он сможет править чужие папки?
                                      0
                                      чтобы вылезти из chroot методом, описанным в посте, нужен root, у которого uid=1 на любой системе. При вылезании же вылезаешь как root с тем же uid=1, соответственно, можешь делать всё, что в голову взбредёт.

                                      Метод вылезания через cd ../../../../ не пробовал, так что насчёт этого метода не в курсе: думаю, при совпадении uid можно будет редактировать файлы данного uid.
                                        +2
                                        uid=0

                                    Only users with full accounts can post comments. Log in, please.