Solving Flaws2.Cloud: A Step-by-Step Guide

flaws2.cloud challenges are hands-on exercises designed to help users identify and exploit security misconfigurations in AWS environments. Participants learn to understand common misconfigurations and weaknesses in cloud infrastructure, improving their skills in securing cloud services. These challenges are valuable for beginners and experienced professionals seeking practical, real-world experience in cloud security.

Flaws2 offers two paths this time: Attacker and Defender! This blog post will discuss the Attacker’s side to learn about serverless (Lambda) and container (ECS Fargate) misconfigurations.

In case you haven’t checked out my flaws.cloud writeup: I highly recommend doing it now.

Level 1

Solution: Here, it asks for a 100-digit number. If you give the wrong number, it prints “Incorrect. Try again,” but for non-integer input, it pops an alert saying, “Code must be a number.”

Let’s look at the HTML logic in the page

<form name="myForm" action="https://2rfismmoo8.execute-api.us-east-1.amazonaws.com/default/level1" onsubmit="return validateForm()">
    Code: <input type="text" name="code" value="1234">
    <br><br>
    <input type="submit" value="Submit">
</form>

The form submits the input to the URL https://2rfismmoo8.execute-api.us-east-1.amazonaws.com/default/level1.

NOTE: If you have already checked Level 6 in the flaws.cloud writeup, you can quickly identify that this is an API Gateway URL, as the URL follows the pattern “https://{api-id}.execute-api.{region}.amazonaws.com/{stage}”. In this URL, “2rfismmoo8” refers to the API Gateway ID, “default” is the stage of the API deployment, and “level1 ” is the specific resource we are accessing.

Let’s intercept the traffic in Burp Suite. The HTML page sent the form data to the server using the GET method. The request contains the input given to the form in the query “?code=1234”.

When I pass on a non-integer input, the server sends an “HTTP/2 500 Internal Server Error,” indicating a problem on the server side while processing your request. However, it dumps many environment variables containing information like AWS access keys, session tokens, etc.

Save these access keys and the session token in the ~/.aws/credentials to configure AWS CLI for a named profile. Then, try listing the files in bucket level1.flaws2.cloud.

aws --profile level1-flaws2 s3 ls s3://level1.flaws2.cloud

It contains a secret file; try accessing it in the browser.

secret-ppxVFdwV4DDtZm8vbQRvhxL8mE6wxNco.html contains the URL to Level2.

Level 2

Solution: Opening the container URL shows a login screen asking for a username and password.

The hint in the description tells us to search the ECR repository named level2. Let’s try listing all ECR repositories in the account. The credentials from level1-flaws2 don’t have permission for the action ecr:DescribeRespositories.

aws --profile level1-flaws2 --region us-east-1 ecr describe-repositories

So, let’s just get all the images’ metadata in the repository named “level2”.

aws --profile level1-flaws2 --region us-east-1 ecr describe-images --repository-name level2

The level2 repository above has an image tagged as latest, with the image digest sha256:513e7d8a5fb9135a61159fbfbc385a4beb5ccbd84e5755d76ce923e040f9607e. The first docker client needs to be authenticated with Amazon ECR to pull the image using docker pull. Use the aws ecr get-login-password command to get the authentication token and pass it to the docker login command using the username AWS.

aws ecr get-login-password --region us-east-1 --profile level1-flaws2 | sudo docker login --username AWS --password-stdin 653711331788.dkr.ecr.us-east-1.amazonaws.com

Now, pull the image using the command:

docker pull 653711331788.dkr.ecr.us-east-1.amazonaws.com/level2:latest

Run the docker container using the following command:

docker run -it 653711331788.dkr.ecr.us-east-1.amazonaws.com/level2 /bin/bash

The container contains the file that leads to level3.

Level 3

Solution: This simple proxy allows us to use the container’s webserver to make HTTP requests to an arbitrary domain, which can lead to unauthorized access to internal resources.

Just like EC2 has a metadata endpoint at the IP 169.254.169.254, ECS containers have a task metadata endpoint at the IP 169.254.170.2.

If a container running on ECS needs IAM credentials during execution, AWS recommends using a task IAM Role. When the container is configured with the role, AWS automatically injects the environment variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI to help running applications fetch temporary credentials during execution.

The value of the above environment variable can be appended to the task metadata endpoint (169.254.170.2) to fetch temporary credentials.

We can obtain the value of AWS_CONTAINER_CREDENTIALS_RELATIVE_URI from the file /proc/self/environ (this path contains all the environment variables available within a Linux system).

curl --output - http://container.target.flaws2.cloud/proxy/proc/self/environ | tr '\0' '\n'

Now, try to access the 169.254.170.2/$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI to get the credentials.

curl --output - http://container.target.flaws2.cloud/proxy/http://169.254.170.2/v2/credentials/cb3fc49d-d169-4964-bb43-f6a5d33034bd | jq

Save these access keys and the session token in the ~/.aws/credentials to configure AWS CLI for a profile name, such as level3-flaws2. Then, try to list the buckets.

aws --profile level3-flaws2 s3 ls

The output contains the bucket name, the end of the flaws2.cloud.

Reply

or to participate.