Perimeter Leak
Challenge Description

Table of Contents
Solution Overview
This challenge demonstrates a multi-stage cloud security exploit chain involving:
Spring Boot Actuator Exposure - Discovering misconfigured management endpoints
SSRF Vulnerability - Exploiting a proxy endpoint to access internal resources
IMDS Access - Bypassing IMDSv2 protections to retrieve EC2 instance credentials
S3 Enumeration - Using temporary IAM credentials to access cloud storage
VPCE Bypass - Leveraging presigned URLs to circumvent VPC endpoint restrictions
Key Vulnerability: A misconfigured Spring Boot application with an exposed proxy endpoint allows Server-Side Request Forgery (SSRF), enabling access to the AWS EC2 Instance Metadata Service (IMDS), retrieval of temporary IAM credentials, and bypass of S3 bucket policies using presigned URLs.
Enumerating Spring Boot Application
Initial reconnaissance reveals the target application:

Curling the index page suggests this is a proxy server:
However, initial path enumeration doesn't reveal any accessible endpoints.
Discovering Spring Boot Actuator Endpoints

Spring Boot applications often expose management endpoints through Spring Boot Actuator, which provides built-in endpoints for monitoring and managing applications. Common Actuator endpoints include:
/actuator- Lists all available actuator endpoints/actuator/env- Displays environment properties/actuator/health- Shows application health status/actuator/mappings- Shows all request mappings
Let's check if the /actuator endpoint is exposed:
Success! The actuator endpoint is accessible and reveals several management endpoints:

Note: Exposing Spring Boot Actuator endpoints without proper authentication is a common misconfiguration that can leak sensitive information about the application's configuration, environment variables, and internal structure.
Analyzing Endpoint Mappings
Examining the /actuator/mappings endpoint reveals the application's route configuration. Filtering out the noise, we identify two interesting endpoints:
/proxy- Accepts aurlparameter (potential SSRF vector)Standard actuator endpoints

Testing the /proxy endpoint:
Initial access attempt returns a 401 Unauthorized error:

Attempting to proxy http://example.com reveals a verbose error message with valuable information:

Testing with example.com:
Response:
Key findings from the error message:
The proxy accepts a
urlparameterThe proxy passes along headers and different request types (HTTP methods)
The proxy only allows URLs containing:
IP addresses (e.g.,
169.254.169.254)Hostnames containing
amazonaws.com
This restriction is intended to limit the proxy to AWS services only
This configuration creates a Server-Side Request Forgery (SSRF) vulnerability that can be exploited to access internal AWS metadata services!
Exploiting SSRF to Access IMDS
Understanding IMDSv2
The AWS Instance Metadata Service (IMDS) is accessible at http://169.254.169.254 from within EC2 instances. It provides information about the instance, including:
Instance ID and type
Security credentials (IAM role credentials)
Network configuration
User data
AWS introduced IMDSv2 (Instance Metadata Service Version 2) as a defense-in-depth measure against SSRF attacks. IMDSv2 requires a session token obtained via a PUT request, which traditional SSRF attacks cannot easily perform.
Initial IMDS access attempt:
Attempting to access IMDS directly returns a 401 Unauthorized error, confirming IMDSv2 is enabled:

Bypassing IMDSv2 Protection
Remember from the error message: "This proxy passes along headers and different request types"
This is critical! Since the proxy forwards:
HTTP headers
Different HTTP methods (GET, PUT, etc.)
We can exploit this to perform the IMDSv2 token request flow through the proxy!
Step 1: Request an IMDSv2 session token using PUT
Parameters explained:
-X PUT- Uses HTTP PUT method (required for IMDSv2 token request)X-aws-ec2-metadata-token-ttl-seconds: 21600- Requests a token valid for 6 hours (21600 seconds)Target:
http://169.254.169.254/latest/api/token- IMDSv2 token endpoint
Response:

Success! We received a valid IMDSv2 session token.
Step 2: Use the token to access IMDS metadata
Response:

