AWS - EKS Post Exploitation

Reading time: 6 minutes

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

EKS

Kwa taarifa zaidi angalia

AWS - EKS Enum

Orodhesha klasta kutoka AWS Console

Ikiwa una ruhusa eks:AccessKubernetesApi unaweza kuona vitu vya Kubernetes kupitia AWS EKS console (Learn more).

Unganisha kwenye AWS Kubernetes Cluster

  • Njia rahisi:
bash
# Generate kubeconfig
aws eks update-kubeconfig --name aws-eks-dev
  • Njia sio rahisi hivyo:

Ikiwa unaweza pata token kwa kutumia aws eks get-token --name <cluster_name> lakini huna ruhusa za kupata taarifa za cluster (describeCluster), unaweza andaa yako mwenyewe ~/.kube/config. Hata hivyo, ukishokuwa na token, bado unahitaji url endpoint ya kuunganishia (ikiwa umefanikiwa kupata JWT token kutoka kwa pod soma here) na jina la cluster.

Katika kesi yangu, sikuipata taarifa hiyo kwenye CloudWatch logs, lakini niliikuta kwenye LaunchTemaplates userData na pia kwenye EC2 machines katika userData. Unaweza kuona taarifa hii katika userData kwa urahisi, kwa mfano katika mfano ufuatao (jina la cluster lilikuwa 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

From AWS to Kubernetes

The muumba wa EKS cluster atakuwa DAIMA na uwezo wa kuingia katika sehemu ya klasta ya kubernetes ya kundi system:masters (k8s admin). Wakati wa kuandika haya kuna hakuna njia ya moja kwa moja ya kupata nani aliyeunda klasta (unaweza kuangalia CloudTrail). Na hakuna njia ya kuondoa hiyo idhini.

Njia ya kuwapa ufikiaji kwa K8s kwa watumiaji au roles zaidi za AWS IAM ni kutumia configmap aws-auth.

warning

Hivyo basi, yeyote aliye na write access kwenye config map aws-auth ataweza compromise the whole cluster.

Kwa maelezo zaidi kuhusu jinsi ya grant extra privileges to IAM roles & users katika akaunti ile ile au tofauti na jinsi ya abuse hii: privesc check this page.

Angalia pia this awesome chapisho hili ili kujifunza jinsi authentication IAM -> Kubernetes inavyofanya kazi.

From Kubernetes to AWS

Inawezekana kuruhusu OpenID authentication for kubernetes service account ili kuwaruhusu kuchukua roles kwenye AWS. Jifunze jinsi hii inavyofanya kazi kwenye ukurasa huu.

GET Api Server Endpoint from a JWT Token

Kwa kutafsiri token ya JWT tunapata cluster id na pia region. image Ikijulikana kuwa muundo wa kawaida wa EKS url ni

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

Sikupata nyaraka yoyote inayofafanua vigezo vya 'two chars' na 'number'. Lakini baada ya kufanya majaribio nimeona hizi zikirudiwa mara kwa mara:

  • gr7
  • yl4

Vivyo hivyo, ni chars 3 tu; tunaweza bruteforce. Tumia script iliyo hapa chini kuzalisha orodha

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

Kisha kwa wfuzz

bash
wfuzz -Z -z file,out.txt --hw 0 https://<cluster-id>.FUZZ.<region>.eks.amazonaws.com

warning

Kumbuka kubadilisha & .

Kuepuka 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).

Hivyo wakati the attacker anazungumza na 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 Fidya?

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, the attacker could have ransomed the cluster.

tip

Kumbuka kwamba ikiwa cluster ilikuwa ikitumia EC2 VMs, inawezekana kupata Admin privileges kutoka kwa Node na kurejesha cluster.

Kwa kweli, If the cluster is using Fargate you could EC2 nodes or move everything to EC2 to the cluster and recover it accessing the tokens in the node.

tip

Jifunze na fanya mazoezi ya AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Jifunze na fanya mazoezi ya Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks