AWS - EKS Post Exploitation
Reading time: 7 minutes
tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
EKS
Para mais informações, veja
Enumerar o cluster pelo AWS Console
Se você tem a permissão eks:AccessKubernetesApi, você pode visualizar objetos do Kubernetes via AWS EKS console (Saiba mais).
Conectar ao AWS Kubernetes Cluster
- Maneira fácil:
# Generate kubeconfig
aws eks update-kubeconfig --name aws-eks-dev
- Não é tão simples:
Se você consegue obter um token com aws eks get-token --name <cluster_name> mas não tem permissões para obter informações do cluster (describeCluster), você pode preparar seu próprio ~/.kube/config. No entanto, tendo o token, você ainda precisa do endpoint URL para se conectar (se você conseguiu um JWT token de um pod leia aqui) e do nome do cluster.
No meu caso, não encontrei as informações nos logs do CloudWatch, mas eu as encontrei em LaunchTemaplates userData e também em máquinas EC2 no userData. Você pode ver essas informações no userData facilmente, por exemplo no exemplo abaixo (o nome do cluster era 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
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
From AWS to Kubernetes
O criador do EKS cluster sempre terá acesso à parte do kubernetes pertencente ao grupo system:masters (k8s admin). No momento desta escrita não existe uma forma direta de descobrir quem criou o cluster (você pode checar CloudTrail). E não há como remover esse privilégio.
A forma de conceder acesso ao K8s para mais AWS IAM users or roles é usando o configmap aws-auth.
warning
Portanto, qualquer pessoa com write access sobre o config map aws-auth poderá comprometer todo o cluster.
Para mais informações sobre como conceder privilégios extras a IAM roles & users na mesma ou em outra conta e como abusar disso veja privesc check this page.
Confira também this awesome post para aprender como a autenticação IAM -> Kubernetes funciona.
De Kubernetes para AWS
É possível permitir uma OpenID authentication para kubernetes service account para que elas possam assumir roles na AWS. Saiba como this work in this page.
Obter o endpoint do API Server a partir de um token JWT
Decodificando o token JWT obtemos o cluster id e também a região. Sabendo que o formato padrão para a URL do EKS é
https://<cluster-id>.<two-random-chars><number>.<region>.eks.amazonaws.com
Não encontrei nenhuma documentação que explique os critérios para os 'two chars' e o 'number'. Mas, fazendo alguns testes por minha conta, vejo que estes aparecem com frequência:
- gr7
- yl4
De qualquer forma, são apenas 3 chars; podemos usar bruteforce neles. Use o script abaixo para gerar a lista
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))
Em seguida, com wfuzz
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com
warning
Lembre-se de substituir & .
Bypass CloudTrail
Se um atacante obtiver credenciais de uma conta AWS com permissão sobre um EKS. Se o atacante configurar seu próprio kubeconfig (sem chamar update-kubeconfig) como explicado anteriormente, o get-token não gera logs no Cloudtrail porque não interage com a API da AWS (ele apenas cria o token localmente).
Então, quando o atacante se comunica com o cluster EKS, cloudtrail não vai registrar nada relacionado ao usuário comprometido e ao seu acesso.
Observe que o cluster EKS pode ter logs habilitados que irão registrar esse acesso (embora, por padrão, eles estejam desabilitados).
Ransom no EKS?
Por padrão o usuário ou role que criou um cluster sempre terá privilégios de admin sobre o cluster. E esse é o único acesso "seguro" que a AWS terá sobre o cluster Kubernetes.
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, o atacante poderia ter extorquido o cluster.
tip
Observe que se o cluster estiver usando EC2 VMs, pode ser possível obter privilégios de Admin a partir do Node e recuperar o cluster.
Na verdade, se o cluster estiver usando Fargate, você poderia criar nodes EC2 ou mover tudo para EC2 no cluster e recuperá‑lo acessando os tokens no node.
tip
Aprenda e pratique Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP:
HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
HackTricks Cloud