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

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2ForufkA6Jk0Htq4fKMq29%2Fimage.png?alt=media&#x26;token=b2e2e1b2-850f-4166-8fcb-ce8b1b5c4f0b" alt=""><figcaption></figcaption></figure>

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

```
aws ecr describe-repositories --profile <PROFILENAME>
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FamrRBGHH1emorWs3cjjo%2Fimage.png?alt=media&#x26;token=67d21705-5f1a-4556-a3c1-57cdad84b435" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FVYkBFglW0zYeQbKIx0Mx%2Fimage.png?alt=media&#x26;token=62059aca-44a1-49fb-adfe-bcd4c160c4e6" alt=""><figcaption></figcaption></figure>

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](https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-pull-ecr-image.html), 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
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FXct5atVgtKBd8KdpQ68r%2Fimage.png?alt=media&#x26;token=707acd2f-c82f-4c84-9829-8de876b68bfc" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2F13IV3ErXjZOHpENwfgUS%2Fimage.png?alt=media&#x26;token=6770f9e1-66bd-48ac-a8ae-ce893d0748c1" alt=""><figcaption></figcaption></figure>

Let’s confirm using docker images

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FoaTycfSpanCyVaCryAey%2Fimage.png?alt=media&#x26;token=4ada88b6-c42b-4676-a12d-183b5a5ded02" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FNRQHpTlvJEUYnNvMK3li%2Fimage.png?alt=media&#x26;token=a207f3eb-6339-4cfa-ad9b-78169cace203" alt=""><figcaption></figcaption></figure>

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:

{% embed url="<https://github.com/wagoodman/dive>" %}

#### 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>
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FScvUOWBlcWVuGOEPljwD%2Fimage.png?alt=media&#x26;token=c88e5f70-27bd-4824-ad12-a3905ea8a16e" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FFCnflDtMHt0Dp1l7I3bI%2Fimage.png?alt=media&#x26;token=1d4fb531-a3a0-4a2a-a926-0f581daadba4" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FGD2e5uGdFm9BVo5CkSON%2Fimage.png?alt=media&#x26;token=984663cf-5be1-4321-bc2f-3d679abc3028" alt=""><figcaption></figcaption></figure>

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

{% embed url="<https://github.com/micahyoung/docker-layer-extract>" %}

**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
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FdZlYZWdIzn9xkeLgigbU%2Fimage.png?alt=media&#x26;token=721733ca-7947-4796-8411-20227434ebd5" alt=""><figcaption></figcaption></figure>

> 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
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FbDRdmauPJkfYJfRZA3Nh%2Fimage.png?alt=media&#x26;token=9be1be8d-1a63-4f49-b1a0-ebb7ea7cf7cf" alt=""><figcaption></figcaption></figure>

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

Let’s see what it holds:

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FS61fDo8lBXw4lBjgPgDJ%2Fimage.png?alt=media&#x26;token=78d79bea-c01e-421e-ba26-3a0f4118f406" alt=""><figcaption></figcaption></figure>

## **Scenario - ECS**

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

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FNDPrUooNhfqKXXQfIjaE%2Fimage.png?alt=media&#x26;token=12bd3a6c-e0a1-4b5c-8052-f78f1137b497" alt=""><figcaption></figcaption></figure>

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:

{% embed url="<https://github.com/RhinoSecurityLabs/pacu>" %}

#### Installation:

```
pip3 install pacu
```

We can then just start the tool with pacu

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FcFROCluHoCFUQ6bd01oT%2Fimage.png?alt=media&#x26;token=b10a9247-7591-459e-b4aa-504836e22436" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FvLYXNqBrdhesPtcVal5E%2Fimage.png?alt=media&#x26;token=f914b5f2-02bd-402a-b65f-eb34b0f09d3b" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2F72oNhMd7OuoGhAVYezuX%2Fimage.png?alt=media&#x26;token=dfa6931f-7aa9-475e-a4a7-a1eb80ba3672" alt=""><figcaption></figcaption></figure>

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

```
run ecs__enum_task_def
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FbfzrzrHZDsiZ8aDxT3Jl%2Fimage.png?alt=media&#x26;token=940b5ac8-b2f1-4911-960c-8895388c565e" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2FHtUauRFOcxYYJVouXRyw%2Fimage.png?alt=media&#x26;token=a125563b-8982-410a-8e01-bf1cac6a7b22" alt=""><figcaption></figcaption></figure>

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!
