AWS - EKS Post Exploitation

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks:

EKS

Pour plus d'informations, consultez

pageAWS - EKS Enum

Enumérer le cluster depuis la console AWS

Si vous avez l'autorisation eks:AccessKubernetesApi, vous pouvez afficher les objets Kubernetes via la console AWS EKS (En savoir plus).

Se connecter au cluster Kubernetes AWS

  • Facilement :

# Generate kubeconfig
aws eks update-kubeconfig --name aws-eks-dev
  • Pas si facile :

Si vous pouvez obtenir un jeton avec aws eks get-token --name <cluster_name> mais que vous n'avez pas les autorisations pour obtenir des informations sur le cluster (describeCluster), vous pourriez préparer votre propre ~/.kube/config. Cependant, en ayant le jeton, vous avez toujours besoin de l'URL de point de terminaison pour vous connecter (si vous avez réussi à obtenir un jeton JWT à partir d'un pod, lisez ici) et du nom du cluster.

Dans mon cas, je n'ai pas trouvé les informations dans les journaux CloudWatch, mais je les ai trouvées dans les données utilisateur des LaunchTemplates et également dans les machines EC2 dans les données utilisateur. Vous pouvez voir ces informations dans userData facilement, par exemple dans l'exemple suivant (le nom du cluster était cluster-name):

API_SERVER_URL=https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-east-1.eks.amazonaws.com

/etc/eks/bootstrap.sh cluster-name --kubelet-extra-args '--node-labels=eks.amazonaws.com/sourceLaunchTemplateVersion=1,alpha.eksctl.io/cluster-name=cluster-name,alpha.eksctl.io/nodegroup-name=prd-ondemand-us-west-2b,role=worker,eks.amazonaws.com/nodegroup-image=ami-002539dd2c532d0a5,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup=prd-ondemand-us-west-2b,type=ondemand,eks.amazonaws.com/sourceLaunchTemplateId=lt-0f0f0ba62bef782e5 --max-pods=58' --b64-cluster-ca $B64_CLUSTER_CA --apiserver-endpoint $API_SERVER_URL --dns-cluster-ip $K8S_CLUSTER_DNS_IP --use-max-pods false
configuration kube

```yaml describe-cache-parametersapiVersion: v1 clusters: - cluster: certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1USXlPREUyTWpjek1Wb1hEVE15TVRJeU5URTJNamN6TVZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTDlXCk9OS0ZqeXZoRUxDZGhMNnFwWkMwa1d0UURSRVF1UzVpRDcwK2pjbjFKWXZ4a3FsV1ZpbmtwOUt5N2x2ME5mUW8KYkNqREFLQWZmMEtlNlFUWVVvOC9jQXJ4K0RzWVlKV3dzcEZGbWlsY1lFWFZHMG5RV1VoMVQ3VWhOanc0MllMRQpkcVpzTGg4OTlzTXRLT1JtVE5sN1V6a05pTlUzSytueTZSRysvVzZmbFNYYnRiT2kwcXJSeFVpcDhMdWl4WGRVCnk4QTg3VjRjbllsMXo2MUt3NllIV3hhSm11eWI5enRtbCtBRHQ5RVhOUXhDMExrdWcxSDBqdTl1MDlkU09YYlkKMHJxY2lINjYvSTh0MjlPZ3JwNkY0dit5eUNJUjZFQURRaktHTFVEWUlVSkZ4WXA0Y1pGcVA1aVJteGJ5Nkh3UwpDSE52TWNJZFZRRUNQMlg5R2c4Q0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZQVXFsekhWZmlDd0xqalhPRmJJUUc3L0VxZ1hNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBS1o4c0l4aXpsemx0aXRPcGcySgpYV0VUSThoeWxYNWx6cW1mV0dpZkdFVVduUDU3UEVtWW55eWJHbnZ5RlVDbnczTldMRTNrbEVMQVE4d0tLSG8rCnBZdXAzQlNYamdiWFovdWVJc2RhWlNucmVqNU1USlJ3SVFod250ZUtpU0J4MWFRVU01ZGdZc2c4SlpJY3I2WC8KRG5POGlHOGxmMXVxend1dUdHSHM2R1lNR0Mvd1V0czVvcm1GS291SmtSUWhBZElMVkNuaStYNCtmcHUzT21UNwprS3VmR0tyRVlKT09VL1c2YTB3OTRycU9iSS9Mem1GSWxJQnVNcXZWVDBwOGtlcTc1eklpdGNzaUJmYVVidng3Ci9sMGhvS1RqM0IrOGlwbktIWW4wNGZ1R2F2YVJRbEhWcldDVlZ4c3ZyYWpxOUdJNWJUUlJ6TnpTbzFlcTVZNisKRzVBPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== server: https://6253F6CA47F81264D8E16FAA7A103A0D.gr7.us-west-2.eks.amazonaws.com name: arn:aws:eks:us-east-1::cluster/ contexts: - context: cluster: arn:aws:eks:us-east-1::cluster/ user: arn:aws:eks:us-east-1::cluster/ name: arn:aws:eks:us-east-1::cluster/ current-context: arn:aws:eks:us-east-1::cluster/ kind: Config preferences: {} users: - name: arn:aws:eks:us-east-1::cluster/ user: exec: apiVersion: client.authentication.k8s.io/v1beta1 args: - --region - us-west-2 - --profile - - eks - get-token - --cluster-name - command: aws env: null interactiveMode: IfAvailable provideClusterInfo: false ```

De AWS à Kubernetes

Le créateur du cluster EKS pourra TOUJOURS accéder à la partie du cluster Kubernetes du groupe system:masters (administrateur k8s). À l'heure où ces lignes sont écrites, il n'y a aucun moyen direct de savoir qui a créé le cluster (vous pouvez vérifier CloudTrail). Et il n'y a aucun moyen de retirer ce privilège.

La manière d'accorder l'accès à plus d'utilisateurs ou de rôles IAM AWS sur K8s est d'utiliser le configmap aws-auth.

Par conséquent, toute personne ayant un accès en écriture sur le configmap aws-auth pourra compromettre l'ensemble du cluster.

Pour plus d'informations sur la manière d'accorder des privilèges supplémentaires aux rôles et utilisateurs IAM dans le même compte ou un compte différent et sur la manière d'abuser de cela pour vérifier les privilèges.

Consultez également cet article impressionnant pour apprendre comment fonctionne l'authentification IAM -> Kubernetes.

De Kubernetes à AWS

Il est possible d'autoriser une authentification OpenID pour le compte de service Kubernetes pour leur permettre d'assumer des rôles dans AWS. Apprenez comment cela fonctionne sur cette page.

Obtenir l'endpoint du serveur API à partir d'un jeton JWT

https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com

Je n'ai trouvé aucune documentation expliquant les critères pour les 'deux caractères' et le 'nombre'. Mais en faisant quelques tests de mon côté, je vois que ceux-ci reviennent régulièrement :

  • gr7

  • yl4

Quoi qu'il en soit, ce ne sont que 3 caractères que nous pouvons les bruteforcer. Utilisez le script ci-dessous pour générer la liste

from itertools import product
from string import ascii_lowercase

letter_combinations = product('abcdefghijklmnopqrstuvwxyz', repeat = 2)
number_combinations = product('0123456789', repeat = 1)

result = [
f'{''.join(comb[0])}{comb[1][0]}'
for comb in product(letter_combinations, number_combinations)
]

with open('out.txt', 'w') as f:
f.write('\n'.join(result))

Ensuite avec wfuzz

wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com

N'oubliez pas de remplacer & .

Contourner CloudTrail

Si un attaquant obtient des informations d'identification d'un AWS avec des autorisations sur un EKS. Si l'attaquant configure son propre kubeconfig (sans appeler update-kubeconfig) comme expliqué précédemment, le get-token ne génère pas de journaux dans Cloudtrail car il n'interagit pas avec l'API AWS (il crée simplement le jeton localement).

Ainsi, lorsque l'attaquant communique avec le cluster EKS, cloudtrail ne va pas enregistrer quoi que ce soit en rapport avec l'utilisateur ayant été volé et y accédant.

Notez que le cluster EKS pourrait avoir des journaux activés qui enregistreront cet accès (bien que, par défaut, ils soient désactivés).

Rançon EKS?

Par défaut, l'utilisateur ou le rôle qui a créé un cluster a toujours des privilèges d'administrateur sur le cluster. Et c'est le seul accès "sécurisé" qu'AWS aura sur le cluster Kubernetes.

Ainsi, si un attaquant compromet un cluster en utilisant Fargate et supprime tous les autres administrateurs et supprime l'utilisateur/le rôle AWS qui a créé le Cluster, l'attaquant pourrait avoir rançonné le clusterr.

Notez que si le cluster utilisait des VM EC2, il pourrait être possible d'obtenir des privilèges d'administrateur à partir du nœud et de récupérer le cluster.

En fait, si le cluster utilise Fargate, vous pourriez utiliser des nœuds EC2 ou tout déplacer vers EC2 dans le cluster et le récupérer en accédant aux jetons dans le nœud.

Apprenez le piratage AWS de zéro à héros avec htARTE (HackTricks AWS Red Team Expert)!

Autres façons de soutenir HackTricks:

Dernière mise à jour