Привет, Хабр!

Меня зовут Рустем Галиев, я Senior DevOps Engineer в IBM.

В последние годы контейнеризация стала неотъемлемой частью инфраструктуры для современных приложений. Технологии контейнеризации, такие как Docker и Kubernetes, предоставляют удобный способ упаковки, развёртывания и масштабирования приложений, а также обеспечивают лёгкость миграции и управление зависимостями. Но, как и любая другая технология, контейнеры имеют свои уязвимости. Ошибки в конфигурации, слабые политики безопасности и недостаточная изоляция контейнеров могут превратить их в привлекательные цели для злоумышленников.

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

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



Эксплуатация устаревших библиотек и эскалация привилегий

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


Проблема устаревших библиотек в контейнерах

Контейнеры, как правило, создаются на основе базовых образов, таких как Ubuntu, Debian, Alpine и т.д., которые содержат в себе определенный набор системных библиотек. Когда приложение собирается с использованием образа, библиотеки, которые были актуальны на момент создания контейнера, могут устареть и содержать уязвимости.

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


Как уязвимости в библиотеках могут быть использованы для атак

Когда контейнер содержит уязвимую версию какой-либо библиотеки, злоумышленник может попытаться использовать известную уязвимость для выполнения кода или повышения привилегий. Рассмотрим процесс на примере реальной уязвимости.

Пример: Уязвимость в библиотеке OpenSSL

Предположим, что контейнерное приложение использует библиотеку OpenSSL для шифрования и дешифрования данных, но в контейнере используется устаревшая версия этой библиотеки. OpenSSL подвергалась критическим уязвимостям, одна из которых — Heartbleed (CVE-2014-0160). Heartbleed позволяет злоумышленнику считывать содержимое памяти сервера, в том числе конфиденциальную информацию, такую как ключи шифрования и пароли.

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

— Получение доступов: Используя полученные данные, злоумышленник может получить доступ к сессионным токенам, паролям или ключам. С их помощью он может войти в систему под видом авторизованного пользователя.

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

В некоторых случаях злоумышленник может использовать уязвимости для выхода за пределы контейнера. Это возможно, если контейнер работает с повышенными привилегиями или если хост-система также уязвима. Примером может служить CVE-2019-5736 — уязвимость в Docker, которая позволяла злоумышленнику выйти из контейнера и получить доступ к файловой системе хоста.


Методы защиты контейнеров

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

— Сканирование уязвимостей — использование специализированных инструментов, таких как Trivy, Clair или Anchore, для анализа контейнерных образов на наличие уязвимостей в пакетах.

— Меньше привилегий для контейнеров — запускайте контейнеры с минимальными привилегиями (не от имени root). Это снизит последствия потенциальной атаки.

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

— Политики безопасности Kubernetes и Docker — настройка политик безопасности (PodSecurityPolicies в Kubernetes или seccomp в Docker) позволит ограничить возможности контейнеров и предотвратить их влияние на хост-систему.

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

Неправильная конфигурация контейнеров

Неправильная конфигурация контейнеров действительно может привести к так называемому контейнерному брейкауту (от англ. container breakout) — ситуации, когда злоумышленник выходит за пределы контейнера и получает доступ к хост-системе. Контейнерный брейкаут особенно опасен, если хост-система запускает контейнеры с повышенными привилегиями или не настроена должным образом для изоляции.

Как неправильная конфигурация может привести к брейкауту?

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

Запуск контейнеров с правами суперпользователя (root): Контейнеры, запущенные с правами root, имеют доступ к большему числу системных ресурсов хоста. Это делает возможной эксплуатацию уязвимостей для получения доступа к хосту. Например, если злоумышленник получает root-доступ в контейнере, он может потенциально использовать уязвимости в драйверах или ядре, чтобы выйти за пределы контейнера.

Привилегированные контейнеры: Контейнеры, запущенные с флагом --privileged, получают прямой доступ к ресурсам хост-системы, включая устройства, файлы и т.д. Этот режим практически снимает изоляцию контейнера, что делает его крайне уязвимым.

