redis系列安全问题整理
redis相关
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string、list、set、zset和hash。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
redis常用命令
1 | |
Redis基本操作
1 | |
ReRedis配置文件参数
port参数
1 | |
bind参数
1 | |
save参数
1 | |
requirepass参数
1 | |
dir参数
1 | |
dbfilename参数
1 | |
config命令
1 | |
protected-mode参数
1 | |
redis漏洞利用原理
Redis 提供了2种不同的持久化方式,RDB方式和AOF方式.
- RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照
- AOF 持久化记录服务器执行的所有写操作命令.
经过查看官网文档发现AOF方式备份数据库的文件名默认为appendonly.aof,可以在配置文件中通过appendfilename设置其他名称,通过测试发现不能在客户端交互中动态设置appendfilename,所以不能通过AOF方式备份写任意文件.
- RDB方式备份数据库的文件名默认为dump.rdb,此文件名可以通过客户端交互动态设置dbfilename来更改,造成可以写任意文件.
redis 未授权访问漏洞
其实最关键的便是未授权可以访问redis导致一系列漏洞单独整理一篇redis相关的未授权访问漏洞的利用,还是有比较多的利用方式
漏洞编号:cnvd_2015_07557
漏洞简介以及危害
Redis 默认情况下,会绑定在 0.0.0.0:6379,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的config 命令,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 /root/.ssh 文件夹的authotrized_keys 文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器、添加计划任务、写入Webshell等操作。
环境搭建
直接用在线靶场也是可以的
1 | |

1 | |

漏洞验证
为了方便,在windows攻击机里下载一个redis clinet
下载地址:https://github.com/caoxinyu/RedisClient/releases (利用redis写webshell测试使用)

使用redis clinet 直接无账号成功登录redis,从登录结果可以看出redis未启用认证。

直接写shell
未授权验证成功,可以直接往里写webshell
1 | |
这里我们调出Console,用来执行命令

我们这里因为是本地搭建,靶机网站路径:/var/www/html/,将shell写在这个目录下即可
1 | |




执行完之后去靶机查看目录下,成功写入webshell

后续后渗透这里就不再继续下去了,这里同样也可以直接反弹shell
写 ssh-keygen 公钥登录服务器
靶机开启redis服务,我这里靶机(redis服务端)为192.168.158.143,是一台kali

SSH提供两种登录验证方式,一种是口令验证也就是账号密码登录,另一种是密钥验证。
所谓密钥验证,其实就是一种基于公钥密码的认证,使用公钥加密、私钥解密,其中公钥是可以公开的,放在服务器端,你可以把同一个公钥放在所有你想SSH远程登录的服务器中,而私钥是保密的只有你自己知道,公钥加密的消息只有私钥才能解密,大体过程如下:
(1)客户端生成私钥和公钥,并把公钥拷贝给服务器端;
(2)客户端发起登录请求,发送自己的相关信息;
(3)服务器端根据客户端发来的信息查找是否存有该客户端的公钥,若没有拒绝登录,若有则生成一段随机数使用该公钥加密后发送给客户端;
(4)客户端收到服务器发来的加密后的消息后使用私钥解密,并把解密后的结果发给服务器用于验证;
(5)服务器收到客户端发来的解密结果,与自己刚才生成的随机数比对,若一样则允许登录,不一样则拒绝登录。
条件:
Redis服务使用ROOT账号启动
服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器。
在攻击机本地生成公钥文件,为我们的公钥文件设置一个私钥
公钥文件默认路径:/root/.ssh/id_rsa.pub
1 | |

将生成的公钥也就是id_rsa.pub写入ket.txt
1 | |
然后通过未授权访问目标机器,将保存ssh的公钥1.txt写入redis缓存(使用redis-cli -h ip命令连接靶机,将文件写入):
1 | |
然后执行下列命令:
1 | |
去靶机root/.ssh/目录下可以看到成功写入authorized_keys,

利用公钥进行SSH登录攻击机,第一次需要输入yes

利用crontab计划任务反弹shell
cron介绍
我们经常使用的是crontab命令是cron table的简写,它是cron的配置文件,也可以叫它作业列表,我们可以在以下文件夹内找到相关配置文件。
/var/spool/cron/ 目录下存放的是每个用户包括root的crontab任务,每个任务以创建者的名字命名
/etc/crontab 这个文件负责调度各种管理和维护任务。
/etc/cron.d/ 这个目录用来存放任何要执行的crontab文件或脚本。
我们还可以把脚本放在/etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly、/etc/cron.monthly目录中,让它每小时/天/星期、月执行一次。
其他crontab知识可以参考:https://www.runoob.com/w3cnote/linux-crontab-tasks.html
注意:
在不同系统中,root的位置是不一样的
在kali和ubuntu中,其文件位置为/var/spool/cron/crontabs/root,在centos系列中位置为/var/spool/cron/root,通常情况下没有root文件,需要自己创建。
攻击机监听端口:

连接redis,写入反弹shell,也可以跟上方一样在console执行,注意kali和centos的定时任务路径不同即可
1 | |

过一分钟左右监听就能收到shell了

