Предыстория с 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)
mpa4b
21.05.2019 17:50+2Одному мне кажется, что 'нет пароля root' и 'пароль пустой' — совершенно разные вещи? Можно взять и убрать хеш пароля из /etc/shadow и тогда уже никакой пароль руту не подойдёт. А можно задать пароль в виде пустой строки — и тогда пустая строка, очевидно, будет паролём.
shurup Автор
22.05.2019 09:51Фраза «пустой пароль» однажды использовалась в тексте и во избежание некорректного её прочтения исправил, спасибо.
Речь про строку в /etc/shadow определённого вида (root::…
), что указано в описании работы скрипта. Такая строка означает, что пользователя root пустят в систему без даже просьбы вводить какой-либо пароль. В Ubuntu, например, по умолчанию делаютroot:!:…
, что действительно означает уже совсем иное: никакой пароль не подойдёт (хэш не совпадёт).
zvulon
21.05.2019 20:31+1я не понял как ее можно использовать?
если есть доступ к хосту то и пароль не поможет — в любой образ зайти можно.
если нет то большинство и так запускают приложения из под рута в докере,
так что есть пароль нет пароля — все равно.
KirEv
21.05.2019 21:28+2с одной стороны не секюрно, с другой — как этим воспользоваться?
1. большинство контейнеров выполняются внутри от рута
2. если ssh-порт не прокинуть на ружу — извне не зайти
3. если есть доступ к пользователю имеющий право выполнять docker — он может что угодно делать с контейнером и без внутреннего рута (перезобрать образ, в конце концов, и чтото подменить внутри)
4. вопрос: зачем вообще образу рут с паролем?
PavelBelyaev
Как залезть в консоль контейнера, если там выключен shell вообще? Вот пример контейнер с движком Ghost. Или как получить доступ к файловой системе контейнера, чтобы там что-то подправить, только сборкой своего контейнера на основе другого?
pewpew
получаем id контейнера:
docker ps
заходим и делаем всё, что хочется:
docker exec -i -t 6ee6223a3ce3 bash
vp7
Но от этого не спасёт и наличие рутового пароля в контейнере.