How I (accidentally) hacked ImaginaryCTF infra

Posted on Jul 23, 2023

For this years ImaginaryCTF I played with my friends les amateurs. We ended up placing 12th out of 880 teams competing! There were lots of super interesting challenges and I look forward to competing next year.


Just for fun, I decided to look at the challenge misc/obscured

When we initially connect to the challenge, it has us complete a Proof-of-Work which after completing gives us a box to SSH into. Once I realized I have no clue what I’m doing, I decided to run a powerful Linux enumeration script (very skid), LinPEAS (github). This tool does a variety of checks, specifically looking for possible privilege escalation vulnerabilities. Since the box had access to the internet, we could easily run a command to download and run the LinPEAS script.

curl -L | sh

Running this script revealed some interesting information. Obviously it did reveal some information about the intended solution (polkit) but what really caught my eye the information it had gathered about the Google Cloud environment it was running in. It was able to find data such as the project ID, project SSH keys, and lots more. The juiciest part out of all of that was access tokens for the GCP service accounts.

GCP Enumeration

At first I was unsure if we could use the access tokens for anything. However, after a bit of research I realized we can use the access tokens to make API requests to get more information about the GCP project. And looking at the scopes we had access to, I decided to look at the GCP storage to see if this is something worth reporting.

Using the GCP Storage JSON API documentation as a reference, I crafted the following request to list the available buckets.

curl \
  '[REDACTED]' \
  --header 'Authorization: Bearer ya29.c.[REDACTED]' \
  --header 'Accept: application/json' \

Running this command revealed two buckets. To list the contents of the buckets, we could make the following cURL request.

curl \
  '[BUCKET ID]/o' \
  --header 'Authorization: Bearer ya29.c.[REDACTED]' \
  --header 'Accept: application/json' \

One of them would end up being empty, however the other bucket would contain some pretty sensitive information. Each one of the object IDs looked something like this

[REDACTED URL]/containers/images/sha256:[sha256 hash]/[some num]

Noticing this I assumed this bucket contained all of the docker containers used for ImaginaryCTF. To double check, I tried downloading one of the files, and it just so happened that the file we downloaded did contain a flag.


Once we found this, I immediately messaged one of the organizers telling him what I found and gave all the information he asked for. We ended up not using the flag we found (since you shouldn’t do that) and the challenge went down for maintenance to get fixed.

Thank you to Eth007 for handling the situation very well and not DQ’ing our team for this! Once again, this was an amazing CTF and I have high hopes that next year this problem won’t happen again!

Funny Screenshots