nmap检测
如果你的redis-info模块没法用,更新一下nmap可能会有用
1 | |

redis未授权访问(主从复制)
本质也是未授权访问,但是因为只存在于4.x、5.x版本中,所以单独写出来
Redis提供了主从模式,主从模式指使用一个redis作为主机,其他的作为备份机,主、从机数据都是一样的,从机只负责读,主机只负责写。在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在Redis中实现一个新的Redis命令,通过写C语言编译并加载恶意的.so文件,达到代码执行的目的。
漏洞编号:cnvd_2019_21763
原理:
Redis如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上,然后在从机上加载so文件,我们就可以执行拓展的新命令了。
条件:
Redis 版本(4.x~5.0.5)(新增模块功能,可以通过C语言并编译出恶意.so文件)
redis弱密码或者无密码
root启动redis
原理倒是很简单也很易懂,整个还是建立在redis未授权基础上的漏洞
环境搭建
因为之前服务端我搭建的是2.x版本的,要重新搭建,直接用现成的靶场也可以,我这里就再搭建一个4.x版本的redis,毕竟搭建redis不是那么麻烦的
1 | |
切换个版本就好,把之前2.x版本的东西覆盖一下,注意这里要将配置文件中的bind参数改为0.0.0.0或者注释掉,并且修改protected-mode为no允许外连



漏洞验证
下载漏洞利用工具,也有一个整体的利用项目:https://github.com/n0b0dyCN/redis-rogue-server
我这里是用了另一个佬的脚本
1 | |
下载利用脚本并运行
1 | |

漏洞修复
本质上还是因为未授权访问导致的命令执行漏洞
Redis Lua沙盒绕过命令执行
也是建立在未授权访问的基础上产生的该漏洞
漏洞描述及影响范围
Redis是著名的开源Key-Value数据库,其具备在沙箱中执行Lua脚本的能力
Debian以及Ubuntu发行版的源在打包Redis时,不慎在Lua沙箱中遗留了一个对象package,攻击者可以利用这个对象提供的方法加载动态链接库liblua里的函数,进而逃逸沙箱执行任意命令;要利用此漏洞,攻击者需具有执行 eval 命令的权限(攻击者经过认证、或者 Redis 本身未设置鉴权检查)
只影响运行在 Debian 系的 Linux 发行版系统(Debian、Ubuntu 等)上的 Redis 服务,其他系统上的 Redis 服务不受影响。
漏洞编号:CVE-2022-0543
环境搭建
通俗点来讲就是借助Lua沙箱中遗留的这个对象提供的方法加载动态链接库liblua里的函数,逃逸沙箱执行任意命令
vulfocus在线靶场、vulhub或者自己搭建redis
漏洞验证
1 | |
我们借助Lua沙箱中遗留的变量package的loadlib函数来加载动态链接库/usr/lib/x86_64-linux-gnu/liblua5.1.so.0里的导出函数luaopen_io。在Lua中执行这个导出函数,即可获得io库,再使用其执行命令:
值得注意的是,不同环境下的liblua库路径不同,你需要指定一个正确的路径。Vulhub环境(Ubuntu fiocal)中,这个路径是/usr/lib/x86_64-linux-gnu/liblua5.1.so.0。
1 | |

这里是在线靶场,直接在对应目录下找flag即可
1 | |

修复措施
目前官方已有安全版本,请受影响的用户尽快升级至安全版本进行防护,参考链接:#1005787 - redis: CVE-2022-0543 - Debian Bug report logs。
安全版本:
1 | |
Windows下如何getshell
1 | |
批量检测未授权redis脚本
https://github.com/Ridter/hackredis
修复方式及加固
1、禁止一些高危命令(重启redis才能生效)
- 修改 redis.conf 文件,禁用远程修改 DB 文件地址
1 | |
- 或者通过修改redis.conf文件,改变这些高危命令的名称
1 | |
2、以低权限运行 Redis 服务(重启redis才能生效)
为 Redis 服务创建单独的用户和家目录,并且配置禁止登陆
1 | |
3、为 Redis 添加密码验证(重启redis才能生效)
修改 redis.conf 文件,添加
1 | |
4、禁止外网访问 Redis(重启redis才能生效)
修改 redis.conf 文件,添加或修改,使得 Redis 服务只在当前主机可用
1 | |
在redis3.2之后,redis增加了protected-mode,在这个模式下,非绑定IP或者没有配置密码访问时都会报错。
5、修改默认端口
修改配置文件redis.conf文件
1 | |
默认端口是6379,可以改变成其他端口(不要冲突就好)
6、保证 authorized_keys 文件的安全
为了保证安全,您应该阻止其他用户添加新的公钥。
- 将 authorized_keys 的权限设置为对拥有者只读,其他用户没有任何权限:
1 | |
- 为保证 authorized_keys 的权限不会被改掉,您还需要设置该文件的 immutable 位权限:
1 | |
- 然而,用户还可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目录和 authorized_keys 文件。要避免这种情况,需要设置 ~./ssh 的 immutable 权限:
1 | |
7、设置防火墙策略
如果正常业务中Redis服务需要被其他服务器来访问,可以设置iptables策略仅允许指定的IP来访问Redis服务。