PHP任意文件上传漏洞
漏洞细节:
这个漏洞存在于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参数的值。
相关文章: