June 2025 - Perimeter Leak
A walkthrough of the WIZ Ultimate Cloud Security Championship for June 2025
CTF Source: WIZ Ultimate Cloud Security Championship
Challenge Credit: Scott Piper
Overview
In this walkthrough, I'll demonstrate how to successfully complete the June 2025 WIZ challenge.
Walkthrough

Enumerating the Application
Upon starting this challenge we're provided with the following,
You've discovered a Spring Boot Actuator application running on AWS: curl https://ctf:[email protected] {"status":"UP"}
Truthfully, I know that Spring Boot is related to Java but otherwise have no clue how to approach this.
A quick Google search for Spring Boot Actuator takes me to the official documentation.
After a bit of research I've learned that Spring Boot is a Java-based framework enabling developers to quickly spin up production-ready applications. And I've also learned about its Actuator endpoints.
In fact, we can return that status message shared earlier by querying the endpoint like so,
There's another interesting endpoint which can expose sensitive information, env
The output is quite large so I'll just show a snippet.
Yea.. these endpoints shouldn't be publicly exposed 😬
Alright, so it's looking like this application is running on an EC2 and we learn of an S3 bucket name!
Based on the challenge description, it sounds like the flag will be in S3 so let's take a look.
Checking S3
Let's first check what region the bucket is in.
Now we'll attempt to view the bucket "anonymously" i.e., --no-sign-request
No dice. Maybe the bucket allows for any AWS identity to view it though? I'll try again using AWS credentials from my personal AWS account.
Also doesn't work. I try a few other commands like list-object-versions and get-bucket-policy but none work.
Let's go back to enumerating the spring boot app.
Finding a Custom Proxy Endpoint
The actuator/mappings endpoint returns information about the different endpoints available to the application. Let's enumerate it and pass the data to jq to easily parse.
Hmm.. that proxy endpoint isn't standard. Let's take a look!
Let's check if we can query that.
Since we know this app is running on an EC2, let's check the Instance Metadata Service (IMDS).
Okay, so this likely means it's running IMDSv2 which requires passing a token. Let's try,
We're in!
Alright, let's check if the EC2 has an Instance Profile (IAM Role attached).
Let's grab its credentials.
Nice! We're in.
Something to note here is if GuardDuty is enabled in the target environment, we'll have just triggered an alert since we used the EC2's credentials outside of itself. We're not concerned for the purposes of this challenge though.
Enumerating S3 (Successfully this time!)
So here's what we know so far:
The spring boot application makes reference to an S3 bucket
The application runs on EC2
The EC2 has an IAM Role attached
We can guess that the application leverages the IAM Role to access the S3 bucket. Let's try!
We're making progress!
The hello.txt file isn't interesting and we can't access the flag..
So it seems we have permissions to view the files but not access the flag file.
Can we check the bucket policy?
Ah here we go! The flag.txt file (or any files within the private/ prefix actually) can only be accessed from this VPC Endpoint. We'll assume it's an S3 VPC Endpoint or else the policy wouldn't make sense 😄
Accessing the flag!
So, here's the thing, we don't know if that VPC Endpoint is attached to the same VPC that our EC2 instance is in so we'll just assume it is.
How can we access the S3 bucket from this VPC Endpoint?
We need to access it from the EC2 but all we can do is use curl via that proxy we found.
One thing we can try to do is generate an S3 Presigned URL. This would provide us with a URL that we could then curl through the proxy. Since the request would come from the EC2 instance, it should use that S3 VPC Endpoint we discovered in the S3 bucket policy.
Let's see if we can generate a presigned URL.
Nice!
And now we'll try to query it from the proxy.
Hmm... probably an encoding issue.
Let's try again and this time we'll URL-encode the payload using jq and save the output to a variable.
We did it! We found the flag.
Wrap Up
In this challenge, we were given access to a Spring Boot application running on an AWS EC2 instance. The application exposed sensitive Actuator endpoints, which revealed internal configuration details, including the name of an S3 bucket. Additionally, a custom /proxy endpoint was vulnerable to Server-Side Request Forgery (SSRF), allowing us to query the EC2 instance metadata service (IMDS). Through this, we obtained temporary IAM role credentials assigned to the EC2 instance. Using these credentials, we were able to generate a pre-signed S3 URL and retrieve the flag stored in the otherwise restricted bucket.
Last updated
Was this helpful?