AWS - EKS Post Exploitation

Reading time: 7 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें

EKS

अधिक जानकारी के लिए देखें

AWS - EKS Enum

Enumerate the cluster from the AWS Console

यदि आपके पास अनुमति eks:AccessKubernetesApi है, तो आप AWS EKS console के माध्यम से Kubernetes objects देख सकते हैं (Learn more).

Connect to AWS Kubernetes Cluster

  • आसान तरीका:
bash
# Generate kubeconfig
aws eks update-kubeconfig --name aws-eks-dev
  • इतना आसान तरीका नहीं:

यदि आप get a token के साथ aws eks get-token --name <cluster_name> प्राप्त कर सकते हैं पर आपके पास cluster info (describeCluster) पाने की permissions नहीं हैं, तो आप अपना खुद का ~/.kube/config तैयार कर सकते हैं। हालांकि, token होने के बावजूद, आपको अभी भी कनेक्ट करने के लिए url endpoint to connect to चाहिए (यदि आपने pod से JWT token प्राप्त किया है तो here पढ़ें) और name of the cluster भी चाहिए।

मेरे केस में, मैंने जानकारी CloudWatch logs में नहीं पाई, लेकिन मैंने इसे LaunchTemaplates userData में पाया और EC2 machines के userData में भी। आप यह जानकारी userData में आसानी से देख सकते हैं, उदाहरण के लिए अगले उदाहरण में (the 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

From AWS to Kubernetes

The निर्माता of the EKS cluster हमेशा kubernetes क्लस्टर के group system:masters (k8s admin) हिस्से में पहुँचने में सक्षम होगा। इस लेखन के समय यह पता लगाने का कोई प्रत्यक्ष तरीका नहीं है कि किसने क्लस्टर बनाया था (आप CloudTrail चेक कर सकते हैं)। और उस privilege को हटाने का कोई तरीका नहीं है।

The way to grant K8s पर अधिक AWS IAM users या roles को access देने का तरीका is using the configmap aws-auth.

warning

इसलिए, जिनके पास config map aws-auth पर write access है वे पूरे क्लस्टर को compromise कर सकेंगे।

For more information about how to grant extra privileges to IAM roles & users in the same or different account and how to abuse this to privesc check this page.

Check also this awesome post to learn how the authentication IAM -> Kubernetes work.

Kubernetes से AWS

यह संभव है कि kubernetes service account के लिए OpenID authentication की अनुमति दी जाए ताकि वे AWS में roles assume कर सकें। Learn how this work in this page.

GET Api Server Endpoint from a JWT Token

JWT token को decode करने पर हमें cluster id & साथ ही region मिलते हैं। image यह जानते हुए कि EKS url का standard format है

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

ऐसी कोई दस्तावेज़ नहीं मिली जो 'two chars' और 'number' के मानदंडों की व्याख्या करे। पर मेरी ओर से किए गए कुछ परीक्षणों में ये बार-बार दिखे:

  • gr7
  • yl4

वैसे ये सिर्फ 3 chars हैं — इन्हें हम bruteforce कर सकते हैं। सूची जनरेट करने के लिए नीचे दिए गए script का उपयोग करें

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

फिर wfuzz के साथ

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

warning

इन्हें बदलना याद रखें & .

CloudTrail को बायपास करें

यदि कोई attacker AWS के credentials प्राप्त कर लेता है जिसके पास permission over an EKS है। यदि attacker अपना खुद का kubeconfig (जैसा पहले बताया गया, update-kubeconfig को कॉल किए बिना) कॉन्फ़िगर करता है, तो get-token Cloudtrail में logs जनरेट नहीं करता क्योंकि यह AWS API के साथ इंटरैक्ट नहीं करता (यह सिर्फ token लोकली बनाता है)।

तो जब attacker EKS cluster के साथ संचार करता है, cloudtrail उस चोरी किए गए user द्वारा किए गए access से संबंधित कुछ भी लॉग नहीं करेगा

ध्यान दें कि EKS cluster might have logs enabled जो इस access को log करेंगे (हालाँकि, by default वे disabled होते हैं)।

EKS Ransom?

Default रूप से जो user or role that created एक cluster है उसे cluster पर ALWAYS going to have admin privileges मिलेंगे। और वही AWS का Kubernetes cluster पर एकमात्र "secure" access होगा।

तो, यदि एक attacker compromises a cluster using fargate और removes all the other admins और deletes the AWS user/role that created the Cluster, the attacker could have ransomed the cluster

tip

ध्यान दें कि यदि cluster EC2 VMs का उपयोग कर रहा था, तो संभव है कि Node से Admin privileges प्राप्त करके cluster को recover किया जा सके।

वास्तव में, यदि cluster Fargate का उपयोग कर रहा है आप EC2 nodes कर सकते हैं या सब कुछ EC2 पर मूव करके cluster को recover कर सकते हैं और node में मौजूद tokens को एक्सेस करके उसे वापस ले सकते हैं।

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE) Azure हैकिंग सीखें और अभ्यास करें: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks का समर्थन करें