Abusing ECR & ECS

What is AWS ECR?

Amazon Elastic Container Registry (ECR) is a fully-managed Docker container registry that makes it easy to store, manage, and deploy Docker container images.

Key features of ECR:

  • Private container storage - ECR provides secure and scalable private storage for container images. Access is controlled through IAM.

  • Docker image management - Push, pull, and manage images from a central repository. Integrates with Docker CLI. Supports tags and versioning.

  • Access control - Role-based access to repository images. Set individual user or IAM role permissions.

  • Scalable - Built to scale seamlessly with your usage. No capacity planning required.

  • High availability - Replicated across multiple AZs for high availability and fault tolerance.

  • Life cycle policies - Configure image retention rules. Set image expiration, limit image count.

  • Integrations - Easily push/pull images to/from ECR from any Docker environment like EC2 containers, ECS, Kubernetes.

What is AWS ECS?

Amazon Elastic Container Service (ECS) is a scalable, high-performance container orchestration service that supports Docker containers. It simplifies running and scaling containerized applications on AWS.

Key features of ECS:

  • Container orchestration - Provisions and manages clusters of EC2 instances to run containers. Handles scheduling and coordination.

  • Integrated with ECR - Tight integration with Elastic Container Registry (ECR) for managing Docker images.

  • Highly scalable - Scales up to thousands of tasks/containers. Auto-scales capacity to meet demands.

  • Scheduling strategies - Supports binpack, spread and random scheduling across clusters. Places containers based on resource needs and availability.

  • Dynamic scaling - Scaling tasks up or down as demand changes for applications.

  • Security and IAM support - IAM roles and security policies manage user/resource permissions. Supports security groups and VPC for network security.

  • Cost effective - Pay only for the resources (like EC2 instances) you use to run tasks and containers.

Scenario - Image enumeration in ECR

Let us assume that we already have access credentials for AWS and upon enumerating our level of access, we find:

Let’s see if we can find out more information about the ECR repositories in the account:

aws ecr describe-repositories --profile <PROFILENAME>

So, we see a repository here named apptest. Let’s see whether it has any container images present.

aws ecr list-images --repository-name apptest --profile newcreds

So, we find out that there is indeed an image in the repository with the tag *latest.*

Let’s pull the image and see what we can find. According to the documentation here, we first need to authenticate to the registry using:

aws ecr get-login-password --region us-east-2 --profile newcreds| docker login --username AWS --password-stdin <ACCOUNT ID>.dkr.ecr.us-east-2.amazonaws.com

Now that the login has succeeded, we can pull the image and inspect it.

The command to do so is

docker pull <REPOSITORY URI>:<IMAGE TAG>

Based on the information above, the command becomes

docker pull 490106454974.dkr.ecr.us-east-2.amazonaws.com/apptest:latest

Let’s confirm using docker images

Now that we have the image locally on our system, we can inspect it.

docker history 490106454974.dkr.ecr.us-east-2.amazonaws.com/apptest

Now, this give us some details about the container image and the dockerfile commands used to build it.

To go even deeper and inspect the image contents layer-by-layer, we can use a tool called Dive, which can be found here:

Installation

export DIVE_VERSION=$(curl -sL "https://api.github.com/repos/wagoodman/dive/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
curl -OL https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.deb
sudo apt install ./dive_${DIVE_VERSION}_linux_amd64.deb

We can then inspect the image’s contents using

dive <IMAGE NAME>

In one of the layers, we can see that a credentials.txt file has been added into the image and in a later layer, it was removed. So, the file would not exist within the final image but it can be retrieved from one of the layers in the image.

So, we also need to note down the layer ID:

To extract a layer, we can use the docker-layer-extract tool

Prerequisites

Golang

Installation

git clone https://github.com/micahyoung/docker-layer-extract
cd docker-layer-extract
go install

We need to first save the image as a tarball:

docker save 490106454974.dkr.ecr.us-east-2.amazonaws.com/apptest:latest -o image.tar

We can then list all the layers from the tarball using the tool:

docker-layer-extract --imagefile image.tar ls

The layer IDs shown here are incorrect and do not match with the ones shown in Dive. For our purposes, we’ll be using the values from the Dive output. The LayerID here is actually the value of the Digest field from Dive.

Let’s now try to extract the layer we highlighted in the Dive output above. Now, let’s take the digest value from there and extract the corresponding layer using

docker-layer-extract --imagefile image.tar extract --layerid 9432805db4123bc06f14b73a9de6ed2c7023d43f5c715043acd3e1b2606c337e --layerfile layer.tar

Let’s try extracting the layer contents

 tar -xvf layer.tar

Bingo! It seems that we have obtained our credentials.txt file.

Let’s see what it holds:

Scenario - ECS

Enumerating the permissions we’ve obtained for the same set of credentials we used above, we see:

So, we see that we have permissions for ECS as well.

We’re going to use a tool called Pacu here. It can be found here:

Installation:

pip3 install pacu

We can then just start the tool with pacu

On first start, it asks us to name a session. Once we do that, we can begin using the tool. Now that the session is created, we need to configure our access keys using the set-keys option.

Let’s try enumerating ECS and see what we can find here. We first run some enumeration using

run ecs__enum

When it finishes running, it shows us a summary

We can now download a detailed version of the task definition using

run ecs__enum_task_def

Pacu has downloaded the task definition for us and we can view the same using

cat /root/.local/share/pacu/new/downloads/ecs_task_def_data/new.txt

We can now see the complete details of the task definition, including all the commands specified and any environment variables passed along to the container for the task. Here, we have found an API Key and a Database password from the task definition!

Last updated