CVE-2019-5736, runC and the Trickle down effect of Bad Advice

CVE-2019-5736, runC and the Trickle down effect of Bad Advice

"Docker Containers are supposed to run as root", he said, authoritatively on a call. I started to doubt myself. "How can anything running as root, be a good thing?" I asked myself. But the gent giving us the piece of advice (nay, justification) was a senior security pro with a good deal of experience under his belt. He was working on contract for a client of ours. This was 2015. They were an early adopter of containers and were gung-ho about it. They had hired us to pentest their apps. My team and I were in a call scoping the apps that we were engaged to test. I wasn't too aware of this "docker" thing. I mean, I had heard of it. Used it a bit. But that was it. This guy sounded confident. And since I wasn't so sure of this myself. I decided to shut up. Of course, not too further down the road, I realized that this was a bad security call and this expert on security was talking out of his </bleep>

Even though the first release of Docker was around 5 years ago. The rate of adoption of container technology has been asymmetrical with the rate of dissemination of security knowledge around it.

First, we heard that it was ok to run containers as root, much like our eloquent security pro from one paragraph ago. So some of us thought containers were "like VMs". This of course, has created a massive wave of containers and images being built and deployed with uid0 privileges. As I say this I find that many of my own container images have been built with root privs. And while we run them (at runtime) as non-root, its still no excuse. </separate thread>

Then we saw security tools like Docker Bench, which is a tool to identify security issues, on the host, against the CIS give us a quickstart instruction that is an exact antithesis of good Docker runtime security practice. See if you can spot said practices

Docker Bench Security - Running as a Container

These kind of practices are still pretty common, especially when people have services like CI, etc that are containers that spawn containers 🙀

Then, we heard, that we should reduce unnecessary code in our containers by not using huge OS images like Ubuntu, etc, but to use alpine instead, that was much more lightweight. Until we realized that alpine downloads all packages over HTTP, vulnerable to MiTM attacks, which can lead to Remote Code Execution. 🙀🙀🙀🙀

Full disclosure: Some of our images still run alpine by the way. We are migrating to distroless for some of our apps, but this could take time rearchitecting them to work this way.

The point I am trying to make is that a lot of (bad) advice around Container Security over the last 5 years or so have shaped our current view of containerized technology. This is what has caused the poor state of container security, and the exacerbation of flaws when they are deployed at scale (with Kubernetes and so on).

Now, lets talk about CVE-2019-5736...

runC is a low-level tool that is used to spawn and run containers. It is used by Docker and other container runtimes to run containers. These engines provide the additional CLI, data formatting and serialization options to run runC.

On 11 Feb 2019, a vulnerability in runC was released. Here, an attacker can exploit a vulnerable runC deployment by overwriting the host runC binary and compromise host root access.

>> Basically, if you're running a container that has been compromised AND is running as uid0, with a vulnerable version of runC on your host, then an attacker can escalate privileges to your host and obtain root privs on the host running the container.

Already I see a ton of marketing material and the obvious security industry FUD about this flaw. However, this is underpinned by some very key elements.

If you're running your container as root...

I think its safe to say that there's always a chance of a container breakout if you're running your container as root. This can be made worse by: attacker-controlled docker images, malicious docker images, vulnerable apps in images and other possibilities caused by the "easy pull" effect from public repositories. Running your container as root, runC vulnerability or otherwise has dangerous consequences

Something as simple as this, for instance

root$ echo "S3cr3tStuff" >> /root/secretfile.txt
root$ usermod -aG docker we45
root$ su we45
we45$ docker run -it -v /:/hostFS alpine sh
/ # cat /hostFS/root/secretfile.txt

If you're running Docker, always run containers with -u 100 or something similar, that will run the container as uid100

docker run -it -u100 -v /:/hostFS alpine sh
/ $ whoami
whoami: uid 100

Most of us run containers with Orchestration Systems like Kubernetes.

Kubernetes has the PodSecurityPolicy Admission Controller that can be configured to NEVER allow a container running in the namespace as root.CV

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: non-root
spec:
  privileged: false
  allowPrivilegeEscalation: false
  runAsUser:
    # Require the container to run without root privileges.
    rule: 'MustRunAsNonRoot'

Its also a good idea to not run containers mapped to Host UIDS, Host PIDs and Host Networks

You should be continuously your hosts for containers running with insecure options like --privileged or other insecure options with tools like OSquery, Sysdig Falco and so on.

However, beyond all this, if you're running Docker, you should patch your Docker runtime to version 18.09.2

The good thing is that this flaw has already been patched by several cloud service providers. I received emails from some of them immediately. Especially the ones running managed K8s services

CVE-2019-5736 (the runC flaw) is a serious flaw. However, its not unlike many of the flaws that get disclosed regularly. I believe that it being exploited actively is also largely owed to the fact that a lot of container security basics are missing in most deployment environments.