Objective
Learn how Server-Side Request Forgery (SSRF) vulnerabilities can be exploited to make unauthorized requests from a server to internal or external resources. Understand how to prevent SSRF by validating input URLs, limiting internal requests, and implementing allow-lists.
Scenario
You are assessing a web application that allows users to fetch external data (e.g., image previews or metadata) by providing a URL. Due to improper validation of user input, an attacker can manipulate the URL to send requests to internal services, potentially bypassing firewall restrictions and accessing sensitive internal resources.
Lab Setup
Prerequisites:
- Basic knowledge of PHP and web servers.
- XAMPP/LAMP/WAMP stack installed (or any web server with PHP support).
- Tools like Burp Suite or cURL for testing.
Step 1: Create the Vulnerable Web Application
- PHP Script with SSRF Vulnerability
- Create a file
fetch.php
:<?php if (isset($_GET['url'])) { $url = $_GET['url']; $response = file_get_contents($url); echo "<pre>$response</pre>"; } else { echo "<h2>Please provide a URL to fetch data.</h2>"; } ?> <h2>Fetch External Data</h2> <form method="GET" action=""> URL: <input type="text" name="url" required> <button type="submit">Fetch</button> </form>
- Create a file
- Running the Application
- Start the Apache server.
- Place
fetch.php
in the web server’s root directory (htdocs
for XAMPP). - Open
http://localhost/fetch.php
in your browser.
Exploitation Steps
Step 1: Exploiting SSRF to Access Internal Services
- Input the following URL in the form:
http://localhost:8080
- Expected Result:
- The server makes a request to the internal service running on port 8080, bypassing firewall rules.
Step 2: Accessing Sensitive Files
- Input this payload:
file:///etc/passwd
- Expected Result:
- The content of the
/etc/passwd
file is displayed, exposing sensitive system information.
- The content of the
Step 3: Scanning Internal Network (Advanced)
- Input URLs to internal IPs:
http://127.0.0.1:22
- Expected Result:
- The attacker can scan internal services, potentially discovering services not meant to be exposed.
Solution and Prevention
Problem Analysis
- The application does not validate or restrict the URLs provided by users, allowing requests to internal systems.
Fixing the Vulnerability
- Validate and Sanitize User Input
- Use URL validation to restrict dangerous schemes:
$url = $_GET['url']; if (filter_var($url, FILTER_VALIDATE_URL) && !preg_match('/^(file|gopher|ftp):/', $url)) { $response = file_get_contents($url); echo "<pre>$response</pre>"; } else { die("Invalid URL."); }
- Use URL validation to restrict dangerous schemes:
- Implement Allow-Lists
- Allow only trusted domains:
$allowed_domains = ['example.com', 'trustedsite.com']; $host = parse_url($url, PHP_URL_HOST); if (in_array($host, $allowed_domains)) { $response = file_get_contents($url); echo "<pre>$response</pre>"; } else { die("Access denied."); }
- Allow only trusted domains:
- Block Requests to Internal IPs
- Prevent requests to internal network ranges:
$ip = gethostbyname($host); if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { $response = file_get_contents($url); echo "<pre>$response</pre>"; } else { die("Internal IPs are not allowed."); }
- Prevent requests to internal network ranges:
- Use Network Layer Protections
- Configure firewalls to block outgoing requests to sensitive internal resources.
- Limit HTTP Methods
- Restrict the application to safe HTTP methods (e.g., GET, POST only).
Testing After Fix
- Attempt to fetch
file:///etc/passwd
. - Expected Result:
- The application blocks the request with an error message.
- Attempt to fetch
http://localhost:8080
. - Expected Result:
- The server denies access to internal services.
Conclusion
In this lab, you exploited a Server-Side Request Forgery (SSRF) vulnerability to access internal services and sensitive data. You also learned how to mitigate SSRF by validating input URLs, implementing allow-lists, and restricting internal network access.
0 Comments