По умолчанию кластер Kubernetes позволяет любому поду обращаться к любому другому поду. Объекты NetworkPolicy могут ограничить этот трафик, но только если они определены и принудительно применяются сетевым уровнем кластера. Без этих политик рабочая нагрузка веб-сервера может подключиться к базе данных, даже если у нее нет причин для доступа к ней.
Предыдущие публикации в этой серии были посвящены ошибкам конфигурации на уровне контейнеров. Часть 2 охватывала привилегированные контейнеры и опасные возможности, а Часть 3 — совместное использование пространств имен хоста и отсутствие лимитов ресурсов. Но усиление защиты контейнера не меняет того, к чему он может получить доступ: под, лишенный всех привилегий, все равно может направлять трафик к любой базе данных в кластере.
Эта публикация переходит от защиты контейнеров к сетевой доступности. Мы используем Kimera, набор инструментов для тестирования безопасности Kubernetes с открытым исходным кодом, поддерживаемый Dynatrace, для оценки, эксплуатации, устранения уязвимостей и обеспечения соблюдения элементов управления безопасностью Kubernetes в авторизованных демонстрационных средах. Начиная с одной скомпрометированной рабочей нагрузки, мы показываем, как злоумышленник может получить действительный сеанс пользователя. В процессе Dynatrace Kubernetes Security Posture Management (KSPM) выявляет отсутствующие сетевые политики, а Smartscape показывает вызовы служб, задействованные в пути атаки через приложение. Затем мы используем Kimera для применения элементов управления NetworkPolicy и проверяем, блокируют ли они этот путь.
Сетевая модель Kubernetes
Сетевая модель Kubernetes построена на трех требованиях:
- Каждый под получает свой собственный IP-адрес без трансляции сетевых адресов (NAT) внутри кластера.
- Все поды могут обмениваться данными со всеми другими подами.
- Агенты узлов могут обращаться ко всем подам на своем узле.
Плагины Container Network Interface (CNI) реализуют эти требования, определяя, как настраивается сеть подов и, что критически важно, применяются ли сетевые политики вообще.
CNI дает каждому узлу часть диапазона адресов всего кластера и инкапсулирует трафик между узлами. Это приводит к созданию плоской оверлейной сети, в которой каждый под напрямую доступен из любого другого пода.
Злоумышленник, понимающий топологию сети, может использовать плоскую сеть для доступа к другим рабочим нагрузкам. Kubernetes может упростить обнаружение этой топологии: CoreDNS регистрирует службы под предсказуемыми именами, поэтому под, знающий соглашение об именовании, может разрешать другие службы. В зависимости от конфигурации кластера, эти запросы также могут достигать соседних пространств имен. CoreDNS разрешает имена; сетевые и платформенные элементы управления определяют, кому разрешено подключаться.
Демонстрационная среда
В нашей демонстрации используется приложение Unguard от Dynatrace — намеренно уязвимое приложение на основе микросервисов. Unguard предоставляет службы и уязвимости на уровне приложений; Kimera выполняет проверки, методы атаки и шаги по устранению уязвимостей в кластере Kubernetes. Unguard запускает 16 служб в одном пространстве имен (см. Рисунок 1), включая:
- Экземпляр MariaDB
- Экземпляр Redis
- Службы, которые аутентифицируют пользователей и принимают платежи
- Публичные рабочие нагрузки, которые в идеальных условиях не должны взаимодействовать ни с чем из вышеперечисленного.
Перед тестированием атаки мы используем Kimera, чтобы проверить, какие средства защиты уже установлены. Приведенная ниже команда сообщает контекст безопасности каждой рабочей нагрузки и количество NetworkPolicy в пространстве имен. Для этой демонстрации мы сосредоточимся на количестве политик:
В пространстве имен нет NetworkPolicies, что является состоянием по умолчанию для нового пространства имен и все еще встречается в некоторых реальных развертываниях. Руководство по усилению безопасности Kubernetes от АНБ и CISA, стандарт CIS Kubernetes Benchmark и список OWASP Kubernetes Top 10 называют отсутствие сетевых политик распространенной ошибкой конфигурации Kubernetes. В Dynatrace Kubernetes Security Posture Management (KSPM), который постоянно проверяет ресурсы Kubernetes на соответствие элементам управления безопасностью и комплаенсу, эта же проблема отображается как DORA-67974: Убедитесь, что для всех пространств имен определены сетевые политики.
Ценность одного скомпрометированного пода
Контекст атаки: В этом сценарии злоумышленник контролирует один обращенный в интернет под, но еще не знает, что еще работает в пространстве имен. В неправильно настроенном кластере сама платформа Kubernetes может предоставить эту информацию. Соглашение об именовании DNS является публичным, и поскольку для разрешения DNS не требуются учетные данные, CoreDNS может разрешать имена служб для рабочих нагрузок, которые могут отправлять к нему запросы.
Мы рассматриваем фронтенд как скомпрометированную рабочую нагрузку, поскольку поды, обращенные в интернет, часто обеспечивают первоначальный плацдарм для злоумышленника. Одна команда выполняет разведку и проверку доступности, которую, скорее всего, попробует злоумышленник:
Первые тесты спрашивают CoreDNS, что существует:
Из скомпрометированного пода фронтенда Kimera обнаруживает 16 служб и возвращает их имена и IP-адреса. По умолчанию журналы аудита Kubernetes не записывают DNS-запросы, поэтому этот шаг обнаружения может не оставить очевидных следов в данных аудита кластера.
После обнаружения служб мы проверяем, с какими пунктами назначения может связаться скомпрометированный под: 16 служб, сервер API Kubernetes и DNS кластера. Kimera обнаруживает, что все они отвечают:
У фронтенда нет законных причин для общения с базой данных, кэшем или сервером API Kubernetes, тем не менее все три ответили на его запросы.
Запутанный заместитель
Контекст атаки: Мы предполагаем, что у злоумышленника нет действительных учетных данных базы данных и, следовательно, он не может запрашивать MariaDB напрямую. Вместо этого злоумышленник ищет путь в приложении, который выполнит запрос от его имени. Приложение делает этот запрос, используя свою собственную идентичность и полномочия, даже если у злоумышленника их нет. Это форма проблемы «запутанного заместителя» (confused deputy).
В Unguard служба proxy-service предоставляет именно такой путь. Она принимает предоставленный пользователем URL и извлекает его от имени пользователя, включая URL-адреса, указывающие на внутренние службы. Таким образом, злоумышленник может использовать ее для доступа к user-auth-service через Kimera, даже если эта служба в противном случае была бы для него недоступна напрямую.
user-auth-service аутентифицирует пользователей и имеет доступ к базовым таблицам MariaDB. Его маршрут входа принимает учетные данные через параметры запроса и конструирует поиск в базе данных с помощью замены строк. Исходный код Unguard явно указывает на возникающую уязвимость:
Эта SQL-инъекция является преднамеренной уязвимостью в Unguard, а не ошибкой конфигурации Kubernetes. Отсутствие сетевых ограничений делает уязвимую службу доступной через этот путь атаки.
Собранный запрос имеет три столбца:
Служба входа использует bcrypt.compare для проверки отправленного пароля на соответствие хешу в возвращенной строке. UNION позволяет нам предоставить эту строку, включая хеш bcrypt для выбранного нами пароля. Отправка совпадающего пароля проходит проверку, и служба выдает токен для предоставленного нами идентификатора пользователя. Отдельный запрос извлекает роли этого пользователя из базы данных.
Мы управляем всем этим через прокси-службу, из скомпрометированного пода фронтенда, используя технику L7 от Kimera, которая выполняет HTTP-запрос прикладного уровня изнутри выбранного пода:
Декодирование токена дает нам:
Теперь у нас есть корректно подписанный сеанс для пользователя с идентификатором 1, содержащий его реальную роль, при этом мы не узнали его пароль и не открывали соединение с базой данных MariaDB.
Что показывает нам Dynatrace
Dynatrace KSPM сканирует кластер по расписанию и помечает пространства имен, в которых отсутствуют сетевые политики:
Этот отфильтрованный запрос наглядно демонстрирует проблему: DORA-67974 не проходит для протестированного нами пространства имен. Результат означает, что для этого пространства имен не определены объекты NetworkPolicy, поэтому стандартное соединение между подами в Kubernetes остается открытым до тех пор, пока политики не будут созданы и применены.
Примечание: сканирование выполняется по фиксированному расписанию, поэтому в короткие промежутки времени сканирование может вообще не проводиться, и будет возвращена пустая таблица.
Примечание: сканирование выполняется по фиксированному расписанию, поэтому в короткие промежутки времени сканирование может вообще не проводиться, и будет возвращена пустая таблица.
Путь атаки виден в Dynatrace, поскольку критический переход осуществляется через proxy-service — процесс приложения, инструментированный с помощью Dynatrace OneAgent. Smartscape записывает наблюдаемые вызовы между сервисами, поэтому он может показать, когда прокси вызывает user-auth-service во время окна атаки.
За период времени до начала атаки пространство имен показывает восемь ребер, при этом трафик, исходящий от прокси, отсутствует. Каждое из них является обычным трафиком приложения, присутствующим независимо от того, идет ли атака.
Без окна до начала атаки девятое ребро выглядит как любой другой вызов сервиса; одна лишь строка топологии не говорит о том, какое ребро относится к атаке.
Smartscape также визуально отображает атаку. В этом примере злоумышленник контролирует только фронтенд. Прокси совершает второй переход, используя собственную идентификацию приложения, передавая запрос злоумышленника к бэкенд-сервису, который злоумышленник не должен иметь возможности использовать через этот путь. Этот вызов отображается как ребро, поскольку он исходит от инструментированного приложения. Более ранние зонды на основе оболочки (shell) выполнялись внутри пода и не создавали ни спана, ни ребра Smartscape.
KSPM сообщает о результатах для рабочих нагрузок Kubernetes, в то время как Smartscape называет сервисы по идентификации приложения. Это означает, что одна и та же рабочая нагрузка может фигурировать под двумя именами: proxy-service в KSPM и ProxyController в Smartscape. Чтобы связать результат конфигурации с наблюдаемым путем атаки, мы объединяем результаты KSPM с ребрами Smartscape из окна атаки:
Для proxy-service возвращаются два элемента управления: DORA-67954, «Минимизация доступа к созданию подов», и DOR_67955, «Обеспечение того, чтобы учетные записи сервисов по умолчанию не использовались активно». В отчете о соответствии требованиям они выглядят как обычные результаты управления доступом на основе ролей (RBAC) и учетных записей сервисов, ранжированные по правилам, а не по действиям рабочей нагрузки.
Закрытие маршрутов
Решением является набор объектов NetworkPolicy. Эти объекты работают только тогда, когда CNI кластера обеспечивает их соблюдение; в плагине без механизма политик политики будут существовать, но трафик все равно будет разрешен. Для этой демонстрации мы используем Cilium, поэтому приведенные ниже политики применяются.
Теперь мы используем Kimera для создания набора защитных политик на основе путей, достигнутых во время эксплойта. В этой демонстрации LLM составляет рекомендации по исправлению, используя результаты Dynatrace и данные топологии, полученные через протокол Model Context Protocol:
Эти девять ребер Smartscape — тот же набор, который вернул наш запрос топологии, включая переход атаки.
Kimera классифицирует каждый путь перед тем, как что-либо записывать:
Пользователь решает, какие зависимости являются легитимными; Kimera не делает выводов за него. Пути, объявленные в профиле, классифицируются как KEEP. Пути REVIEW остаются запрещенными до тех пор, пока пользователь их не одобрит. Мы сохраняем доступ к DNS, поскольку блокировка разрешения имен привела бы к нарушению работы рабочей нагрузки, не закрыв при этом путь атаки.
Применение набора создает 19 политик:
Проверка
Чтобы проверить исправление, мы повторно запускаем ту же команду, которая использовалась при атаке. Повторение ее каждые 20 секунд во время окна проверки помогает отличить заблокированный путь от пути, который просто простаивал:
Цепочка прерывается на user-auth-service, поскольку его правило входящего трафика исключает proxy-service. Правило разрешает только фронтенд, ad-service, like-service и microblog-service. Эти четыре вызывающих объекта объявлены в network_topology профиля и сохраняют доступ для аутентификации пользователей. Остальные 11 рабочих нагрузок теряют доступ.
Тот же набор политик дает proxy-service правило исходящего трафика, поскольку ему все еще нужно получать внешние URL-адреса, что является частью его предполагаемого поведения в Unguard. Это правило разрешает 0.0.0.0/0, но исключает частные диапазоны IP-адресов — 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 — и адрес метаданных облака 169.254.169.254/32. Исключение частных диапазонов закрывает вариант, когда та же SSRF нацелена на IP пода вместо имени сервиса, поскольку сеть подов находится внутри этих диапазонов. Правило не ограничивает, на какой внешний хост может быть направлен прокси.
Топология за период после вступления политик в силу показывает, что наше ребро атаки исчезло, а восемь обычных ребер приложения остались неизменными, включая собственный вызов фронтенда к прокси:
KSPM отражает изменение политики при следующем сканировании. Фиксация идентификатора правила и чтение трех последовательных сканирований показывают переход от состояния «не пройдено» к «пройдено»:
Контроль соответствия требованиям проходит при следующем сканировании:
NetworkPolicy блокирует путь «запутанного заместителя» (confused deputy), но не устраняет уязвимость SQL-инъекции в приложении. Фронтенд остается объявленным вызывающим объектом user-auth-service, поэтому инъекция все еще может работать через разрешенный путь. Политика сокращает количество рабочих нагрузок, которые могут достичь сервиса аутентификации, с 15 до четырех. Устранение уязвимости по-прежнему требует внесения изменений в код приложения.
Вся последовательность, от отсутствующего контроля до проверенного исправления, проходит через пять этапов, как показано ниже:
Основные выводы
- Сети Kubernetes по умолчанию имеют полную связность, а DNS-перечисление каждого сервиса не оставляет записей в журнале аудита Kubernetes.
- Одной лишь достижимости было недостаточно для получения сеанса. Для превращения ее в сеанс потребовалось приложение, которое могло бы получать URL-адрес по запросу, и бэкенд с уязвимостью на уровне приложения.
- Движение, осуществляемое инструментированным приложением, отображается в топологии, в то время как оболочка, которую злоумышленник запускает внутри пода, — нет, поэтому мы подтвердили блокировку с помощью прямого зонда достижимости.
- Контроль соответствия требованиям может проверить, определены ли политики, без .
Следующие шаги
- Проведите аудит своих пространств имен. Запустите запрос KSPM из предыдущего раздела для своих собственных пространств имен с двумя изменениями: удалите фильтр k8s.namespace.name, чтобы он охватывал все пространства имен, и выполните дедупликацию по {check, namespace}, чтобы каждое пространство имен отчитывалось отдельно. Любое пространство имен, возвращающее FAILED по DORA-67974 или по варианту CIS 5.3.2 того же контроля, не имеет определенной NetworkPolicy.
- Ознакомьтесь с серией статей. Сегментация сети дополняет усиление защиты контейнеров из части 3 и контроль рабочих нагрузок из части 2. Эти элементы управления формируют базовый уровень безопасности при совместном использовании; ни один из них не является достаточным сам по себе.
- Далее: RBAC. Плоская сеть — это то, как злоумышленники перемещаются латерально. Чрезмерно разрешительные роли и привязки — это то, как они эскалируют привилегии вертикально; от одного пода до cluster-admin. Часть 5 этой серии будет посвящена этой цепочке атак.
Готовы обеспечить безопасность ваших контейнеров Kubernetes? Узнайте, как начать работу с Kubernetes Security Posture Management, или начните бесплатную пробную версию Dynatrace и посмотрите, как KSPM может автоматически обнаруживать и помогать устранять ошибки конфигурации контейнеров в вашей среде.
Дополнительные ресурсы
- Документация по сетевым политикам Kubernetes
- Сетевое взаимодействие кластеров Kubernetes
- Стандарт безопасности CIS Kubernetes – Сетевые политики
- Документация Dynatrace KSPM
- Репозиторий приложений Unguard
Методы, продемонстрированные в этой статье, предназначены только для образовательных целей. Всегда получайте надлежащее разрешение перед тестированием средств контроля безопасности в любой среде.












