AWS - EKS Post Exploitation

Tip

Apprenez & pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Soutenez HackTricks

EKS

Pour plus d’informations, consultez

AWS - EKS Enum

ÉnumĂ©rer le cluster depuis la console AWS

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

Se connecter au cluster Kubernetes AWS

  • MĂ©thode simple:
# Generate kubeconfig
aws eks update-kubeconfig --name aws-eks-dev
  • Pas si simple :

Si vous pouvez get a token avec aws eks get-token --name <cluster_name> mais que vous n’avez pas les permissions pour obtenir les infos du cluster (describeCluster), vous pouvez prĂ©parer votre propre ~/.kube/config. Cependant, mĂȘme avec le token, il vous faut encore l’url endpoint pour vous connecter (si vous avez rĂ©ussi Ă  obtenir un JWT token depuis un pod, lisez ici) et le nom du cluster.

Dans mon cas, je n’ai pas trouvĂ© l’info dans CloudWatch logs, mais je l’ai trouvĂ©e dans LaunchTemaplates userData et aussi dans les EC2 machines in userData. Vous pouvez voir cette info dans userData facilement, par exemple dans l’exemple suivant (le cluster name was 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
kube config ```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 EKS cluster pourra TOUJOURS accĂ©der Ă  la partie cluster kubernetes faisant partie du groupe system:masters (k8s admin). Au moment de la rĂ©daction, il n’existe aucun moyen direct pour savoir qui a créé le cluster (vous pouvez vĂ©rifier CloudTrail). Et il n’y a aucune façon de supprimer ce privilĂšge.

La mĂ©thode pour accorder l’accĂšs Ă  K8s Ă  davantage d’utilisateurs ou rĂŽles AWS IAM est d’utiliser le configmap aws-auth.

Warning

Par consĂ©quent, toute personne ayant un accĂšs en Ă©criture au configmap aws-auth pourra compromettre l’ensemble du cluster.

Pour plus d’informations sur la maniĂšre de donner des privilĂšges supplĂ©mentaires aux rĂŽles et utilisateurs IAM dans le mĂȘme ou un autre compte et sur la façon de abuser de cela, voir privesc check this page.

Check also this awesome post to learn how the authentication IAM -> Kubernetes work.

De Kubernetes Ă  AWS

Il est possible d’autoriser une authentification OpenID pour kubernetes service account afin de leur permettre d’assumer des rîles dans AWS. Learn how this work in this page.

GET Api Server Endpoint from a JWT Token

En dĂ©codant le token JWT, on obtient l’ID du cluster et aussi la rĂ©gion. image Sachant que le format standard pour l’URL EKS est

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

Je n’ai trouvĂ© aucune documentation expliquant les critĂšres pour les ‘two chars’ et le ‘number’. Mais aprĂšs quelques tests de mon cĂŽtĂ©, je remarque que ces valeurs reviennent souvent :

  • gr7
  • yl4

De toute façon, ce ne sont que 3 caractÚres ; on peut les bruteforce. 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

Warning

N’oubliez pas de remplacer & .

Bypass CloudTrail

If an attacker obtains credentials of an AWS with permission over an EKS. If the attacker configures it’s own kubeconfig (without calling update-kubeconfig) as explained previously, the get-token doesn’t generate logs in Cloudtrail because it doesn’t interact with the AWS API (it just creates the token locally).

So when the attacker talks with the EKS cluster, cloudtrail won’t log anything related to the user being stolen and accessing it.

Note that the EKS cluster might have logs enabled that will log this access (although, by default, they are disabled).

EKS Ransom?

By default the user or role that created a cluster is ALWAYS going to have admin privileges over the cluster. And that the only “secure” access AWS will have over the Kubernetes cluster.

So, if an attacker compromises a cluster using fargate and removes all the other admins and deletes the AWS user/role that created the Cluster, l’attaquant pourrait avoir rançonnĂ© le cluster.

Tip

Notez que si le cluster utilisait des EC2 VMs, il pourrait ĂȘtre possible d’obtenir des privilĂšges Admin depuis le Node et rĂ©cupĂ©rer le cluster.

En fait, si le cluster utilise Fargate, vous pourriez crĂ©er des nƓuds EC2 ou migrer tout vers EC2 dans le cluster et le rĂ©cupĂ©rer en accĂ©dant aux tokens sur le nƓud.

Tip

Apprenez & pratiquez AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Apprenez & pratiquez GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apprenez & pratiquez Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Soutenez HackTricks