以洞打洞看PHP下的SSRF的攻与防
字数 1477 2025-08-19 12:40:31
PHP下的SSRF攻防研究
前言
本文深入探讨PHP环境下SSRF(Server-Side Request Forgery)漏洞的攻击与防御,特别关注在限制条件下的利用技巧和防御方法。文章源自一个实际问题:为什么某些系统的SSRF漏洞无法攻击Redis服务,进而引发对SSRF攻击面及其局限性的全面思考。
前台SSRF漏洞分析
漏洞点1:盲SSRF
- 位置:
get_head函数未过滤用户输入 - 通过
get_curl可造成SSRF漏洞 - 特点:盲SSRF,无回显,利用不直观
漏洞点2:有回显的SSRF
- 文件位置:
include/file.php - 漏洞函数:
download_img - 漏洞特点:
- 未限制请求协议
- 通过
pathinfo检查文件后缀(仅允许jpg/gif/png/ico) - 请求结果会回显给客户端
测试环境与核心问题
环境条件
- curl未限制传入协议
- curl开启跟随跳转(支持301)
- 文件后缀限制为图片格式(jpg/gif/png/ico)
关键问题
- 是否可通过file://协议实现任意文件读取?
- 能否利用跳转绕过后缀限制?
- 如果限制只允许http协议,SSRF的攻击面和防御边界在哪里?
cURL协议深入研究
协议支持
- PHP内置curl模块(
--with-curl) - 测试环境curl版本7.52.1
- 默认支持20种网络协议
重要参数
CURLOPT_REDIR_PROTOCOLS:控制重定向允许的协议- 默认重定向支持除FILE和SCP外的所有协议(7.19.4之前版本例外)
SMB协议攻击面探索
SMB协议版本
- cURL 7.40+支持SMB/CIFS协议
- 仅支持SMBv1.0(Windows 10默认禁用)
攻击尝试
-
Net-NTLM劫持:
- 使用Responder工具
- 需要目标启用SMBv1
- 测试失败,无响应
-
NTLM中继:
- 需要SMB签名未开启
- 受限于MS08-068补丁(无法中继自己)
- 多机环境下可能利用
cURL与SMB的限制
- 严格格式要求:
smb://host/sharename/ - 必须提供有效凭证(或Guest访问)
- 仅支持SMBv1.0,现代系统默认禁用
Fuzz测试方法
Fuzz 1:任意文件读取绕过
- 尝试绕过后缀限制
- 测试
file:///etc/passwd{1}{2}{3}jpg等变形 - 结果:无法绕过后缀检查
Fuzz 2:重定向状态码
- 测试不同状态码(301/302/303/307/308)的行为差异:
- 301-303:强制转为GET请求
- 307-308:保持原始请求方法
Fuzz 3:重定向协议支持
- 测试libcurl重定向支持的协议
- 确认默认不支持file和smb协议重定向
防御SSRF的最佳实践
安全配置建议
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS | CURLPROTO_HTTP);
curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
防御要点
- 严格限制允许的协议(HTTP/HTTPS)
- 单独控制重定向协议
- 设置合理的超时和重定向次数
- 启用完整的SSL/TLS验证
结论
本文通过实际案例展示了PHP环境下SSRF漏洞的多种利用方式,特别是在限制条件下的攻击技巧。研究发现:
- 即使有后缀限制,SSRF仍可能通过协议特性造成危害
- SMB协议攻击面受限于协议版本和系统配置
- 合理的cURL配置可有效防御SSRF漏洞
参考资源
- PHP Curl Security Hardening
- Responder/SMB Relay技术
- CVE-2019-15601: SMB access smuggling via FILE URL
- NTLM Relay攻击技术
- Potato家族提权技术