[攻击者] --> [SSRF 漏洞] --> [Redis 未授权访问] --> [写入 WebShell] --> [访问 shell.php 执行 RCE]
漏洞原理
原理概述: SSRF(服务器端请求伪造)漏洞允许攻击者通过目标服务器发起对内网资源的请求。结合 Redis 的未授权访问漏洞,攻击者可以发送恶意命令,利用 Redis 的文件写入功能(通过 CONFIG SET 和 SAVE)将 WebShell(如 PHP 代码)写入 Web 服务器目录(如 /var/www/html)。随后,访问该文件触发 RCE(远程代码执行),执行任意命令。
具体机制:
SSRF 发起请求:通过 SSRF 漏洞,向内网的 Redis 服务(通常 127.0.0.1:6379)发送 Gopher 协议封装的 Redis 命令。
Redis 未授权执行:Redis 接受并执行命令,如 FLUSHALL 清空数据,SET 写入 WebShell,CONFIG SET 修改保存目录和文件名,SAVE 生成文件。
文件写入 Web 目录:Redis 将数据保存为 Web 可访问文件(如 shell.php),内容包含可执行代码。
RCE 执行:攻击者访问
http://target/shell.php
,通过 POST 参数(如 sec=system("ls"))执行任意命令。
这个漏洞是利用SSRF进行RCE非常经典的一个漏洞。
利用条件
利用条件简单来讲就是说这里要存在SSRF漏洞,Redis组件存在而且其有未授权访问漏洞且我们有Redis文件写入权限,Redis 的文件写入需要运行用户对目标目录(如 /var/www/html)具有写权限。如果目标系统启用了 SELinux 或其他安全机制,可能限制写入。此外,Redis 高版本可能禁用 CONFIG 命令,需确认目标版本支持。详情具体见下:
SSRF 漏洞存在:
服务器允许用户控制请求 URL。
支持 Gopher 协议(如果目标服务器不支持 Gopher 协议,可尝试其他协议(如 HTTP 或 file://)访问 Redis,但效果可能受限)。
可访问内网资源(如 127.0.0.1:6379)。
Redis 配置不当:
未设置密码(未授权访问)。
监听端口(6379)暴露给内网或本地。
支持 CONFIG SET 命令修改 dir 和 dbfilename。
文件系统和 Web 服务器许可:
Redis 用户有权限写入 Web 目录(如 /var/www/html)。
Web 服务器能解析写入的文件(如 PHP 文件)。
攻击者可访问该文件(无 IP 限制)。
网络环境支持:
无防火墙阻挡 SSRF 到 Redis 的流量。
Payload 传输完整,无截断或过滤。
攻击者能力:
能构造 Gopher Payload(如用 Gopherus)。
了解 Redis RESP 协议和 WebShell 原理。
漏洞复现
环境启动
这个实际中比较少,这里使用CTF的靶场进行演示:
https://www.ctfhub.com/#/skilltree
这里,进入之后点击Web,然后点击SSRF,然后点击Redis协议一栏启动靶场即可。
然后这里我们还需要kali-linux虚拟机和Gopherus工具,这里分享了Gopherus工具。
通过网盘分享的文件:Gopherus-master
链接: https://pan.baidu.com/s/1fSGzrf-PDyX_nxqc0yE6SQ 提取码: ygvv
--来自百度网盘超级会员v3的分享
制作payload
我们把Gopherus拖入虚拟机中,之后切入Gopherus目录下,然后:
然后我们获得了payload:
payload内容分析
我们先解码payload,将 Gopher URL 的 Payload 部分(_%2A1%0D%0A...)解码为原始的 Redis 命令。以下是分步解析:
步骤 1:去掉 Gopher 前缀
Gopher URL 的 _ 之后是实际的 Payload,去掉 gopher://127.0.0.1:6379/_
,得到:
步骤2:URL解码
将 URL 编码的字符还原为原始字符:
%2A → *
%0D → \r(回车,CR)
%0A → \n(换行,LF)
%3C → <
%3E → >
%20 → 空格
%40 → @
%28 → (
%24 → $
%5B → [
%27 → '
%29 → )
%3B → ;
逐段解码后,Payload 变成以下内容(以可读格式表示,实际是连续的字节流):
步骤 3:解析 RESP 协议
RESP(Redis Serialization Protocol)是 Redis 客户端与服务器通信的协议,定义了命令和数据的传输格式。
Redis 的 RESP 协议使用以下规则:
*n\r\n
表示一个数组,包含 n 个元素。$m\r\n
表示一个字符串,长度为 m 个字节,后面跟着字符串内容和 \r\n。每个命令以数组形式发送,数组元素是命令和参数。
Redis 使用 RESP(Redis Serialization Protocol)作为客户端与服务器之间的通信协议。客户端发送的命令必须符合 RESP 格式,Redis 才能正确解析并执行。
步骤 4:整理为 Redis 命令
综合解码结果,Payload 对应的 Redis 命令如下:
这些命令依次:
清空 Redis 数据库。
设置键 1 的值为 PHP WebShell 代码。
设置 Redis 数据保存目录为 Web 根目录。
设置保存文件名为 shell.php。
保存数据到 /var/www/html/shell.php,将 PHP 代码写入文件。
payload生成过程
首先我们要知道Gopherus 是一个用于生成 SSRF Payload 的工具,支持将 Redis 命令转换为 Gopher 协议格式。
Gopher URL 是通过以下步骤生成的:
用户输入 PHP Shell,并指定 Web 根目录(如 /var/www/html)。Gopherus 自动设计了一组 Redis 命令(如
FLUSHALL
、SET
等)。步骤 2:使用 RESP 协议将命令转换为字节流
Gopherus将这些 Redis 命令转换为 RESP 协议格式,这是 Redis 通信的必需格式。
RESP 使用 *n 表示数组元素数,$m 表示字符串长度,\r\n 作为分隔符,确保 Redis 能正确解析。
使用 Gopherus 工具将字节流编码为 URL 安全格式(
* → %2A,\r → %0D,\n → %0A
等)。拼接成 Gopher URL,附加到
gopher://127.0.0.1:6379/_
。
为什么要进行URL编码
Gopher 协议要求:Gopher 协议传输的数据需要符合 URL 格式,特殊字符(如 *、\r、\n)必须编码为 %XX 形式,否则无法正确传输。
SSRF 场景:SSRF 漏洞通常通过 HTTP 请求发送 Payload,URL 编码确保 Payload 在传输过程中不被截断或解析错误。
攻击过程
我们先把我们上面获得的那个payload
再进行一次URL编码(这里这个二次编码并非在所有情况下都要进行,只是对于这个靶场环境而言要进行)
我们把这个payload复制,拼接,就像这样
然后我们直接访问shell.php
可以看到有乱码了,此时就是上传成功了,我们可以使用hackbar来进一步利用
我们继续
然后
这样我们就成功夺旗了。
修复建议
1. 修复 SSRF 漏洞:严格校验用户输入的 URL,禁止内网地址访问,禁用 Gopher 等危险协议。
2. 强化 Redis 配置:设置强密码,绑定 127.0.0.1 限制访问,禁用 CONFIG 命令。
3. 文件系统安全:限制 Redis 用户的写权限,使用 SELinux 或 chroot 隔离。
4. 网络安全:使用防火墙阻止内网流量,部署 WAF 过滤恶意 Payload。