Vulnerability 4: Abusing Namespaces
What Are Namespaces
Namespaces segregate system resources such as processes, files, and memory away from other namespaces. Every process running on Linux will be assigned two things:
A namespace
A Process Identifier (PID)
Namespaces are how containerisation is achieved! Processes can only "see" the process in the same namespace. Take Docker, for example, every new container will run as a new namespace, although the container may run multiple applications (processes).
Let's prove the concept of containerisation by comparing the number of processes on the host operating system, in comparison to the Docker container that the host is running (an apache2 web server):
In the first column on the very left, we can see the user the process is running as, including the process number (PID). Additionally, notice that the column on the very right has the command or application that started the process (such as Firefox and Gnome terminal). It's important to note here that multiple applications and processes are running (specifically 320!).
Generally speaking, a Docker container will have very processes running. This is because a container is designed to do one task. I.e., just run a web server, or a database.
Determining if We're in a Container (Processes)
Let's list the processes running in our Docker container using ps aux
. It's important to note that we only have six processes running in this example. The difference in the number of processes is usually a great indicator that we're in a container.
Additionally, the first process in the snippet below has a PID of 1. This is the first process that is running. PID 1 (usually init) is the ancestor (parent) for all future processes that are started. If, for whatever reason, this process is stopped, then all other processes are stopped too.
Comparatively, we can see that only 5 processes are running. A good indicator that we're in a container! However, as we come to discover shortly, this is not 100% indicative. There are cases where, ironically, you want the container to be able to interact directly with the host.
How Can We Abuse Namespaces
Recall cgroups (control groups) in a previous vulnerability. We are going to be using these in another method of exploitation. This attack abuses conditions where the container will share the same namespace as the host operating system (and therefore, the container can communicate with the processes on the host).
You might see this in cases where the container relies on a process running or needs to "plug in" to the host such as the use of debugging tools. In these situations, you can expect to see the host's processes in the container when listing them via ps aux
.
The Exploit
For this vulnerability, we will be using nsenter
(namespace enter). This command allows us to execute or start processes, and place them within the same namespace as another process. In this case, we will be abusing the fact that the container can see the "/sbin/init" process on the host, meaning that we can launch new commands such as a bash shell on the host.
Use the following exploit: nsenter --target 1 --mount --uts --ipc --net /bin/bash
, which does the following:
We use the
--target
switch with the value of "1" to execute our shell command that we later provide to execute in the namespace of the special system process ID to get the ultimate root!Specifying
--mount
this is where we provide the mount namespace of the process that we are targeting. "If no file is specified, enter the mount namespace of the target process." (Man.org., 2013).The
--uts
switch allows us to share the same UTS namespace as the target process meaning the same hostname is used. This is important as mismatching hostnames can cause connection issues (especially with network services).The
--ipc
switch means that we enter the Inter-process Communication namespace of the process which is important. This means that memory can be shared.The
--net
switch means that we enter the network namespace meaning that we can interact with network-related features of the system. For example, the network interfaces. We can use this to open up a new connection (such as a stable reverse shell on the host).As we are targeting the "/sbin/init" process #1 (although it's a symbolic link to "lib/systemd/systemd" for backwards compatibility), we are using the namespace and permissions of the systemd daemon for our new process (the shell)
Here's where our process will be executed into this privileged namespace:
sh
or a shell. This will execute in the same namespace (and therefore privileges) of the kernel.
You may need to "Ctrl + C" to cancel the exploit once or twice for this vulnerability to work, but as you can see below, we have escaped the docker container and can look around the host OS (showing the change in hostname)
Last updated