Про безопасность в K8S
https://t.me/monkey_hackerВообще, перед тем как рассматривать проблемы в Kubernetes, стоит разобрать основы.
И так для чего нужен Kubernetes (K8S)?
K8S нужен для автоматизации развертывания контейнизированных приложений.
Т.е используемая технология - Docker. А основной используемый компонент K8s это - Cluster. K8S Cluster создается с помощью Nodes (сервера)
Есть два типа Nodes:
- Worker Node - сервер на котором запускаются и работают контейнеры
- 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 это:
- Pod - состоит из контейнера/контейнеров
- Deployment - копия pods
- Service - дает доступ к deployment
- Nodes - сервер где работает service
- 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
А на этом всё :)