文件上传漏洞限制绕过总结

Author:zusheng

Link:http://www.isbase.cc

0x01 前言

在如今的合法渗透测试中,我们已经很难遇到不受限制的文件上传功能了。现在是不是就没有文件上传漏洞存在了呢,然后事实并非如此,往往我们可以绕过某些文件上传限制。本文就将研究Web应用程序如何处理文件上传过程以及如何验证上传文件的合法性,从而讨论如何绕过这些验证。

PHP文件上传关键函数:move_uploaded_file()

0x02 客户端过滤

客户端验证是在我们输入发送到服务器之前进行的验证,它通过JavaScript、VBScript或者HTML5在浏览器上进行验证。一般这种验证可以给用户更好的体验,提高了响应速度。

例如:

<script>
     var _validFileExtensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"];
     function filter()
     {
         var files = document.getElementsByTagName("input");
        for(var i=0;i<files.length;i++)
        {
            var oinput = files[i];
            if(oinput.type == "file"){
                var sfilename = oinput.value;
                if(sfilename.length>0)
                {
                    var verify = false;
                    for(var j=0;j<_validFileExtensions.length;j++)
                    {
                        var sFileExtension = _validFileExtensions[j];
                        if(sfilename.substr(sfilename.length-sFileExtension.length,sFileExtension.length).toLowerCase() == sFileExtension.toLowerCase())
                        {
                            verify = true;
                            break;
                        }
                    }
                    if(!verify)
                    {
                        alert("违规文件上传");
                        return false;
                    }
                }
            }
        }
        return true;
     }
</script>

这里在客服端使用了JavaScript进行验证,限制只能上传jpg、jpeg、bmp、gif、png文件。

当我们试图上传一个php文件时遭到了拒绝。

客户端过滤绕过

方法1:安装浏览器插件关闭JS脚本

Chrome浏览器插件ScriptBlock

方法2:修改文件后缀名为合法上传,然后使用Burp截取修改

0x03 文件名过滤

文件名过滤是指服务器验证正在上传的文件扩展名,这个验证有很多方法,但是现在最常用的方法有两种。一种是基于黑名单验证,另一种是基于白名单验证。

黑名单方式是拒绝上传存在于黑名单中扩展名的文件,如php、aspx。白名单方式是只允许上传存在于白名单中的文件扩展名,如jpg、png、gif。

基于黑名单的文件名过滤绕过

1、上传不常见的PHP扩展名来绕过黑名单

pht, phpt, phtml, php3,php4,php5,php6

2、文件名过滤时忽略了大小写

pHp, Php, phP

3、解析漏洞

例如Apache和IIS解析漏洞

基于白名单的文件名过滤绕过

1、空字节注入

shell.php%00.png

2、双写扩展名

shell.jpg.php

0x04 Content-Type和文件头过滤

Content-Type过滤

Content-Type过滤是指服务器通过检查文件的MIME类型来决定上传是否被通过。例如我们上传一张图片时。

针对这种情况绕过方法也很简单,使用Burp截断,然后修改Content-Type为正常图片类型就可以了,例如修改为image/jpeg。

PHP关键函数:mime_content_type()

文件头过滤

文件头过滤主要是通过验证图片的文件头的方式来判断是不是图片文件。

例如GIF图片的文件头就是GIF89a。

PNG文件头

针对这种情况绕过也很简单,在要上传文件的文件头里面加上图片文件头就可以了。

PHP关键函数:getimagesize()

0x05 超短shell

在某些时候,服务器对上传文件的大小限制很大,这时候我们就需要把shell代码缩短至极限。

<?=`$_GET[x]`?>

这里利用的是PHP命令执行的特性。`号内会被当做命令执行。