Монтирование сокета Docker: Если контейнеру предоставлен доступ к сокету Docker (например, /var/run/docker.sock), злоумышленник может использовать его для управления другими контейнерами и даже для запуска новых контейнеров на хосте. Сокет Docker предоставляет API для управления контейнерами, и, обладая доступом к нему, злоумышленник может выполнить команды на уровне хост-системы.

Монтирование файловой системы хоста: Разрешение контейнеру монтировать критические файлы и директории хоста, такие как /etc или /root, предоставляет злоумышленнику доступ к конфиденциальным данным и настройкам. Например, если контейнер может монтировать /proc или /sys, злоумышленник может получить доступ к информации о процессах хост-системы и даже к некоторым интерфейсам управления ядром.

Отсутствие ограничений на системные вызовы: Политики безопасности, такие как seccomp (Security Computing Mode), позволяют ограничить доступ контейнеров к системным вызовам ядра. Без seccomp и подобных политик злоумышленник может использовать уязвимые системные вызовы для выхода за пределы контейнера и доступа к хосту.

Примеры контейнерных брейкаутов

CVE-2019-5736: Уязвимость в runc

Эта уязвимость была обнаружена в контейнерном runtime-инструменте runc, который является базой для Docker и Kubernetes. Злоумышленник мог воспользоваться уязвимостью, чтобы подменить бинарный файл runc внутри контейнера и выполнить произвольный код на уровне хост-системы. Для эксплуатации этой уязвимости злоумышленнику нужно было иметь возможность запускать контейнеры или монтировать определенные директории.

Как это происходит: Злоумышленник изменяет бинарный файл runc, используемый контейнером. При следующем запуске контейнера система выполняет подмененный runc, что позволяет злоумышленнику выполнять команды от имени хост-системы.

Защита: Обновление до защищенной версии runc, запуск контейнеров с минимальными привилегиями и ограничение доступа к сокету Docker.

Монтирование Docker сокета

Контейнеры, которым предоставлен доступ к /var/run/docker.sock, могут выполнять команды Docker на хосте, что позволяет злоумышленнику запускать свои собственные контейнеры с привилегиями на хосте или управлять существующими контейнерами.

Как это происходит: Злоумышленник запускает команду docker внутри контейнера, подключенного к сокету Docker. Получив доступ, он может, например, запустить привилегированный контейнер, который получит полный доступ к файловой системе хоста.

Защита: Не предоставлять контейнерам доступ к Docker сокету, если это не абсолютно необходимо.

Рекомендации по безопасности для предотвращения брейкаута

— Запуск контейнеров с минимальными привилегиями: По возможности, избегайте запуска контейнеров с правами root. Используйте флаги --user или специальные политики безопасности для ограничения прав внутри контейнера.

— Ограничение прав доступа с помощью seccomp и AppArmor: Настройка профилей безопасности seccomp и AppArmor позволяет изолировать контейнеры от потенциально опасных системных вызовов.

— Использование сетевых пространств имен (Namespaces): Используйте различные пространства имен, такие как user namespace, которые создают дополнительный уровень изоляции, ограничивая видимость процессов и ресурсов на уровне хост-системы.

— Сканирование образов на наличие уязвимостей: Проводите регулярное сканирование образов с помощью инструментов, таких как Trivy и Clair, чтобы вовремя обнаружить уязвимые версии библиотек и зависимостей.

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

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


Стартовый курс для администраторов и инженеров, которые хотят освоить основы работы с k8s — «Kubernetes База»

Продвинутый курс для тех, кто уже работал с k8s и хочет повысить компетенции с точки зрения развертывания и сопровождения кластеров K8s — «Kubernetes Мега»

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


  1. amarkevich
    03.12.2024 00:03

    базой должно быть понимание того, что благодаря CRI в K8S Docker не является рантаймом по умолчанию, и большинство упомянутых уязвимостей не будет актуально при использовании другого рантайма