В минувшую субботу, 18 мая, Jerry Gamblin из Kenna Security проверил 1000 самых популярных образов с Docker Hub на используемый в них пароль для пользователя root. В 19% случаев он отсутствовал.



Предыстория с Alpine


Поводом для проведённого мини-исследования стал появившийся ранее в этом месяце Talos Vulnerability Report (TALOS-2019-0782), авторы которого — благодаря находке Peter Adkins из Cisco Umbrella — сообщили, что Docker-образы с популярным дистрибутивом для контейнеров Alpine не имеют пароля для root:

«Официальные версии Docker-образов Alpine Linux (начиная с v3.3) содержат NULL-пароль для пользователя root. Эта уязвимость появилась в результате регрессии, представленной в декабре 2015 года. Её суть сводится к тому, что системы, развёрнутые с проблемными версиями Alpine Linux в контейнере и использующие Linux PAM или другой механизм, задействующий системный файл shadow в качестве базы данных для аутентификации, могут принимать нулевой (NULL) пароль для пользователя root».

Проверенными на проблему версиями Docker-образов с Alpine назывались 3.3—3.9 включительно, а также последний релиз edge.

Авторы давали следующую рекомендацию пользователям, подверженным проблеме:

«Учётная запись root должна быть явно отключена в Docker-образах, собранных на базе проблемных версий Alpine. Вероятная эксплуатация уязвимости зависит от окружения, поскольку её успех требует проброшенного вовне сервиса или приложения, использующего Linux PAM или другого подобного механизма».

Проблема была устранена в Alpine версий 3.6.5, 3.7.3, 3.8.4, 3.9.2 и edge (20190228 snapshot), а обладателям подверженным ей образов предложили закомментировать строку с root в /etc/shadow или убедиться в отсутствии пакета linux-pam.

Продолжение с Docker Hub


Jerry Gamblin решил полюбопытствовать, «насколько распространённой может оказаться практика использования null-паролей в контейнерах». Для этого он написал небольшой Bash-скрипт, суть которого весьма проста:

  • через curl-запрос к API в Docker Hub запрашивается список размещённых там Docker-образов;
  • через jq он сортируется по полю popularity, а из полученных результатов остаётся первая тысяча;
  • для каждого из них выполняется docker pull;
  • для каждого полученного с Docker Hub образа выполняется docker run с чтением первой строки из файла /etc/shadow;
  • если значение строки оказалось равным root:::0:::::, название образа сохраняется в отдельный файл.

Что же получилось? В этом файле оказалось 194 строки с названиями популярных Docker-образов с Linux-системами, root-пользователь в которых не имеет установленного пароля:

«Среди наиболее известных имён в этом списке оказались govuk/governmentpaas, hashicorp, microsoft, monsanto и mesosphere. А kylemanna/openvpn — самый популярный контейнер из списка, его статистика насчитывает более 10 миллионов pull'ов».

Стоит, впрочем, напомнить, что само по себе это явление не означает прямой уязвимости в безопасности систем, которые их используют: всё зависит и от того, как именно они применяются (см. комментарий из случая с Alpine выше). Однако «мораль сей басни» мы видели уже много раз: видимая простота зачастую имеет и обратную сторону, о которой всегда необходимо помнить и последствия которой учитывать в своих сценариях применения технологии.

P.S.


Читайте также в нашем блоге:

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


  1. PavelBelyaev
    21.05.2019 13:05
    +1

    Как залезть в консоль контейнера, если там выключен shell вообще? Вот пример контейнер с движком Ghost. Или как получить доступ к файловой системе контейнера, чтобы там что-то подправить, только сборкой своего контейнера на основе другого?


    1. pewpew
      21.05.2019 13:52

      получаем id контейнера:
      docker ps

      заходим и делаем всё, что хочется:
      docker exec -i -t 6ee6223a3ce3 bash


      1. vp7
        21.05.2019 13:58

        Но от этого не спасёт и наличие рутового пароля в контейнере.


  1. mpa4b
    21.05.2019 17:50
    +2

    Одному мне кажется, что 'нет пароля root' и 'пароль пустой' — совершенно разные вещи? Можно взять и убрать хеш пароля из /etc/shadow и тогда уже никакой пароль руту не подойдёт. А можно задать пароль в виде пустой строки — и тогда пустая строка, очевидно, будет паролём.


    1. shurup Автор
      22.05.2019 09:51

      Фраза «пустой пароль» однажды использовалась в тексте и во избежание некорректного её прочтения исправил, спасибо.

      Речь про строку в /etc/shadow определённого вида (root::…), что указано в описании работы скрипта. Такая строка означает, что пользователя root пустят в систему без даже просьбы вводить какой-либо пароль. В Ubuntu, например, по умолчанию делают root:!:…, что действительно означает уже совсем иное: никакой пароль не подойдёт (хэш не совпадёт).


  1. zvulon
    21.05.2019 20:31
    +1

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


  1. KirEv
    21.05.2019 21:28
    +2

    с одной стороны не секюрно, с другой — как этим воспользоваться?
    1. большинство контейнеров выполняются внутри от рута
    2. если ssh-порт не прокинуть на ружу — извне не зайти
    3. если есть доступ к пользователю имеющий право выполнять docker — он может что угодно делать с контейнером и без внутреннего рута (перезобрать образ, в конце концов, и чтото подменить внутри)
    4. вопрос: зачем вообще образу рут с паролем?


  1. site6893
    22.05.2019 00:55

    а зачем он там в нужен в докер образах?