AWS - EKS Post Exploitation

Reading time: 7 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

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

bash
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:<acc-id>:cluster/<cluster-name>
contexts:
- context:
cluster: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
user: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
current-context: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
kind: Config
preferences: {}
users:
- name: arn:aws:eks:us-east-1:<acc-id>:cluster/<cluster-name>
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- us-west-2
- --profile
- <profile>
- eks
- get-token
- --cluster-name
- <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

bash
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

python
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

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