某天公司的一台云主机被挖矿病毒入侵了,遭受了挖矿病毒的攻击,该挖矿病毒为redis未授权访问写入crontab脚本挖矿。公司由于一些历史信息建设的原因,采用了大量的阿里云主机构建了云上内网VPC,在上面部署的Redis服务很多没有设置密码。
该云主机的防护措施依赖于iptables,也就是设置Iptables只允许公司的企业网络出口访问,在正常情况下,这个Redis未授权访问相当于内网未访问。
而这起安全事件发生在该台主机宕机不久后发生。
通过病毒家族结合现有日志以及告警信息来看,该安全事件的发生有两个原因:
1、iptables 在系统宕机重启后未生效
2、redis空口令且root权限执行
在分析后得知了为何iptables在系统宕机重启后未生效
分析如下:
1、首先系统iptables规则的写入依赖于脚本/bin/iptables.sh
2、执行sh /bin/iptables.sh则依赖于自启动项/etc/rc.local
3、/etc/rc.local(开机自启动服务)在系统启动时执行,并且只执行一次,如果执行存在异常,则不再重新执行,如下图所示,直接写入sh /bin/iptables.sh即可
4、cat /etc/inittab 这个主机默认运行级别为id=3 ,那么也就是rc3,完整的多用户模式,绝大部分主机都是这个模式。
5、之后我们就可以查看ls -al /etc/rc3.d/,观察该目录,发现了S(start服务)redis服务。
rc.local的执行优先级为S99,而Redis的执行优先级为S90,那么根据顺序就是Redis启动之后rc.local服务才会启动,而rc.local启动后iptables规则才会生效。
6、在redis中存在/usr/local/redis-4.0.2/utils/redis_init_script,用户可以编辑或者修改该文件,使用chkconfig --add 命令,能够将redis服务进行开机自启动,将其添加到/etc/init.d/redis 中,
如下所示,redis开机自启动服务,拼接命令为
redis-server /etc/redis.conf
并且这台主机上允许的redis服务配置文件 /etc/redis.conf 中的daemonize配置默认为no ,没有设置后台启动
而该配置为no会增加Redis服务卡死或者阻塞的风险,这个情况比较常见。
7、于是我们梳理整个链条,得出如下情况:
1)主机因为某些原因导致宕机,需要重启
2)重启主机后rc3.d下S90为Redis和S99为rc.local
3)由于在启动S90 Redis服务时它的daemonize 设置为no,因此Redis服务启动了造成了阻塞,导致后续的程序启动异常,最终无法执行rc.local,也就无法启动iptables.sh。
因此防火墙没启动,造成了Redis未授权访问暴露在公网。
总结:
低版本centos(6.x)采用chkconfig添加自启动服务时,配置了redis优先于 rc.local启动, 并且redis-serve启动时为单进程模式,会对后续服务的启动进行阻塞,导致rc.local无法启动, 从而导致了iptables规则无法成功写入。
1)本地复现测试centos(7.9)
我们可以采用chkconfig -add redis的方式来开机自启动redis服务,会自动转发到systemctl来进行启动,并且rc.local的服务不会注册软链接到/etc/rc3.d/中
如下图所示,rc.local默认不会注册软链接到/etc/rc3.d/中,在高版本的centos里rc.local会被默认注册到systemctl中的 rc.local.service
通过对systemctl启动服务的分析,可以生成一个svg图,这个命令可以分析出systemctl关于显示系统启动过程中各个服务的启动顺序和时间占用情况
systemd-analyze plot >/root/1.svg
systemctl对于相同级别的总是并行启动,并多次重启发现rc.local总是比redis服务启动的时间更早
可以看到rc.local.service启动顺序排在redis.service前面,因此rc.local里的iptables.sh自然会启动成功
2)本地测试在低版本centos(6.8)
在/etc/rc3.d/中,rc.local默认软链接注册在目录当中,遵循rc3.d服务启动中的执行原则
使用chkconfig --add redis 后重启主机后,表现如下,启动后iptables 规则明显没有第一时间启动
1、启动后iptables没启动成功
2、执行ps -ef 发现是存在redis进程的
3、手动杀死redis进程
4、当redis进程消失后,iptables规则才写入成功
5、继续测试:chkconfig --del redis 后重启,此时已经没有redis写入启动项了,iptables则直接生效,说明redis的启动对iptables的规则写入产生了巨大的影响
6、在配置了daemonize为yes后,如下所示,一切正常
7、监控数据证明
因为监控数据服务的启动顺序在rc.local服务启动之后,且因为rc.local服务未启动,因此监控数据服务也未正常启动,如下图所示,在时间段内缺失了监控数据服务的日志,可以证明的确如上文所述
以下为监控数据服务截图(普罗米修斯运维工具)
安全事件发生原因
1、直接原因:
某云主机因Redis未授权访问漏洞被入侵,攻击者通过写入crontab脚本植入挖矿病毒。
2、根本问题:
Redis服务未设置密码,且以root权限运行。
iptables规则在主机重启后未生效,导致Redis暴露在公网。
3、防护失效分析
iptables规则依赖脚本/bin/iptables.sh,该脚本由/etc/rc.local在系统启动时执行。
rc.local仅在系统启动时执行一次,若执行失败(如被阻塞),不会自动重试。
4、关键依赖顺序:
低版本CentOS(6.x)中,服务启动顺序由/etc/rcX.d/目录的优先级决定(S表示启动顺序,数值越小优先级越高)。
在rc3.d目录中,redis服务(优先级90)先于rc.local(优先级99)启动,导致redis阻塞后续服务启动。
5、如何解决
1)Redis需要设置密码
2)CentOs7不会出现该问题,升级CentOs系统
3)Redis的配置daemonize错误
如果感觉公众号存在排版不舒服可以查看:
https://www.yuque.com/iceqaq/gpxll3/mfkbcpk3wdo68ik7
原文始发于微信公众号(Ice ThirdSpace):应急响应 | 记录一次不一样的redis未授权访问挖矿病毒分析——redis+iptables的配置异常导致入侵
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论