# AWS - EKS Post Exploitation

{{#include ../../../banners/hacktricks-training.md}}

## EKS

Pour plus d'informations, consultez

{{#ref}}
../aws-services/aws-eks-enum.md
{{#endref}}

### Énumérer le cluster depuis la console AWS

Si vous avez la permission **`eks:AccessKubernetesApi`**, vous pouvez **voir les objets Kubernetes** via la console AWS EKS ([En savoir plus](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html)).

### Se connecter au cluster Kubernetes AWS

- Facile :
```bash
# Generate kubeconfig
aws eks update-kubeconfig --name aws-eks-dev
```
- Pas si facile :

Si vous pouvez **obtenir un token** avec **`aws eks get-token --name <cluster_name>`** mais que vous n'avez pas les permissions pour obtenir les informations du cluster (describeCluster), vous pourriez **préparer votre propre `~/.kube/config`**. Cependant, avec le token, vous avez toujours besoin de l'**url endpoint pour vous connecter** (si vous avez réussi à obtenir un token JWT d'un pod lisez [ici](aws-eks-post-exploitation.md#get-api-server-endpoint-from-a-jwt-token)) et du **nom du cluster**.

Dans mon cas, je n'ai pas trouvé l'info dans les logs CloudWatch, mais j'ai **trouvé dans les userData des LaunchTemplates** et dans les **machines EC2 dans userData aussi**. Vous pouvez voir cette info dans **userData** facilement, par exemple dans l'exemple suivant (le nom du cluster était 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
```
<details>

<summary>kube config</summary>
```yaml
describe-cache-parametersapiVersion: v1
clusters:
- cluster:
certificate-authority-data:  
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
```
</details>

### D'AWS à Kubernetes

Le **créateur** du **cluster EKS** sera **TOUJOURS** capable d'accéder à la partie du cluster kubernetes du groupe **`system:masters`** (admin k8s). Au moment de la rédaction de ce document, 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 **supprimer** ce **privilège**.

La façon de donner **accès à plus d'utilisateurs ou de rôles AWS IAM sur K8s** est d'utiliser le **configmap** **`aws-auth`**.

> [!WARNING]
> Par conséquent, toute personne ayant un **accès en écriture** sur le config map **`aws-auth`** pourra **compromettre l'ensemble du cluster**.

Pour plus d'informations sur la façon de **donner des privilèges supplémentaires aux rôles et utilisateurs IAM** dans le **même ou un autre compte** et comment **abuser** de cela pour [**privesc, consultez cette page**](../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/#aws-eks-aws-auth-configmaps).

Vérifiez aussi [**ce post génial**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **pour apprendre comment fonctionne l'authentification IAM -> Kubernetes**.

### De Kubernetes à AWS

Il est possible de permettre une **authentification OpenID pour le compte de service kubernetes** afin de leur permettre d'assumer des rôles dans AWS. Apprenez comment [**cela fonctionne sur cette page**](../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1).

### OBTENIR le point de terminaison de l'API Server à partir d'un jeton JWT

En décodant le jeton JWT, nous obtenons l'ID du cluster et aussi la région. ![image](https://github.com/HackTricks-wiki/hacktricks-cloud/assets/87022719/0e47204a-eea5-4fcb-b702-36dc184a39e9) 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 qui explique 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 souvent :

- gr7
- yl4

Quoi qu'il en soit, ce ne sont que 3 caractères que nous pouvons brute-forcer. 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 & .

### Contournement de CloudTrail

Si un attaquant obtient des identifiants d'un AWS avec **permission 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 token localement).

Ainsi, lorsque l'attaquant communique avec le cluster EKS, **cloudtrail ne journalisera rien lié à l'utilisateur 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.

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

> [!TIP]
> Notez que si le cluster utilisait des **VM EC2**, il pourrait être possible d'obtenir des privilèges d'administrateur depuis le **Node** et de récupérer le cluster.
>
> En fait, si le cluster utilise Fargate, vous pourriez EC2 nodes ou déplacer tout vers EC2 vers le cluster et le récupérer en accédant aux tokens dans le node.

{{#include ../../../banners/hacktricks-training.md}}
