Перейти к основному содержимому
  1. Блог/

Получаем доступ к сервисам через Kubernetes

·3 минут·

У экспертов по анализу защищённости часто возникает ситуация, когда во время пентеста уже получен доступ к внутренней инфраструктуре, а что интересного есть в этой инфраструктуре — непонятно.

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

Один из способов обнаружить ноды — найти, какие хосты используют SSL-сертификат с common name Kubernetes Ingress Controller Fake Certificate. Например, это можно сделать с помощью скрипта для nmap ssl-cert.

На одном из проектов мы нашли таким способом 47 нод. И по некоторым хостнеймам и подсетям сделали вывод, что кластер не один. Но как узнать, какие сервисы запущены в этих кластерах?

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

В директории /etc/kubernetes/ на мастер-ноде был конфиг не только самой ноды, но и администратора кластера, что позволило не тратить время на повышение привилегий.

Так как Kubernetes API доступен был только на localhost мастер-ноды, использовали опцию -D при подключении по SSH к ноде, и с конфигом администратора кластера получили полный доступ к API. А затем собрали всю необходимую информацию о кластере K8s, добавив опцию для игнорирования недоверенного сертификата и переменную окружения для работы через прокси:

export KUBECONFIG=~/admin.conf
HTTPS_PROXY=socks5://127.0.0.1:1080 kubectl --insecure-skip-tls-verify=true cluster-info

Список нод поможет оценить размер кластера и отметить хосты, которые к нему относятся:

kubectl get nodes -o wide

По названиям неймспейсов можно попытаться понять, какие сервисы запущены в кластере (например, minio или keycloak):

kubectl get namespaces

Для получения полных конфигов подов можно использовать вывод в формате yaml. Из результата выполнения команды можно получить список подов, информацию о том, какие образы используют контейнеры, на каких портах слушают сервисы, что примонтировано в файловую систему пода. Зачастую из передаваемых в контейнеры переменных окружения можно получить учетные данные или полезные параметры конфигурации сервисов. Параметр -A для команды позволит получить сведения сразу для всех пространств имен:

kubectl get pods -A -o yaml

В списке ingress-ов можно увидеть имена виртуальных хостов и правила маршрутизации трафика (на уровне L7):

kubectl get ingress -A

Пример вывода:

NAMESPACE  NAME  CLASS  HOSTS      ADDRESS    PORTS
minio    minio  nginx  s3.domain.local  10.10.10.10  80,  443

Configmap-ы предназначены для хранения настроек в виде пар “ключ-значение”. И хотя не рекомендуется хранить в них учётные данные, ключи и подобные настройки, они там все равно встречаются. А ещё скрипты, настройки coredns и другие конфигурационные файлы. Поэтому заглянем и туда:

kubectl get configmaps -A -o yaml

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

kubectl get secrets -A
kubectl get secret -n <namespace> <secret_name>

Если в списке ingress-ов мы обнаружили виртуальный хост, а при обращении к нему получаем 404, то для поиска нужного пути можно посмотреть логи nginx (для каждого пода ingress-nginx-controller).

kubectl get logs -n ingress-nginx ingress-nginx-controller-<id>

Анализируя полученную информацию, мы можем получить доступ к сервисам. Например, мы в конфиге пода обнаружили, что используются значения из секрета minio для доступа к S3-хранилищу на узле minio.minio.svc.cluster.local. А в списке ingress-ов увидели, что виртуальный хост s3.domain.local доступен на хосте 10.10.10.10, и входящий трафик на порт 443/TCP перенаправляется на под minio в неймспейсе minio. Используя значения секрета, мы получили доступ к содержимому бакетов в S3-хранилище и реализовали один из бизнес-рисков.

Related