When you run docker again on the volume, some files may get re-chowned to root again, or the application therein (i.e. Redis) may even fail because of wrong ownership. So it is a dilemma that I don't have a perfect answer. But you may want to study this docker setup on github that I contributed to, where you can run docker with none-root user. Both as docker container volume mapping and remote path mapping. PS: Yes, IP is good, as long as it’s the same in the settings and the mapping. MirxNL March 23, 2018, 5:24pm.
In our previous article we have discussed “Docker Installation & Configuration”but today you will learn how to escalate the root shell if docker is running on the hots machine or I should say docker privilege escalation to spawn root shell.
While we know that there is an issue with the docker that all the commands in docker require sudo as docker needs root to run. The Docker daemon works in such a way that it is allowed access to the root user or any other user in the particular docker group. This shows that access to the docker group is the same as to give constant root access without any password. 🧐
Quick Lab setup
Execute the below command to install docker in your localhost machine. I have used ubutnu 18.04 here as target machine.
Create a local user, say Ignite is the username with least privileges add new group “docker” for “ignite”.
To proceed for privilege escalation, you should have local access of the host machine, therefore here we choose ssh to access the machine as ignite who is a local user on this machine.
Since we have access to the user which is a part of the docker group and said above if the user is part of the docker group then it is the same as to give constant root access without any password. 😈
We ran the command shown below, this command obtains the alpine image from the Docker Hub Registry and runs it. The –v parameter specifies that we want to create a volume in the Docker instance. The –it parameters put the Docker into the shell mode rather than starting a daemon process. The instance is set up to mount the root filesystem of the target machine to the instance volume, so when the instance starts it immediately loads a chroot into that volume. This gives us the root of the machine. After running the command, we traverse into the /mnt directory and found out flag.txt.

Similarly, an intruder can mount other system files to escalate the privilege for the local user such as he can mount the passwd or shadow or ssh-key.
As you can see here, we try to mount/etc directory to obtain shadow file and similarly one can access passwd file and add his own privilege user. 🤔
So, if you have access shadow file then you can try to crack passwd hashes and if you have access passwd file you can add you own privilege user by generating password salt as shown here.
Docker Volume Mount Permission Denied 2018
Now a new record inside the passwd file for your user.

From the given below image you can observe that now we have user raj as member of root. Thus, we switch to as raj and access the root shell.
Thus, in this way we can escalated the permission of a host machine, hope you will enjoy this little and powerful post. 😊
Author: Kavish Tyagi is a Cybersecurity enthusiast and Researcher in the field of WebApp Penetration testing. Contacthere
This article is part of a series of three articles about Docker:
- Docker and permissions management
In this first post, I will show how you can deal with file permissions when a container is using root
and you want to keep access to the files as an unprivileged host user.
Let's start by looking at the problem.
We will run an alpine
container which is using root
. We will bind a host directory to a volume making every file in this directory available inside the container. Then, from the container, we will create a new file inside the volume.

From a host point of view, who will be the owner of this new file? What rights will be applied to it?
Let's run an alpine
container with a volume:
Replace [host directory]
and [container directory]
with any path that fits to you.
Doing this, you are prompted inside an Alpine distribution and every file inside the host's directory will be available inside the container's directory, and vice versa.
From the container, create a new file inside the volume:
As you can see, inside the container, the file is owned by root
. What about from the host?
The file is owned by root
too!
Now, from the host and with an unprivileged user, how can I access this file? Turns out I can't!
Permission denied
As every container can use a set of users and groups, we cannot just translate every container's user into a single host's user without breaking the rights. We have to map them into host's sub-users. Doing this is a feature called “User namespaces”.
A user namespace extends user's rights by allowing it to access files owned by other users or groups. Its configuration is made by editing two files:
/etc/subuid
/etc/subgid
Docker Mount Permission Denied
These two files have the same structure and are made of lines with this format:
Each line means that the user will gain access to a number of UID or GID starting from a certain number. As an example for subuid
:
This means that user foo
will have access to files owned by users with a UID of 1000, 1001 and 1002. This works the same for groups!
In a Docker context, container's users are mapped with host's users. Since UID 0 is always root
, the container's root
will always match the host's root
! This is the reason why, sometimes, we hear about 'Docker process isolation' or 'Process breaking out of a Docker container' because a user in a container has too many rights on the host.
We will now create two configurations:
- Tell Docker to use a different user than
root
- Map this user's sub UIDs with container's users
These two configurations will give us the ability to access files created by the container with a lower privileged user but also to avoid a container's user having root
rights on our host. To illustrate this point, we will use an Alpine image with a volume.
In our case, our user apocheau
will become the owner of our containers instead of root
:
We can see here that apocheau
has a UID and a GID of 1000.
We now have to define subuid
and subgid
with which our user will be allowed to access.
Edit the files /etc/subuid
and /etc/subgid
and add:
Here, I also recommend to add the following line to the /etc/subgid
file:
We are here saying that user apocheau
will have access to one group with GID starting from 999. In other words, apocheau
user will have access to group 999.
You should replace apocheau
with your username and 999 with the docker
group GID which you can grab with this command:
As the owner of the container will not be root
anymore, he does not have the permission to access the Docker socket that is owned by the docker
group. This additional line will give your user the right to access docker
group files and so the Docker socket. With this additional right, you'll be able to continue to bind you Docker socket. Useful for Portainer/Rancher/Træfik/Docker-gen/etc.!
Now that this is done, the last thing to do is to tell Docker to use our user. Create or edit the /etc/docker/daemon.json
file and add the following:
Different formats can be used here: username
, UID
or UID:GID
for example.

Docker Volume Mount Permission Denied
All what's left is to restart Docker:
Start the container and get into it:
Docker Volume Mount Permission

And create a file in /apps/files
directory inside this running image:
Now, from the host, go to the volume and notice that the owner of the test
file is not root
anymore but your user!
You'll also notice that the owner of the process is not root
anymore.
We have seen how common and recurrent these permission problems are. We used a really minimalist example to showcase the problem and the solution.
User namespaces should always be used when it comes to controlling your data and pushing your containers into production.
- You will have to re-download your images (after deactivating the user namespace, you will again have access to your previous images)
- This configuration applies to all your daemon's containers. The user namespace will only reduce the risk of a process breaking out of its container.