是否可以在图像文件中执行 php 脚本?

信息安全 Web应用程序 php 网络服务器
2021-08-18 18:02:39

我有一个图片上传 php 网站。用户可以将图像上传到我的网站。一位用户声称他可以使用上传的图片入侵我的网站。

我用记事本打开了他上传到我服务器的所有图像。一张图片的最后一行是:

Àpa@ ;
<?php

echo "test ok";
?>

他可以使用这张图片破解我的网站吗?如何防止用户上传这样的图像?

3个回答

是的,如果配置不正确,您的服务器可以在图像文件中运行 PHP 代码

http://www.phpclasses.org/blog/post/67-PHP-security-exploit-with-GIF-images.html

一个例子是image.gif.php一个文件既可以是有效的图像也可以是有效的 PHP 脚本,仅检查图像大小或其他属性是不够的。剥离元数据也不够,未压缩的 GIF 可以包含 PHP 作为图像数据(虽然它可能不漂亮),PNG 支持任意数据块

该缺陷是接受没有足够健全性检查的上传,特别是试图.php通过使用非锚定正则表达式\.(png|gif|jpg|jpeg)(无$锚)来防止不需要的文件名(例如),允许从启用 PHP 处理的目录提供这些图像。最佳实践是您可能永远不应该按原样使用用户提供的文件名。

这些是相当经典的数据验证输入验证失败。

如果您遵循PHP 安装说明(针对 Apache 2),您的 Apache 配置中会出现类似的内容:

<FilesMatch "\.ph(p[2-6]?|tml)$">
    SetHandler application/x-httpd-php
</FilesMatch>

注意$锚点,它将防止file.php.gif被 PHP 解释。(这些说明中缺少的是确保 PHP 受到<Directory>仅包含受信任代码的上下文的限制,并且Web 服务器用户不可写入。)

如果您不遵循这些说明,请改用mod_mime's AddType(或AddHandler):

AddType application/x-httpd-php .php      # STOP! 

这可能会导致相同的问题,因为可能会使用多个扩展mod_mime做一些您不期望的事情。请参阅http://blog.dynom.nl/archives/Be-careful-with-double-extensions_20081024_25.html(感谢Hendrik Brummermann指出这一点)。这种风险可以通过正确配置<Directory>的上下文来减轻,以仅允许受信任的代码。

该文档 (PDF) 有点旧,但它很好地涵盖了缓解措施:http: //www.net-security.org/dl/articles/php-file-upload.pdf

另一个可能的问题来源是不安全的include/require语句(也包含在该 PDF 中),它允许攻击者include通过更改查询字符串或 HTTP 请求标头来上传内容。

另请参阅最近的相关问题:PHP 图像上传表单的风险 (尽管我认为依靠getimagesize验证图像是不正确的),以及 使用 PHP 检查上传的图像文件是否存在恶意软件?(其中包含一组有用的链接)。

图像上传(通常是任何文件)很难保证完全安全——尤其是在 PHP 中,它提供了许多攻击向量。

例如,如果您通过调用显示图像

require($someImage);

并且该图像内部包含 PHP 代码(就像您发布的那样),它可以被解释和执行。

我的猜测是,如果他声称他拥有您的网站,他很可能拥有。您提供的图像本身除了打印“test ok”外不会做任何事情,但是该代码可以很容易地交换为一些未经授权(甚至完全不受限制)访问您的站点和服务器的代码。

为确保上传到您网站的文件实际上是图像,请使用 GD(或 Imagick)对其进行重新处理,然后保存处理后的图像。保存原始图像是不好的做法,尤其是使用原始文件名,因为这会引发许多其他攻击(例如目录遍历和文件覆盖)。

更多信息:https ://www.owasp.org/index.php/Unrestricted_File_Upload

我将假设您正在运行 LAMP(其他 php 设置的答案将非常相似)。


最有可能的是,他的代码无法对您的站点做任何事情

假设 Apache/var/www在您的服务器上提供文件。假设有人访问index.php您的网站。

  1. Apache 将收到他们正在寻找的信息 /index.php
  2. Apache 将查找该文件 /var/www/index.php
  3. 如果 Apache 正在运行 mod_php,那么它将index.php以某种方式检查是否匹配 mod_php 配置文件中的规则。您的 mod_php 配置文件(可能位于/etc/apache2/mods-available/php5.conf)很可能是我在下面创建的这个最小示例的超集:

    <IfModule mod_php5.c>
        <FilesMatch ".+\.ph(p[345]?|t|tml)$">
            SetHandler application/x-httpd-php
        </FilesMatch>
    </IfModule>
    
    • 如果文件名匹配,则 Apache 将通过 php 解释器运行该文件,创建一个网页,并将其提供给用户。
    • 如果文件名不匹配,则 Apache 只会将其提供给用户。
    • (这些细节跳过了很多我认为在这里不相关的 apache)

假设用户上传了一张图片,例如evil_image.png,其中包含任意 PHP 代码。

还假设您从某个地方(例如在/images/evil_image.png您的文件系统中/var/www/images/evil_image.png)将其提供给用户。

当有人试图通过访问您的网站来检索此图像时/images/evil_image.png,Apache 将执行我上面概述的步骤。在第 3 步,/images/evil_image.png 将不匹配配置文件中的模式,因此您不会将代码作为 php 执行您只需将图像提供给用户。

用户将收到其中存储有恶意制作的文本的图像文件。重要的是您的服务器没有尝试执行代码,使其无效


我并不是说该代码不可能被执行。我会告诉你,你需要非常想念配置你的 web 服务器才能使代码被执行。