Kabinet's GitBook
  • 🚩Kabinet CTF's Writeups
  • Page
  • 2025
    • Thuderdome
      • Emerge through the breach
      • Pulled from the sky
      • An absent defense
      • A new wave (web of deceit)
      • Crossing the great divide
      • Joining forces as one
      • Infiltrate (open the gate)
      • Jaeger
      • Victory
  • 2024
    • GreyCTF 2024
      • Markdown Parser
      • Fearless Concurrency
      • GreyCTF Survey
      • Baby Web
      • Beautiful Styles
      • All About Timing
      • Poly Playground
    • TetCTF 2024
      • Hello from API GW
      • Microservices
  • 2023
    • BSidesSF Cloud Village CTF
      • Tony Tony Tony
      • Plain Sight
      • A Suit of Armor Around The World
      • Sharing is Caring + Sequel
      • Photo Drive
    • DART CTF
      • Flag 1
      • Flag 2
      • Flag 3
      • Flag 4
      • Flag 5
      • Flag 6
      • Flag 7
      • Flag 8
      • Flag 9
      • Flag 10
    • EKS Cluster Games
    • Big IAM Challenge
  • 2022
    • Stack The Flag
      • Secret of Meow Olympurr
  • Authored
    • Cyber League 2025 Major 1
      • Perfect Storage
      • catalog commits
      • pawtainer hub
    • Lag and Crash 2023
      • Managed Secrets
      • Pickle Rick
      • Cloudy with a chance of meatball
    • NYP InfoSec December CTF 2022
      • Super Secure Technology Infrastructure
      • Self Introduction
      • Aww Cuter Cat
      • Obligatory Calc
      • BreadSecurity
  • NYP InfoSec Introduction to Pentesting Workshop
Powered by GitBook
On this page
  • Description
  • Solve
  • Enhanced Flow
  • Classic Flow

Was this helpful?

  1. Authored
  2. Cyber League 2025 Major 1

pawtainer hub

Description

The new intern is testing out a few services, help to audit it to ensure there are no misconfiguration.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Catastic Emporium</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
    <script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm" crossorigin="anonymous">
    </script>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>

<body>
    <nav class="navbar navbar-expand-sm bg-secondary" data-bs-theme="dark">

        <a class="navbar-brand" href="#"><img id="signedImg" src="#" alt="Logo" title="Logo" height="120" width="120" /></a>

        <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo03"
            aria-controls="navbarTogglerDemo03" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="navbarTogglerDemo03">
            <ul class="navbar-nav mr-auto mt-2 mt-lg-0">
                <li class="nav-item">
                    <a class="nav-link" href="#cats">Cats</a>
                </li>
            </ul>
        </div>
    </nav>
    <header class="jumbotron text-center">
        <h1 class="display-4">Meow Meow Wu</h1>
        <h2>Home of Cat Lovers</h2>
    </header>

    <main class="container">
        <section id="cats">
            <h2>All About Cats!</h2>
            <div class="row">
                <article class="col-sm">
                    <h3>Tabby</h3>
                    <figure>
                        <img class="img-thumbnail" src="images/british.jpg" alt="British Shorthair" />
                        <figcaption>British Shorthair</figcaption>
                    </figure>
                    <p>British Shorthairs make great family pets due to their loyal and devoted nature. They love to
                        snuggle and spend time with their humans, and though they can be a bit shy with new people, they
                        are quick to show their affection once they get to know you!
                    </p>
                </article>
                <article class="col-sm">
                    <h3>Ragdoll</h3>
                    <figure>
                        <img class="img-thumbnail" src="images/ragdoll.jpg" alt="Ragdoll" />
                        <figcaption>Ragdoll</figcaption>
                    </figure>
                    <p>Ragdolls are blue-eyed beauties known for their affectionate nature and tendency to go “limp like
                        a ragdoll” when carried. They make wonderful family pets and get along well with other cats and
                        dogs.
                    </p>
                </article>

                <article class="col-sm">
                    <h3>Sphynx</h3>
                    <figure>
                        <img class="img-thumbnail" src="images/sphynx.jpg" alt="sphynx" />
                        <figcaption>Sphynx</figcaption>
                    </figure>
                    <p>Hairless but fearless, the Sphynx cat turns heads everywhere it goes! This cat demands its
                        well-deserved attention, loves entertaining its family, and treasures meeting new humans. The
                        Sphynx have an undeniable power to enchant anyone with their humor, loving nature, and exotic
                        appearance.
                    </p>
                </article>
            </div>
        </section>
    </main>
    <footer class="container">
        <p>Copyright &copy; 2023 Pawtainer Hub Pte. Ltd.</p>
    </footer>

    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.719.0.min.js"></script>
    <script>
        AWS.config.region = 'ap-southeast-1';
        AWS.config.credentials = new AWS.CognitoIdentityCredentials({
            IdentityPoolId: "ap-southeast-1:a96dc13a-9dc3-48ed-867a-ff80e94be21f"
        });
        // Set the region
        AWS.config.update({
            region: 'ap-southeast-1'
        });

        $(document).ready(function () {
            var s3 = new AWS.S3();
            params = {
                Bucket: 'pawtainer-hub-patched',
                Key: 'logo.jpg',
                Expires: 60 * 60
            }

            signedUrl = s3.getSignedUrl('getObject', params, function (err, url) {
                $('#signedImg').attr('src', url);
            });
        });
    </script>
</body>

</html>

Solve

Enhanced Flow

Looking at the page source, we instantly noticed the script utilize hard coded AWS Cognito Identity Pool as well as s3 bucket name.

