Redis介绍

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

未授权访问漏洞介绍

Redis默认的情况下会绑定在0.0.0.0:6379。如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。

漏洞危害

  • 攻击者无需进行身份认证即可访问内容数据,这种情况会导致数据泄露或者数据清除
  • 攻击者可以通过eval来执行lua代码或者通过数据备份功能向磁盘中写入后门
  • 如果redis运行的权限是root,那么攻击者可以给root用户写入ssh公钥文件,直接通过ssh登陆目标服务器

环境搭建

1.首先我们下载Redis

wget http://download.redis.io/releases/redis-3.2.11.tar.gz 


2.解包并编译

tar xzf redis-3.2.11.tar.gz

进入目录编译

cd redis-3.2.11
make

如下即是编译成功:

3.编译成功之后,我们进入src目录,将redis-serverredis-cli拷贝到/usr/bin目录下(以后启动的时候不用每次都进入安装目录了)

cd src
cp redis-server /usr/bin
cp redis-cli /usr/bin


4.查看复制过去的文件

ls /usr/bin/ | grep redis


5.返回到redis-3.2.11的根目录下,将redis.conf拷贝到/etc/目录下

cp redis.conf /etc/

6.编辑复制到/etc/目录中的redis.conf

gedit /etc/redis.conf 

没有gedit的可以用vi

vi /etc/redis.conf 

然后将ip绑定去除,在bind 127.0.0.1前添加注释。

关闭保护模式,允许本地以外的主机远程登陆redis服务,将protected-mode yes中yes的改为no。

7.使用/etc/目录下的redis.conf文件中的配置启动redis服务

redis-server /etc/redis.conf


8.我们查看一下我们的ssh是否启动,方便我们之后的测试,这里我们的ssh已经启动。

没有启动可以使用如下命令启动

service sshd start

9.配置完成之后我们将这台主机克隆为两个主机,一个为攻击机,一个为靶机。

漏洞复现

1.连通性测试
我们通过ifconfig,我们两台机器的ip如下:

192.168.252.174
192.168.252.136

经过我们的测试,两台机器可以ping通


2.我们将ip地址为192.168.252.136的主机为靶机,192.168.252.174为攻击机。
**3.我们打开靶机中的redis服务:redis-server /etc/redis.conf**

4.我们重新打开一个命令行,在靶机中执行mkdir /root/.ssh,这是为了创建ssh公钥的存放目录
5.我们打开攻击机,在这台机器中生成公钥和私钥,将密码设置为空

6.我们进入到攻击机中.ssh目录下,将我们生成的公钥保存到alexsel.txt中。

(echo -e "\n\n";cat id_rsa.pub;echo -e "\n\n") > alexsel.txt

7.接着我们将alexsel.txt写入redis中,这里我们使用redis-cli -h IP命令连接靶机,将文件写入。
我们在连接的时候出现了一些问题,这里问题是由于系统的iptables防火墙拦截了我们的请求,我们在这里可以使用两种方式来解决
方法一:添加规则,放行我们的请求:

iptables -N REDIS
iptables -A REDIS -s 192.168.10.1 -j ACCEPT
iptables -A REDIS -s 192.168.10.2 -j ACCEPT
iptables -A REDIS -j LOG --log-prefix "unauth-redis-access"
iptables -A REDIS -j REJECT --reject-with icmp-port-unreachable
iptables -I INPUT -p tcp --dport 6379 -j REDIS
192.168.10.1  192.168.10.2  为需要访问的ip (包括redis服务器本身ip,不放本机访问不了)

方法二:删除过滤规则

iptables -F

问题解决之后我们就可以成功的执行命令了:

cat alexsel.txt | redis-cli -h 192.168.252.136 -x set crack


8.接着我们在攻击机上远程登录靶机的redis服务并获得redis的备份路径。
登录redis服务

redis-cli -h 192.168.252.136

拿到备份路径

config get dir


9.我们更改redis备份的路径为ssh公钥存放目录,一般默认为/root/.ssh

10.设置上传公钥的备份文件名字为authorized_keys并查看是否设置成功。

11.如上配置均为成功,我们就保存退出。

12.我们在攻击机中使用ssh免密登录靶机,我们这里的靶机的ssh是已经打开的。

13.登录成功,我们在攻击机上查看ip

这里如果有登录不成功的情况,我们需要在靶机中修改配置文件,打开gedit /etc/ssh/sshd_config
这个是登录root用户的情况下需要修改的参数,如果不是不需要修改。

漏洞修复

禁止远程的高危命令
修改redis的配置文件redis.conf来禁用远程修改DB文件地址

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

低权限运行redis服务
我们为redis服务创建一个单独的user和home目录并配置禁止登录

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

为redis添加密码验证
我们在redis配置文件中配置密码验证

requirepass mypassword

禁止外网访问redis
我们可以通过修改redis.conf文件中的配置来使得服务只能在当前的主机可用,这个我们最开始的时候为了实验,我们在配置文件中将其注释了。

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位权限

最后修改:2020 年 08 月 27 日
如果觉得我的文章对你有用,请随意赞赏