The advent of microservices has led to us witnessing containers take the cloud by storm. But, this boom in the container-cloud relationship is exposing security issues that are inviting malware into the party as well.
Juniper Threat Labs recently discovered an infection in the wild that hunts for misconfigured publicly exposed Docker services in the cloud and infects them with containers that run Monero miners.
Docker provides REST APIs for management of its service, including the ability to create and start/stop containers. By default, Docker only enables Unix socket access to its REST APIs. To enable remote access to the Docker service’s REST APIs, one has to configure Docker to listen on TCP ports. The conventional ports used by Docker are 2375 and 2376 which, when enabled, would by default provide unencrypted and unauthenticated access to the docker REST APIs.
The infection we discovered spreads across hosts using misconfigured or loosely configured Docker services that expose its REST Management APIs through open and unauthenticated TCP ports 2375 and 2376 on the internet. Each new infection continues to spread the infection to other new hosts by scanning for the presence of other misconfigured Docker hosts on the network, effectively making it a worming capability.
A general overview of the infection is provided in the diagram below.
The entire infection chain is largely script based and lives off the land, making use of well-known, system-provided utilities to spread the infection and carry out its activities. Some of the system utilities that it uses are Docker, Wget, cURL, Bash, iproute2, MASSCAN, apt-get, yum, up2date, pacman, dpkg-query, systemd, etc.
Below is a screenshot of a Docker host instance being infected through its REST APIs on its daemon service’s default port 2375.
As seen above, the Docker daemon is requested to start a container and execute certain commands. The commands executed inside the container include instructions to download a script called “auto.sh” that is hosted on a remote server using “wget”.
The script “auto.sh” is the start point and platform for the infection. It bootstraps the container execution environment for the infection and also acts as a base to run other scripts to further scan for other Docker hosts and spread the infection.
The anatomy of the code flow is briefly described by the below diagram.
In the first stage of the entry script, “auto.sh”, it checks for the presence of certain packages: cURL, iproute2, openssh-server, openssh-clients and MASSCAN. If the packages are not found, it downloads and installs them using either apt-get, yum, up2date or pacman.
In the second stage of the “auto.sh” script, it creates new users and sets up SSH Access for these new users.
In the third stage of the “auto.sh” script, it downloads MoneroOcean’s Monero miner bash script hosted on Pastebin and executes it. The downloaded script is pretty much the stock version straight from MoneroOcean’s Github account. It download’s XMRig’s miner from the Github account and runs it as a systemd service.
Discovery: Port Scanning for NEW Docker Hosts to Infect
In the fourth stage of the auto.sh script, it uses masscan to port-scan the network subnets connected to the infected host. It scans for hosts running docker daemon with open TCP ports 2375 and 2376, and dumps to a local file, local.txt, the list of new host IP addresses to infect. Masscan is a publicly available port scanner tool.
Spreading The Infection
In this stage it first downloads two more scripts, test3.sh and test.sh, both of which are primarily tasked to spread the infection.
Auto.sh spawns the script test3.sh, passing it to local.txt (previous section)as the input. “test3.sh” loops through each IP address in local.txt and spawns test.sh feeding it each IP address as the argument. “test.sh” utilizes Docker’s very own client tool to connect to the remote host’s Docker service to spread the infection to the IP address passed to it as the argument, thereby expanding its infection footprint.
Going back to the infection scripts, they are hosted on a remote server identified by IP address 126.96.36.199. The contents of this server shown below.
The contents of this server shows all the script files as well as the presence of three more files: xm, it’s config file data.cfg and it’s corresponding systemd file xm.service.
“xm” is an ELF linux binary, identified as a CoinMiner in VirusTotal by other AV vendors.
The data.cfg config file fed to xm miner binary holds the same Wallet address used as a part of this infection - 4Aotje6mGNPRcDQeqS7iUwRLGJhLLgJvfbS6Dju5peSACbVXTFhnds53xuoqif3JEcfbdjiW27xuAJiiKeiCGbuoACrutNE
Please note that this above ELF binary is not downloaded as a part of this infection and that MoneroOcean’s Monero Miner script in this infection directly downloads Xmrig from Github and runs it to mine Monero.
Juniper Networks Sky ATP detects it as a cryptominer:
Cloud and containers are growing exponentially, but the exposure of services to the public internet has shown us that tons of services are misconfigured or loosely configured, leaving them vulnerable to be exploited by malicious parties.
In the same realm, misconfigured Docker services on the cloud are inviting cryptominers to utilize the vast computing resources of the cloud. But, it doesn’t have to stop there for these malicious actors. Apart from the availability of the massive computing power, the short-lived nature of containers means malicious parties can use containers to create temporary and effective attack points in their infection chain. Imagine a botnet that brings up containers running their bot on-demand, runs a DDoS and then shuts down the container, thereby reducing the footprint of its presence.
Correctly configuring network-facing services, instilling authenticated access to exposed ports and opening TCP ports only if necessary can alleviate some of these concerns.