The jaavscript uses the AWS SDK to interact with the S3 Bucket. It uses AWS Cognito to retrieve an assumed unauthenticated role. We are able to either use the Javascript console or the aws cli to retrieve the credentials.

aws cognito-identity get-id --identity-pool-id ap-southeast-1:a96dc13a-9dc3-48ed-867a-ff80e94be21f
aws cognito-identity get-credentials-for-identity --identity-id ap-southeast-1:96a99d70-cce1-c9d2-e7ca-ea7656fc2830

With the credentials, we are able to set up an aws profile (I call it enhanced)with aws cli to enumerate our permission.

Running aws sts get-caller-identityas a sanity check, we noticed that the assumed role is called cognito_unauthenticated. However, attempts in further enumeration of our permission were met with AccessDenied by session policy.

Using AWS Cognito Enhanced flow, there are built-in security controls that restrict certain administrative operations.

  • When credentials are obtained through a Cognito Identity Pool, AWS applies an implicit session policy.

  • This session policy overrides or restricts certain permissions, even if they're explicitly allowed in the role policy

Looking at the AWS documentation

We can see that there is an inline session policy for guest users using enhanced-flow.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:*",
                "logs:*",
                "dynamodb:*",
                "kinesis:*",
                "mobileanalytics:*",
                "s3:*",
                "ses:*",
                "sns:*",
                "sqs:*",
                "lambda:*",
                "machinelearning:*",
                "execute-api:*",
                "iot:*",
                "gamelift:*",
                "scs:*",
                "cognito-identity:*",
                "cognito-idp:*",
                "lex:*",
                "polly:*",
                "comprehend:*",
                "translate:*",
                "transcribe:*",
                "rekognition:*",
                "mobiletargeting:*",
                "firehose:*",
                "appsync:*",
                "personalize:*",
                "sagemaker:InvokeEndpoint",
                "cognito-sync:*",
                "sumerian:View*",
                "codewhisperer:*",
                "textract:DetectDocumentText",
                "textract:AnalyzeDocument",
                "sdb:*"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

Looking at the Session Policy, it explains that why S3 works, but not IAM. To attempt to bypass it, we can use the basic/classic authentication flow.

Referring to another documentation by aws.

We will need to use the three order of operation, GetId, GetOpenIdToken and lastly AssumeRoleWithWebIdentity to get the role.

There is a GitHub issues on aws sdk that probably explain this better than me so ill suggest you to read it instead.

Classic Flow

aws cognito-identity get-open-id-token --identity-id ap-southeast-1:96a99d70-cce1-c9d2-e7ca-ea7656fc2830

The role arn can be manually created as we have the account id as well as the role-name

aws sts assume-role-with-web-identity --role-arn arn:aws:iam::647090761932:role/cognito_unauthenticated --role-session-name asd --web-identity-token <jwt token>

We the access key, secrey key and session token, we are able to configure another profile for the classic flow credential.

Running get-caller-identityagain as a sanity check, we have assumed the role succesfully, with the sesion name test

Now, we can attempt to enumerate IAM again to see if we managed to bypass the session policy.

aws iam get-role --role-name cognito_unauthenticated --profile classic
aws iam list-role-policies --role-name cognito_unauthenticated --profile classic
aws iam get-role-policy --role-name cognito_unauthenticated --policy-name unauthenticated_policy --profile classic

Performing manual enumeration, we managed to retrieve the IAM policy for the role cognito_unauthenticated

Looking at the IAM Policy, we can see that the user has the iam:Get* and iam:List* permission, thus allowing us to enumerate the IAM.

Interestingly, the user also has ECR permission.

AWS ECR is the Elastic Container Registry, which is somewhat similar to a docker registry, but hosted on AWS. The "Resource": "*" in the ECR section grants access to all resources. This is a security risk as it provides the unauthenticated role access to all ECR repositories within the AWS account

aws ecr describe-repositories --profile classic

Running describe profile to tists all Amazon Elastic Container Registry (ECR) repositories in the AWS account associated with the classic profile.

Next, runing describe image to lists details about the container images stored in the specified ECR repository.

aws ecr describe-images --repository-name pawtainerhub_ecr_patched --profile classic

There is a image with the image tag 7xxxx. I authenticates Docker with the specified ECR registry, allowing me to pull images

aws ecr get-login-password --region ap-southeast-1 --profile classic | docker login --username AWS --password-stdin 647090761932.dkr.ecr.ap-southeast-1.amazonaws.com
docker pull 647090761932.dkr.ecr.ap-southeast-1.amazonaws.com/pawtainerhub_ecr_patched:74d031b9fe7c

Lastly, Ill downloads a container image from the specified ECR repository to your local Docker environment.

Running the docker container, we retrieved the flag.

Previouscatalog commitsNextLag and Crash 2023

Last updated 4 months ago

Was this helpful?

IAM roles - Amazon CognitoAmazon Cognito
Logo
Identity pools authentication flow - Amazon CognitoAmazon Cognito
Logo
Cognito unauthenticated user not authorized to perform: ssm:GetParameter because no session policy allows · Issue #4303 · aws/aws-sdk-jsGitHub
Fully Managed Container Registry – Amazon Elastic Container Registry – Amazon Web ServicesAmazon Web Services, Inc.
Logo
Logo
Note that it is denied by session policy and not other policy! This is important
Syntax: arn:aws:iam::account:role/role-name-with-path Resulting Role ARN: arn:aws:iam::647090761932:role/cognito_unauthenticated
Note the ARN with role session name as test, being different from the previous get caller identity call