Excellent! The metadata endpoint is now accessible. From the output, we can see an IAM instance profile is attached to this EC2 instance, which means we can retrieve temporary IAM credentials.
Retrieving IAM Credentials
IAM instance profiles provide temporary security credentials to EC2 instances. Let's retrieve them:
Step 1: List available IAM roles
This reveals the IAM role name: challenge01-5592368
Step 2: Retrieve the IAM security credentials
Retrieved credentials:

Credential details:
Perfect! We now have temporary IAM credentials consisting of:
AccessKeyId - AWS access key
SecretAccessKey - AWS secret key
Token - Session token (required for temporary credentials)
Expiration - When the credentials expire (valid for ~6 hours)
Utilizing Temporary Credentials
Now that we have valid AWS credentials, let's configure the AWS CLI to use them.
Configuring AWS CLI

Enumerating S3 Buckets
Since the challenge description mentions an S3 bucket, let's attempt to enumerate S3 resources:

The aws s3 ls command fails with an access denied error. The IAM role doesn't have permission to list all S3 buckets.
Alternative approach: Recall that earlier, when enumerating /actuator/env, we discovered environment variables containing sensitive configuration data. Let's check if there's an S3 bucket name in the environment:

Excellent! The environment variables reveal the S3 bucket name: challenge01-470f711
Note: Exposing environment variables through
/actuator/envis dangerous as they often contain sensitive information like database credentials, API keys, and resource names.
Accessing the S3 Bucket
With the bucket name in hand, let's list its contents:

Success! We can see two files:
hello.txt- A test fileprivate/flag.txt- The flag (in aprivate/directory)
Attempting to download all files:

Interesting findings:
hello.txtdownloaded successfullyprivate/flag.txtfailed with Access Denied
There's an explicit deny policy preventing access to files in the private/ directory. Let's investigate the bucket policy to understand this restriction.
Analyzing S3 Bucket Policy
Let's retrieve and examine the bucket policy:
Bucket Policy:
Policy Analysis:
Effect:
Deny- This is an explicit deny (takes precedence over any allow statements)Principal:
*- Applies to all principals (users, roles, services)Action:
s3:GetObject- Blocks downloading objectsResource:
arn:aws:s3:::challenge01-470f711/private/*- Only affects files in the/private/directoryCondition:
StringNotEqualswithaws:SourceVpce- Only allows access from a specific VPC endpoint
Understanding VPC Endpoints (VPCE):
A VPC Endpoint (VPCE) allows resources within a VPC to connect to AWS services (like S3) privately, without traversing the public internet. The condition aws:SourceVpce: vpce-0dfd8b6aa1642a057 means:
Requests from VPC Endpoint
vpce-0dfd8b6aa1642a057→ AllowedRequests from anywhere else (including our web s) → Denied
Since the EC2 instance is in the VPC and uses this VPC endpoint, requests made through the proxy will satisfy this condition!
Bypassing VPCE Restrictions with Presigned URLs
The Challenge:
We have valid IAM credentials
We can access the proxy (which uses the VPC endpoint)
We need to retrieve
private/flag.txtthrough the VPC endpoint
The Solution: AWS S3 Presigned URLs
A presigned URL is a temporary URL that grants access to a specific S3 object. It includes:
Authentication information (embedded in query parameters)
Expiration time
Specific permissions (e.g., GET access)
When someone uses a presigned URL, they inherit the permissions of the IAM principal who generated it!
Step 1: Generate a presigned URL

Generated presigned URL:
Step 2: URL encode the presigned URL
Since we're passing the presigned URL as a query parameter to the proxy, we need to URL encode it. We can use CyberChef or any URL encoder:

Step 3: Access the flag through the proxy
Success!

Summary:
The presigned URL contains our IAM credentials (embedded in the URL parameters)
The request goes through the proxy server
The proxy uses the VPC endpoint (
vpce-0dfd8b6aa1642a057)The S3 bucket policy allows requests from this VPC endpoint
We successfully retrieve the flag!
Flag: WIZ_CTF_Presigned_Urls_Are_Everywhere
Last updated