我有一个PHP的网站,人们可以填写帮助门票。 这使他们能上传截图为他们的票。 我让GIF,PSD,JPG,BMP,PNG,TIF上传。 一旦接收到上传,PHP脚本忽略文件扩展名。 它确定仅使用MIME信息,这对于这些文件类型总是被存储的前12个字节的文件内的文件类型。
有人上传一些GIF格式,它与浏览器中查看时,浏览器会说,这是无效的,我的病毒扫描程序提醒我,这是一个注射(或类似的东西)。 见下文包含这些GIF格式的压缩文件。
我不认为只有在检查的头信息是足够的。 我听说的图像可以是完全有效的,但也含有攻击代码。
所以,我有两个基本问题:
- 有谁知道他们是如何注入坏的东西成GIF( 同时仍保持有效的GIF MIME类型 )? 如果我知道这一点,也许我可以在上传时进行检查。
- 我怎样才能阻止上传这样的文件的人?
- 我在共享主机,所以我不能安装一个服务器端的病毒扫描程序。
- 提交信息到在线病毒扫描网站可能太慢。
- 有没有什么办法来检查自己使用PHP类,检查这些东西呢?
- 会使用,如果它不是有效的GD无法调整图像大小? 或将在漏洞仍然漏网之鱼,并调整大小后的图像中? 如果失败,那将是理想的,因为这样我可以使用调整大小作为一种技术,看看它们是否有效。
更新:每个人,感谢到目前为止答复。 我试图寻找在服务器上上载的GIF文件。 如果我找到他们,我会更新这个帖子。
更新2:我所在的GIF兴趣的人。 我把它们放在密码是“123”加密的压缩文件。 它坐落在这里(小心有关于这个托管网站多个“下载”按钮-其中一些是广告) http://www.filedropper.com/badgifs 。 所谓5060.gif的一个是由我的防病毒为木马(TR / Graftor.Q.2)标记。 我要指出的是,这些文件被我之前上传执行前12个字节的MIME检查。 所以,现在,我为这些特定的人的安全。 但我还是想知道如何检测的漏洞隐藏着一个正确的MIME类型后面。
重要说明: 我只关心的风险,谁下载这些文件,看他们的PC。 该文件是不是我的服务器的风险。 他们不会被执行。 他们用的是干净的域名(十六进制散列输出)以“.enc”扩展存储,我使用fwrite的过滤器将它们保存到磁盘加密状态:
// Generate random key to encrypt this file.
$AsciiKey = '';
for($i = 0; $i < 20; $i++)
$AsciiKey .= chr(mt_rand(1, 255));
// The proper key size for the encryption mode we're using is 256-bits (32-bytes).
// That's what "mcrypt_get_key_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC)" says.
// So we'll hash our key using SHA-256 and pass TRUE to the 2nd parameter, so we
// get raw binary output. That will be the perfect length for the key.
$BinKey = hash('SHA256', '~~'.TIME_NOW.'~~'.$AsciiKey.'~~', true);
// Create Initialization Vector with block size of 128 bits (AES compliant) and CBC mode
$InitVec = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC), MCRYPT_RAND);
$Args = array('iv' => $InitVec, 'key' => $BinKey, 'mode' => 'cbc');
// Save encoded file in uploads_tmp directory.
$hDest = fopen(UPLOADS_DIR_TMP.'/'.$Hash.'.enc', 'w');
stream_filter_append($hDest, 'mcrypt.rijndael-128', STREAM_FILTER_WRITE, $Args);
fwrite($hDest, $Data);
fclose($hDest);
对于第一个问题 ,你永远不会真正知道,如果你不能够检索任何记录或有问题的图像,因为有很多事情,这些漏洞可以有针对性,并根据有什么目标的攻击方式被提进入该文件可以是完全不同的。
编辑:W32 / Graftor是一个通用名称的,似乎有木马般的特性计划。
打开该文件后5060.gif
在十六进制编辑器,我发现这个程序实际上是一个改名为Windows程序 。 尽管这不是一个浏览器的漏洞,从而无害,除非它实际上是打开并执行,你必须确保它不与上传定义MIME类型提供服务,因为用户可能仍然被欺骗,打开程序; 一看便知第二个问题。
至于第二个问题 :防止从任何正在运行或用户的攻击代码,你必须确保所有的文件都存储在文件名,使他们与正确的MIME类型提供一个安全的扩展。 例如,你可以使用这个正则表达式来检查文件名:
if(!preg_match ( '/\\.(gif|p(sd|ng)|tiff?|jpg)$/' , $fileName)){
header("415 Unsupported Media Type");
die("File type not allowed.");
}
另外,还要确保你的服务与正确的内容类型的文件; 请确保您不使用服务的文件给用户当与上传文件中指定的内容类型。 如果你依赖于上传指定的内容类型,该文件可能担任text/html
或任何类似,将由用户的浏览器等进行解析。
请注意,这只是防止恶意文件利用在用户的浏览器的漏洞,图像分析器排除。
如果你想阻止针对服务器的攻击,你必须确保你不会让PHP解析器执行图像的内容,您正在使用处理图像的图像库中没有任何已知漏洞。
另外请注意,此代码不会保护你对包含漏洞利用通过用户的浏览器中使用的图像解析图像; 防范这一点,你可以检查getimagesize()
由吉荣的建议计算结果为true。
请注意,使用getimagesize()
单独是不够的,如果你不检查文件名,并确保文件送达正确Content-Type
头,因为完全有效的图像可以嵌入到HTML的意见/ PHP代码。
您可以使用和getimagesize()函数这一点。 如果图像是无效的,将简单的返回false
。
if (getimagesize($filename)) {
// valid image
} else {
// not a valid image
}
值得一提的是,这不是100%安全要么,但它可以为据我所知做到最好。
了解更多关于此这里 。
您可以尝试在接受上传任意PHP脚本phpMussel。 该文件将使用ClamAV的签名,加上寻找这种类型的入侵明确一些内部的启发式签名扫描。
我不知道很多关于图像格式,但重现图像,然后存储结果,我觉得有消除不必要的棘手的问题的一个很好的机会。 特别是如果你去除所有这样的评论和所有其他类型的一些图像格式支持可选的嵌入式领域的元数据。
1)你永远不会知道问题是什么,如果你删除的.gif和您的A / V没有写日志。
问:有问题.gif文件仍然在服务器上?
问:你检查你的A / V日志?
2)有许多不同的可能的攻击,这可能会或可能不会有什么,直接做的.gif文件格式。 下面是一个例子:
- http://www.phpclasses.org/blog/post/67-PHP-security-exploit-with-GIF-images.html
3)为了减轻在这个例子中的风险,你应该:
a)只有上传文件( 任何文件)到一个安全的目录服务器上
b)只有满足特定后缀(.GIF,.PNG等文件)
c)为有关影片上传到您的网站(特别是如果你然后让其他人从您的网站下载任何东西极其偏执!)
在非常有用的提示,以防止注射PHP的问题从我的主机的系统管理员来了:我有一个网站,人们可以上传自己的内容。 我想,以确保在那里上传的图片是从供应不运行任何PHP目录。 有人这样甚至可以发布一个名为“test.php的”图片,它将仍然没有被PHP解析,如果它是在上载目录。 解决办法很简单:在文件夹上载的内容是从把下面.htacess服务:
RewriteEngine On
RewriteRule \.$ - [NC]
php_flag engine off
这将关闭PHP引擎的文件夹,从而阻止任何企图发动任何PHP利用服务器端的漏洞。
反应迟缓,但可能是别人有用。 您可以尝试这样的做法:
//saves filtered $image to specified $path
function save($image,$path,$mime) {
switch($mime) {
case "image/jpeg" : return imagejpeg(imagecreatefromjpeg($image),$path);
case "image/gif" : return imagegif(imagecreatefromgif($image),$path);
case "image/png" : return imagepng(imagecreatefrompng($image),$path);
}
return false;
};