如何阻止人们上传带有注射剂的GIF?
我有一个PHP网站,人们可以在其中填写帮助票证。它允许他们上传门票的屏幕截图。我允许上传gif,psd,bmp,jpg,png,tif。收到上传后,PHP 脚本将忽略文件扩展名。它仅使用 MIME 信息标识文件类型,对于这些文件类型,MIME 信息始终存储在文件的前 12 个字节中。
有人上传了几个GIF,当使用浏览器查看时,浏览器说它是无效的,我的病毒扫描程序提醒我这是注射(或类似的东西)。有关包含这些 GIF 的 zip 文件,请参见下文。
我不认为只检查标题信息就足够了。我听说图像可以完全有效,但也包含漏洞利用代码。
所以我有两个基本问题:
- 有谁知道他们是如何将坏东西注入GIF的(同时仍然保持有效的GIF MIME类型)?如果我知道这一点,也许我可以在上传时检查它。
- 如何防止他人上传此类文件?
- 我正在使用共享主机,因此无法安装服务器端病毒扫描程序。
- 将信息提交到在线病毒扫描网站可能太慢。
- 有没有办法使用PHP类来检查我自己,以检查这些东西?
- 如果 GD 图像无效,使用 GD 调整图像大小会失败吗?或者,该漏洞是否仍会滑过并位于调整大小的映像中?如果它失败了,那将是理想的,因为这样我就可以使用调整大小作为一种技术来查看它们是否有效。
更新:大家,感谢您到目前为止的回复。我正在尝试在服务器上查找已上传的GIF。如果我找到它们,我会更新这篇文章。
更新 2:我为任何感兴趣的人找到了GIF。我把它们放在一个用密码“123”加密的zip文件中。它位于此处(请注意,此托管网站上有多个“下载”按钮 - 其中一些用于广告)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);