Lak*_*key 18 php security gd image-processing code-injection
我有一个PHP网站,人们可以在那里填写帮助票.它允许他们上传票证的屏幕截图.我允许上传gif,psd,bmp,jpg,png,tif.收到上载后,PHP脚本将忽略文件扩展名.它仅使用MIME信息标识文件类型,对于这些文件类型,它始终存储在文件的前12个字节中.
有人上传了几个GIF,当用浏览器查看时,浏览器说它无效,我的病毒扫描程序提醒我这是注射(或类似的东西).请参阅下面的包含这些GIF的zip文件.
我认为只检查标题信息是不够的.我听说图像可以完全有效,但也包含漏洞利用代码.
所以我有两个基本问题:
更新:大家,谢谢你的答复到目前为止.我试图在服务器上查找上传的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);
Run Code Online (Sandbox Code Playgroud)
至于第一个问题,你永远不会真正知道你是否无法检索任何日志或相关图像,因为这些漏洞利用可能有许多目标,并且取决于挖掘漏洞的目标是什么进入文件可以完全不同.
编辑: 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.");
}
Run Code Online (Sandbox Code Playgroud)
还要确保您使用正确的内容类型提供文件; 确保在向用户提供文件时不使用上载文件指定的内容类型.如果您依赖上传者指定的Content-Type,则该文件可以作为text/html或类似的文件提供,并且将由用户的浏览器进行解析.
请注意,这仅防止恶意文件利用用户浏览器中的漏洞,图像解析器被排除在外.
如果你试图阻止对服务器的攻击,你必须确保你不会让PHP解析器执行图像的内容,并且你用来处理图像的图像库没有任何已知的漏洞.
另请注意,此代码不会保护您免受包含用户浏览器使用的图像解析器漏洞利用的图像的影响; 为了防止这种情况,您可以检查getimagesize()Jeroen建议的评估结果是否为真.
请注意,getimagesize()如果不检查文件名并确保使用正确的Content-Type标头提供文件,单独使用是不够的,因为完全有效的图像可以在注释中嵌入HTML/PHP代码.
| 归档时间: |
|
| 查看次数: |
4514 次 |
| 最近记录: |