In February 2019, a vulnerability was found in runC container runtime. CVE-2019-5736 affects Docker’s containers that run on default settings and can lead the attacker to gain root level access on the host. The same fundamental flaw was also found in LXC, where, as opposed to runC, only privileged LXC containers are vulnerable.
What is runC?
RunC is an open source universal container runtime originally developed by Docker. It runs applications in a distributed fashion across many machines, with a variety of hardware and OS configurations. In order to do so, it needs a sandbox environment capable of abstracting the specifics of the underlying OS. Currently, Linux OS is best featured to make these kinds of abstractions possible.
RunC is mainly used by ‘high level’ container runtimes that will usually use runC to handle tasks related to running containers – creating containers, attaching a process to an existing container and so on.
The runC vulnerability takes advantage of file descriptor mishandling, as well as a unique aspect of Linux/proc filesystem that will eventually allow the attacker to write the host runC binary with a malicious binary.
The path /proc/self/exe points to the path of the process currently scheduled in the kernel. When a user launches a new container or launch execs to a running container (by using runC) the /proc/self/exe in the container will point to the host’s runC binary. If the entrypoint script (in new containers) or any binary (if exec’ing to an existing container) is replaced and referenced to /proc/self/exe, then when the action occurs, the container will re-execute the binary that is currently pointed by /pro/self/exe, which means that the host’s runC binary will be executed. Eventually, the host runC will be used, but it will also load runC’s required dynamic libraries from the filesystem.
If the file descriptor is mishandled (like configured by default), and has the ability to open for writing, the attacker can write malicious code in one of the runC libraries. This library can be used to overwrite the host runC binary with a different code. That code will be executed whenever the user runs the original runC binary.
What should you do?
Patch! Both runC and LXC released a patch that uses the same method. It re-executes the container from a temporary copy of itself. As a result, /proc/self/exe will point to the temporary file, preventing the ability to reach the runC binary from within the container. The temporary file itself is also sealed to block writing to it, even though overwriting it shouldn’t be harmful.
However, this patch is not perfect and may introduce some issues. This solution might cause a problem with containers running with a low memory limit. Also, those containers might be Out Of Memory killed by the kernel when the runC init process attaches to them.
The patch, with its own limitations, can give you a solution up to a certain point, but we suggest to think about a low level broader solution.
Reducing the attack surface by adjusting OS configuration to a more secure fashion:
Containers weren’t designed to solve security challenges. Their main destiny is to solve a development challenge – the dependencies labyrinth. This efficiency for the developers comes at the cost of a very complex infrastructure. Often neglected is the security of the container host.
The runC vulnerability should raise concerns among organizations using containers and virtualized environments, according to Mark Nunnikhoven, vice president of cloud research at Trend Micro. “This vulnerability demonstrates that each container can be a risk to the host” says Nunnikhoven. He adds: “Here, the attack highlights the biggest security weakness of containers: they are loosely isolated sharing the same host operating system. This is in stark contrast to virtual machines which are isolated instances of a complete operating system.”
According to Nunnikhoven, in the case of the runC vulnerability, the container host’s security has vital importance. “Hardening the host’s operating system by reducing the number of available services… to the bare minimum, is critical to security success”. You should make sure that the only services running are the container runtime, host security controls, and host monitoring applications.
Ensuring that your OS is hardened will give you broader insurance against the security flaws that virtualization brings. As technologies in this field constantly change, making sure that the foundations are secured can minimize the damage in case of a breach, which will probably happen at some point.
How CHS for Linux can solve this challenge:
Linux OS is believed to be more secure than other OS, but it is probably because up until now it was a less strategic target for attackers. As Linux usage spreads, most likely due to the virtualized technologies that find it more suitable to their needs, attacks will raise. Security professionals know that there is no OS more secure than the other.
CHS for Linux by CalCom will solve this challenge for you by automating your hardening process. With CHS’ learning ability, hardening actions will be conducted without the need to invest in lab testing and without causing any outages to production. In addition, configurations will be updated according to best practices and recommendations and will be automatically implemented on the production environment in one simple action. Using CHS for Linux will give you the ability to constantly get updates regarding your state of compliance.