redis一些利用的整理
本文最后更新于:2025年4月18日 晚上
打ctf很久了,由于redis攻击面在ctf里并不是很常出现,一直没有做深入分析,最近总结一下。
REDIS未授权访问的利用
1 |
|
在password泄漏或者未开启密码验证的情况下,我们可以尝试未授权连接redis数据库。
利用REDIS持久化写入shell
此手法可以结合gopher协议作为对ssrf漏洞的深入利用。本质上在利用成功的情况下,这是一个任意文件写漏洞,可以使用所有任意文件写相关的利用手法做攻击面扩展。
在高版本redis下,似乎手动关闭也不能动态修改受保护的配置文件项。(目前确定原因应该是apt中的redis经过patch?)
动态修改配置文件的操作只有在低版本的REDIS中生效,在高版本中想要动态修改配置文件需要先手动将配置文件。
在配置文件中,
protected-mode no
保护模式关闭外网可访问
enable-protected-configs local
或enable-protected-configs no
来允许动态修改保护的配置
当接收到save命令时,redis会把数据持久化写入硬盘,具体的写入目录是redis的工作目录,这个目录可以通过config get dir
来看到。
我们可以使用config set dir /var/www/html/
来改变redis的工作目录,
接下来修改redis持久化存储的缓存文件名,并执行一次持久化操作,即可将当前redis内容写入缓存文件
我们来分析一下它的缓存文件看看
可以发现,虽然是二进制数据,但是我们的明文信息,仍然会以明文存储在缓存文件中。
使用php解释器运行此文件
似乎无法解析,猜测是redis中其他数据影响了php解释器对文件的解析。
经过验证,想要php解释器解析此文件需要满足以下条件:
- redis键值对中不能有其他
<?
,会影响解释器的解析 - 恶意代码中的尖括号需要闭合,否则会被后续数据影响引起err
REDIS主从复制
搭建环境
我们搭建两个redis:5.0
的docker环境用来实现主从复制。
可以看到,从机可以自动复制主机的键值对。
在主从复制环境中,主机是可以是同时读写的,而从机的环境是只读的。
主从复制漏洞分析
本质上是伪造恶意redis主机做主从复制,加载恶意二进制文件实现rce。
抓包分析
我们使用tcpdump抓流量分析一下主从复制的协议建立过程
1 |
|
此流量记录了我们执行以下操作的网络交互
可以看到先发送了ping和pong确认了连接成功
在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令REPLCONF ACK <replication_offset>
- 主从服务器可以通过发送和接收REPLCONF ACK命令来检查两者之间的网络连接是否正常:如果主服务器超过一秒钟没有收到从服务器发来的REPLCONF ACK命令,那么主服务器就知道主从服务器之间的连接出现问题了
- 通过向主服务器发送INFO replication命令,在列出的从服务器列表的lag一栏中,我们可以看到相应从服务器最后一次向主服务器发送REPLCONF ACK命令距离现在过了多少秒
二者协商了通信监听端口
CAPA 全称是 capabilities,表示的是同步复制的能力。
slave 会在这一阶段发送 capa 告诉 master 自己具备的(同步)复制能力, master 收到后记录在 slave 所对应的客户端状态slave_capa 属性。
CAPA 在最新的 Redis 6.0 版本中有两种值:eof 和 psync2。
eof 表示 slave 支持直接接收从 socket 发送过来的 RDB 数据流,也就是无盘加载(diskless_load)。
psync2 表示 slave 支持 Redis 4.0 引入的部分重同步 v2 版本。
在slave端发送psync2后,master端发送了fullresync
master端的回复的大致结构是
1 |
|
通过对比可以验证此时发送的正是完整的dump.rdb的内容。
这样的话主从复制rce的思路就很明了了,我们只需要实现一个恶意的redis的master端,在能访问受害机器的redis时,将主机设置为我们的恶意master端,我们即可任意传输rdb文件,在受害端设置dbfilename
后,等于是我们获得了一个任意文件写的功能,可以利用redis的module load 即可加载恶意so文件,实现rce。
实验
注意在module load加载so文件时,可能会出现报错:
1
Module /data/module.so failed to load: /data/module.so: cannot open shared object file: No such file or directory
1
2039:M 20 Mar 2025 22:47:15.441 # Module /Users/slain/ctf/things/RedisModules-ExecuteCommand/module.so failed to load: /Users/slain/ctf/things/RedisModules-ExecuteCommand/module.so: failed to map segment from shared object
第一个错误并不是没法找到so文件,并非路径不对,经过验证,应该是so文件编译环境问题导致有些动态连接库找不到,在与目标机器相同环境下编译so文件即可正常加载。
首先我们加载伪造的恶意redis的master端
在受害机上执行了slaveof后成工复制恶意数据
此时rdb文件已经成功被我们写入
直接加载dump.rdb文件
可以看到成功加载system
成功rce
流量分析
可以看到只是将原本的rdb数据内容替换成了我们的恶意文件,随后会被FULLRESYNC指令写入受害redis的rdb中,在受害redis中加载此文件为module即可rce。