【问题标题】:Null byte injection in an upload form上传表单中的空字节注入
【发布时间】:2025-12-06 06:00:02
【问题描述】:

我正在尝试在上传表单上重现空字节注入攻击。我有这个代码:

<?php
if(substr($_FILES['file']['name'], -3) != "php") { 
  if(move_uploaded_file($_FILES['file']['tmp_name'], $_FILES['file']['name']))
    echo '<b>File uploaded</b>';
  else
    echo '<b>Can not upload</b>';
}
else
  echo '<b>This is not a valid file/b>';
?>

我正在尝试上传一个像这样命名的文件:file.php%00jpg 所以它将绕过 substr() 并将作为 file.php 上传,因为 move_uploaded_file() 应该停止空字节 (%00)。

问题是上传的文件在服务器上不是命名为file.php而是file.php%00jpg(可以通过输入/ url 栏中的 file.php%2500jpg)。
看来 move_uploaded_file() 并不关心空字节,那么它是如何工作的呢?是否可以使用我的代码上传扩展名为 .php 的文件?

谢谢:)。

【问题讨论】:

  • 有一个更简单的漏洞利用:可以使用不同的“活动”扩展名上传文件,例如.cgi.asp、或.phtml
  • NULL 字节中毒已在 PHP 5.3.4 中修复。
  • 不要使用黑名单上传文件。使用白名单。另外,我可以想到一些简单的方法来解决这个问题。你应该消毒。

标签: php forms security exploit


【解决方案1】:

HTML 表单将文件名 urlencode 为 %2500,而 PHP 再次将其解码为 %00(百分号、零、零)。在任何地方的测试中都没有空字节,您必须使用实际的空字节命名文件(不可能)或手动处理 HTTP 请求,而不是使用 HTML 表单。尽管如此,当前的 PHP 版本不易受到这种攻击,PHP 在内部将变量装箱在所谓的 ZVal 容器中,并允许字符串中间的空字节没有任何影响。

【讨论】: