漏洞细节:

这个漏洞存在于php中一个非常常用的函数中:move_uploaded_files,开发者总是用这个函数来移动上传的文件,这个函数会检查被上传的文件是否是一个合法的文件(是否是通过 HTTP 的 post 机制上传的),如果是合法的文件,则将它一定到指定目录中。

例子:

move_uploaded_file ( string $filename , string $destination )
这里的问题是,可以在文件名中插入空字符(之前多次修复过这个漏洞,比如CVE-2006-7243),利用插入空字符的方式,攻击者可以上传任意文件,引起远程代码执行漏洞等。

我这里用DVWA来演示这个例子,DVWA级别最高的一题中因为种种原因不是很容易通过,意在告诉开发者如何去开发更安全的文件上传组件。让我们来看看这个例子:

代码地址:https://github.com/RandomStorm/DVWA/blob/master/vulnerabilities/upload/source/high.php

代码片段:

$uploaded_name = $_FILES['uploaded']['name'];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, '.') + 1); $uploaded_size = $_FILES['uploaded']['size'];
if (($uploaded_ext == "jpg" || $uploaded_ext == "JPG" || $uploaded_ext == "jpeg" || $uploaded_ext == "JPEG") && ($uploaded_size < 100000)){ if(!move_uploaded_file($_FILES['uploaded']['tmp_name'], $target_path)) {
$html .= '';
$html .= 'Your image was not uploaded.';
$html .= ''; }
else {
$html .= $target_path . ' succesfully uploaded!';
.
.

这段代码有好多个漏洞,比如XSCH, XSS等,但是没有RCE这种严重的漏洞,因为从PHP 5.3.1开始,空字符的问题已经被修复了。这里的问题是,DVWA将用户上传的name参数传递给了move_upload_file()函数,那么 php 执行的操作可能就是这样子的:

move_uploaded_file($_FILES['name']['tmp_name'],"/file.phpx00.jpg");
这本应该创建一个名为file.phpx00.jpg的文件,但实际上创建的文件是file.php。

这样,就绕过了代码中对后缀名的校验,并且事实证明GD库中又很多其他函数也存在这个问题(比如getimagesize(), imagecreatefromjpeg()…等),可以看这个例子。

如果你机器的php版本在 5.4.39, 5.5.x – 5.5.23, 或者 5.6.x – 5.6.7,可以通过检查文件名中是否有x00字符来解决本文中所述的问题。

安全建议
如果你的机器上存在这个漏洞,建议使用随机字符串重命名文件名,而不是使用用户上传上来的name参数的值。

转载请注明来自WebShell'S Blog,本文地址:https://www.webshell.cc/4686.html