According to Jay Chen, senior cloud vulnerability and exploit researcher for Unit 42 part of Palo Alto, they have discovered a new cryptojacking worm, Graboid that’s spread to more than 2,000 unsecured Docker hosts. We derived the name by paying homage to the 1990’s movie “Tremors,” since this worm behaves similarly to the sandworms in the movie, in that it moves in short bursts of speed, but overall is relatively inept.
There have been incidents of cryptojacking malware spreading as a worm, but this is the first time we see a cryptojacking worm spread using containers in the Docker Engine (Community Edition). Because most traditional endpoint protection software does not inspect data and activities inside containers, this type of malicious activity can be difficult to detect. The malicious actor gained an initial foothold through unsecured Docker daemons, where a Docker image was first installed to run on the compromised host.
The malware, which was downloaded from command and control (C2) servers, is deployed to mine for Monero and periodically queries for new vulnerable hosts from the C2 and picks the next target at random to spread the worm to. Our analysis shows that on average, each miner is active 63% of the time and each mining period lasts for 250 seconds. The Docker team worked quickly in tandem with Unit 42 to remove the malicious images once our team alerted them of this operation.
Containerized Cryptojacking Worm
Figure 1. Cryptojacking worm activity overview
A quick Shodan search shows that show that more than 2,000 Docker engines are insecurely exposed to the internet. Without any authentication or authorization, a malicious actor can take full control of the Docker Engine (CE) and the host. The attacker leverages this entry point to deploy and spread the worm.
Figure 1 illustrates how the malware is delivered and spread. The attacker compromised an unsecured docker daemon, ran the malicious docker container pulled from Docker Hub, downloaded a few scripts and a list of vulnerable hosts from C2 and repeatedly picked the next target to spread the worm. The malware, which we’ve named ‘Graboid’, carries out both worm-spreading and cryptojacking inside containers. It randomly picks three targets at each iteration. It installs the worm on the first target, stops the miner on the second target, and starts the miner on the third target. This procedure leads to a very random mining behavior. If my host is compromised, the malicious container does not start immediately. Instead, I have to wait until another compromised host picks me and starts my mining process. Other compromised hosts can also randomly stop my mining process. Essentially, the miner on every infected host is randomly controlled by all other infected hosts. The motivation for this randomized design is unclear. It can be a bad design, an evasion technique (not very effective), a self-sustaining system or some other purposes.
Worm Simulation
To better understand the effectiveness of the worm and its overall mining power, we created a simple Python program to simulate the worm. Assume that there are 2,000 hosts in the IP file, 30% of these hosts fail during the operation, a 100-seconds refresh interval and one CPU on each compromised host. The experiment simulates a 30-day campaign. We are interested in finding out:
- How long does it take for the worm to spread to all the vulnerable Docker hosts?
- How much mining power does this malicious actor own?
- How much time does each miner stay active on an infected host?
The left part of Figure 2 shows how fast the worm spreads. It takes about 60 minutes for the worm to reach all the 1,400 vulnerable hosts (70% of the 2,000+ hosts). The right part of Figure 2 shows the overall mining power of the compromised hosts. There are, on average, 900 active miners at any time. In other words, the malicious actor owns a 1,400 node mining cluster that has at least 900 CPU mining power. Because miners on the infected hosts can randomly start and stop, each miner is only active 65% of the time and each mining period lasts for only 250 seconds on average.
While this cryptojacking worm doesn’t involve sophisticated tactics, techniques, or procedures, the worm can periodically pull new scripts from the C2s, so it can easily repurpose itself to ransomware or any malware to fully compromise the hosts down the line and shouldn’t be ignored. If a more potent worm is ever created to take a similar infiltration approach, it could cause much greater damage, so it’s imperative for organizations to safeguard their Docker hosts.
Below is a list of best practices for organizations to help prevent from being compromised:
- Never expose a docker daemon to the internet without a proper authentication mechanism. Note that by default the Docker Engine (CE) is NOT exposed to the internet.
- Use Unix socket to communicate with Docker daemon locally or use SSH to connect to a remote docker daemon.
- Use firewall rules to whitelist the incoming traffic to a small set of sources.
- Never pull Docker images from unknown registries or unknown user namespaces.
- Frequently check for any unknown containers or images in the system.
- Cloud security solutions such as Prisma Cloud or Twistlock can identify malicious containers and prevent cryptojacking activities.