mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-15 22:32:31 -08:00
Translated ['src/pentesting-cloud/aws-security/aws-unauthenticated-enum-
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
# AWS - EKS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## EKS
|
||||
|
||||
Para más información consulta
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-eks-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### Enumerar el clúster desde la consola de AWS
|
||||
|
||||
Si tienes el permiso **`eks:AccessKubernetesApi`** puedes **ver objetos de Kubernetes** a través de la consola de AWS EKS ([Learn more](https://docs.aws.amazon.com/eks/latest/userguide/view-workloads.html)).
|
||||
|
||||
### Conectar al clúster de Kubernetes de AWS
|
||||
|
||||
- Forma fácil:
|
||||
```bash
|
||||
# Generate kubeconfig
|
||||
aws eks update-kubeconfig --name aws-eks-dev
|
||||
```
|
||||
- No tan fácil:
|
||||
|
||||
Si puedes **get a token** con **`aws eks get-token --name <cluster_name>`** pero no tienes permisos para obtener información del cluster (describeCluster), podrías **preparar tu propio `~/.kube/config`**. Sin embargo, teniendo el token, todavía necesitas el **url endpoint to connect to** (si lograste obtener un JWT token desde un pod lee [aquí](aws-eks-post-exploitation/README.md#get-api-server-endpoint-from-a-jwt-token)) y el **nombre del cluster**.
|
||||
|
||||
En mi caso, no encontré la información en los logs de CloudWatch, pero **la encontré en LaunchTemaplates userData** y también en **las máquinas EC2 en userData**. Puedes ver esta información en **userData** fácilmente, por ejemplo en el siguiente ejemplo (el nombre del cluster era 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: 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
|
||||
```
|
||||
</details>
|
||||
|
||||
### From AWS to Kubernetes
|
||||
|
||||
El **creador** del **EKS cluster** va a poder **SIEMPRE** acceder a la parte de kubernetes del grupo **`system:masters`** (admin k8s). Al momento de escribir esto no hay **manera directa** de saber **quién creó** el cluster (puedes revisar CloudTrail). Y no hay **forma** de **eliminar** ese **privilegio**.
|
||||
|
||||
La forma de conceder **acceso sobre K8s a más AWS IAM usuarios o roles** es usando el **configmap** **`aws-auth`**.
|
||||
|
||||
> [!WARNING]
|
||||
> Por lo tanto, cualquiera con **acceso de escritura** sobre el config map **`aws-auth`** podrá **comprometer todo el cluster**.
|
||||
|
||||
Para más información sobre cómo **conceder privilegios extra a IAM roles & users** en la **misma o diferente cuenta** y cómo **abusar** de esto para [**privesc revisa esta página**](../../../kubernetes-security/abusing-roles-clusterroles-in-kubernetes/index.html#aws-eks-aws-auth-configmaps).
|
||||
|
||||
Check also[ **este excelente post**](https://blog.lightspin.io/exploiting-eks-authentication-vulnerability-in-aws-iam-authenticator) **para aprender cómo funciona la autenticación IAM -> Kubernetes**.
|
||||
|
||||
### From Kubernetes to AWS
|
||||
|
||||
Es posible permitir una **autenticación OpenID para kubernetes service account** para permitirles asumir roles en AWS. Aprende cómo [**esto funciona en esta página**](../../../kubernetes-security/kubernetes-pivoting-to-clouds.md#workflow-of-iam-role-for-service-accounts-1).
|
||||
|
||||
### GET Api Server Endpoint from a JWT Token
|
||||
|
||||
Al decodificar el token JWT obtenemos el cluster id y también la región.  Sabiendo que el formato estándar para la url de EKS es
|
||||
```bash
|
||||
https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com
|
||||
```
|
||||
No encontré ninguna documentación que explique los criterios para los 'dos caracteres' y el 'número'. Pero haciendo algunas pruebas por mi parte veo que se repiten estos:
|
||||
|
||||
- gr7
|
||||
- yl4
|
||||
|
||||
De todas formas son solo 3 caracteres; podemos bruteforcearlos. Usa el siguiente script para generar la lista
|
||||
```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))
|
||||
```
|
||||
Luego con wfuzz
|
||||
```bash
|
||||
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com
|
||||
```
|
||||
> [!WARNING]
|
||||
> Recuerda reemplazar & .
|
||||
|
||||
### Bypass CloudTrail
|
||||
|
||||
Si un attacker obtiene credenciales de un AWS con **permiso sobre un EKS**. Si el attacker configura su propio **`kubeconfig`** (sin ejecutar **`update-kubeconfig`**) como se explicó anteriormente, el **`get-token`** no genera logs en Cloudtrail porque no interactúa con la AWS API (solo crea el token localmente).
|
||||
|
||||
Así que cuando el attacker se comunica con el EKS cluster, **cloudtrail no registrará nada relacionado con el user robado y su acceso**.
|
||||
|
||||
Ten en cuenta que el **EKS cluster podría tener logs habilitados** que registrarán este acceso (aunque, por defecto, están deshabilitados).
|
||||
|
||||
### ¿Rescate en EKS?
|
||||
|
||||
Por defecto, el **user o role que creó** un cluster va a tener SIEMPRE **admin privileges** sobre el cluster. Y ese es el único acceso "seguro" que AWS tendrá sobre el Kubernetes cluster.
|
||||
|
||||
Entonces, si un **attacker compromete un cluster usando fargate** y **elimina a todos los otros admins** y elimina el AWS user/role que creó el Cluster, ~~el attacker podría haber exigido un rescate al cluster~~.
|
||||
|
||||
> [!TIP]
|
||||
> Ten en cuenta que si el cluster estaba usando **EC2 VMs**, podría ser posible obtener Admin privileges desde el **Node** y recuperar el cluster.
|
||||
>
|
||||
> De hecho, si el cluster está usando Fargate podrías añadir EC2 nodes o mover todo a EC2 en el cluster y recuperarlo accediendo a los tokens en el node.
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
Reference in New Issue
Block a user