文件上传解析漏洞

摘要:
上传漏洞镜像王玉阳2019年10月28日,该网站通常会上传文件。只要上传功能存在,就可能存在上传漏洞危机。与SQL注入漏洞相比,上传漏洞更危险,因为它可以直接将WebShell上传到服务器。利用此功能还可能导致“文件解析漏洞”。文件上载格式错误错误“;exit;}”?
上传漏洞

Mirror王宇阳

2019年10月28日

Web网站通常存在文件上传(例如:图片、文档、zip压缩文件^等)只要存在上传功能,就有可能会有上传漏洞的危机。和SQL注入漏洞相比较而言,上传漏洞更加危险,因为该漏洞可以直接上传一个WebShell到服务器上。

解析漏洞

利用上传漏洞,通常需要结合Web容器(IIS、Nginx、Apache、Tomcat)的解析漏洞来让上传的漏洞得到实现

IIS解析漏洞

IIS5.x/IIS 6.0文件解析漏洞

  • 目录名中含有.asp字符串的(目录下)均按照asp文件进行解析;例如:index.asp/目录中的所有文件都会asp解析

    当出现xx.asp命名的文件名,访问目录下任意一个文件,均会送给asp.dll解析(执行asp脚本)

  • 文件名中含有.asp;字符,即使时jpg格式文件,IIS也会按照asp对文件进行解析

    当文件名xx.asp;xx.jpg,IIS6会将文件送给asp.dll解析(按照asp脚本解析);

    请求时:IIS从左往右检查.号,查询到;/号则(内存)截断;如此执行后,IIS认识的就是xx.asp

  • 默认解析:.asa.cer.cdx IIS6 同时默认解析前面三个文件后缀,都会给asp.dll解析

  • 修复方案:

    设置权限,限制用户创建、修改文件夹权限

    更新微软的补丁或者自定义修改IIS的检测规则,阻止上传非法的文件名后缀

IIS7.0/7.5

  • 默认开启 Fast-CGI 状态,在一个服务器文件URL地址后面添加xx.php会将xx.jpg/xx.php解析为PHP文件

  • 修复方法:

    修改php.ini文件,将cgi.fi: x_pathinfo设置为 0

    IIS7的解析漏洞主要是由于PHP的配置不当导致的

    Windows操作系统中,文件名不能以空格或“.”开头,也不能以空格或“.”结尾。当把一个文件命名为以空格或“.”开头或结尾时,会自动地去掉开头和结尾处的空格和“.”。利用此特性,也可能造成“文件解析漏洞”。

Nginx解析漏洞

Nginx <= 0.8.37

影响版本:0.5/0.6/<0.7.65/<0.8.37

  • Fast-CGI开启状态下,存在如同IIS7一样的漏洞:URL地址后面添加xx.php会将xx.jpg/xx.php解析为PHP文件

    空字节:xx.jpg%00.php (部分版本中,Fast-CGI关闭下也会被执行)

  • 修复方法:

    修改php.ini文件,将cgi.fix_pathinfo设置为 0 [关闭]

    再Nginx配置中设置:当类似xx.jpg/xx.php的URL访问时候,返回403;

    if ( $fastcgi_script_name ~ ..*/.*php) {
    	return 403 ;
    }
    

Apache解析漏洞

Apache后缀名解析漏洞

  • Apache解析文件的规则时从右到左开始判断,如果后缀名为不可识别文件解析,则会继续向左判断,直至可以正确识别

    xxx.php.owf.zip 其中.owf.zip文件后缀Apache不识别,直至判断.php才会按照PHP解析文件

  • 修复方法:

    Apache配置中,禁止xx.php.xxx类似的文件执行

    <Files ~ "/.(php.|php3.)">
    	Order Allow,Deny
    	Deny from all
    </Files>
    

Apache"%0A"绕过上传黑名单 [CVE-2017-15715]

  • Apache中存在一个上传的判断逻辑:(自定义)

    <?php
        if(isset($_FILES['file'])){
            $name = basename($_POST['name']);
            $ext = pathinfo($name,PATHINFO_EXTNSION);
            if(in_array($ext,['php','php3','php4','php5','phtml','pht'])){
                exit("bad file");
            }
            move_uploaded_file($_FILES['file']['tmp_name'],'./'.$name);
        }
    ?>
    

    判断检查上传文件的后缀名,如果发现了,就进行拦截。

    利用CVE-2017-15715,上传一个包含换行符的文件。注意,只能是x0A,不能是x0Dx0A,所以我们用hex功能在1.php后面添加一个x0A

15223122857686.jpg

​ 访问/1.php%0A,即课成功getShell;

文件上传绕过

客户端校验

  • 客户端使用JavaScript检查上传文件的后缀名

    # js验证文件后缀
    extArray = new Array('.gif','.jpg','.png'); // 白名单
    function LimitAttach(form,file){
        allowSubmit = false;
        if(!file)
            return;
        while(file.indexOf('\')!=-1)
        file = file.slice(file.indexOf('\')+1);
        ext = file.slice(file.indexOf('.')).toLowerCase();
        for(var i = 0 ; i < extArray.length ; i++){
            if(extArray[i] == ext){
                allowSubmit = true ; 
                break ;
            }
        }
        if(allowSubmit)
            form.submit();
        else
            alert("bad Extension");
    }
    

    一般情况可以通过抓包绕过客户端的 js校验

    # php接收文件(没有任何校验)
    <?php
    	if(isset($_POST['submit'])){
            $name = $_FILES['file']['name']; //文件名
            $naem = md5(date('Y-m-d h:m:s')).strrchr($name,'.');// 文件重命名保留扩展
            $size = $_FILES['file']['size']; //文件字节大小
            $tmp = $_FILES['file']['tmp_name']; //临时路径
            move_uploaded_file($tmp,$name); //移动文件到tmp目录下
            echo '文件上传成功'.$name;
        }
    ?>
    
  • 绕过客户端校验:

    使用FireBug开发者工具,在本地构造一个可以越过触发校验函数即可提交表单的内容;让校验函数不被调用即可绕过。

    另外也可以通过抓包方式在通过客户端校验后修改数据包的内容。(改包过程中可能会改动数据包的大小,需要留意Content-Length定义的长度要与实际相符)

服务端校验

  • Content-type字段校验(MIME类型校验

  • 文件扩展名检测(检测文件Extension相关的内容)采用黑白名单过滤的机制

  • 文件内容体检测(检测内容是否合法或者恶意代码)

  • 目录验证

MIME校验:Content-type

  • Content-type字段显示文件的MIME类型,判断MIME类型可以对文件做简单的过滤

    # 校验Content-type字段MIME类型
    <?php
        if($_FILES['file']['type'] != 'image/jpeg'){  // 判断文件的MIME格式
            echo "Sorry!文件上传格式错误 Error";
            exit;
        
        }
    ?>
    
  • 绕过MIME校验:

    利用Burp抓包工具,将content-type字段改为需要的MIME类型

扩展名检测

  • 黑名单策略:

    存在一个专门的文件,记录服务器不允许上传的文件名

  • 白名单策略:

    存在一个专门的文件,记录服务器允许上传的文件名

    # 扩展名检测
    <?php
        if(isset($_POST['submit'])){
            $name = $_FILES['file']['name']; // 获取文件名
            $ext = substr(strrchr($name,"."),1); //获取扩展名[strrchr()找到符号"."并返回从该位置到结尾的所有字符(字符串),substr(str,1)获得扩展名字符串]
            while($ext==xxx){}
            // 调用黑白名单进行循环对比,一旦命中则执行相关的放过/拦截操作!
        }
    ?>
    

目录验证

  • 让上传的文件存储在一个统一的目录

    # 目录验证
    <?php
        if(isset($_POST['submit'])){
            $name = $_FILES['file']['name']; //文件名
            $naem = date('Y-m-d h:m:s').strrchr($name,'.');// 文件重命名保留扩展
            $tmp = "./root/"; //存储路径,可以是服务器指定或者用户原则或则机制选择
            move_uploaded_file($tmp,$name); //移动文件到tmp目录下
        }
    ?>
    

服务器校验文件实例代码

<?php
	if(isset($_POST['submit'])){
		$name = $_FILES['file']['name'] ;
		$type = $_FILES['file']['type'] ;
		$tmp = "./image/";
	}
	
	file_array = new array('jpeg','png','jpg','gif');// 白名单
	for ($i=0; $i < file_array.length; $i++) {
		if (substr(strrchr($name, "."),1) == file_array[i]) {
			if( $type == "image/gif" | $type == "image/jpeg" ){

				move_uploaded_file($tmp, $name);
                echo "图片上传成功……".$name;
				exit;
			}
		}
	}
?>

绕过策略

  • burp抓包改包,绕过校验机制,再利用包含漏洞进行getShell

文本编辑器上传漏洞

常见文本编辑器:FCKEditor、Ewebeditor、UEditor、KindEditor、XHditor;合俗称“富文本编辑器

笔者接触文本编辑器不多,贡献一个不错的参考文章: https://blog.yuntest.org/jszy/stcs/91.html

免责声明:文章转载自《文件上传解析漏洞》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇OSG安装编译关于文件中的0D、0A下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

linux学习9 运维基本功-Linux常用基础命令实战应用

一、文件系统知识回顾 1、Linux文件系统: a、文件名称严格区分字符大小写 b、文件可以使用除/以外任意字符 c、文件名长度不能超过255个字符 d、以.开头的文件为隐藏文件: . :当前目录 .. :当前目录的上一级目录 2、linux目录 a、工作目录:working directory b、家目录 二、常用命令 1、pwd:printing wo...

Apache Shiro快速如门教程

第一部分 什么是Apache Shiro    1、什么是 apache shiro :   Apache Shiro是一个功能强大且易于使用的Java安全框架,提供了认证,授权,加密,和会话管理 如同 Spring security 一样都是是一个权限安全框架,但是与Spring Security相比,在于他使用了和比较简洁易懂的认证和授权方式。  ...

Mac usr/bin 目录 权限问题

Mac进行 usr/bin 目录下修改权限问题,operation not permitted 一般情况下我们在使用mac系统过程中下载一些文件、新建一些项目之后,这些文件都会默认是只读状态,这时我们只需要简单的一句权限设置命令就可以解决 sudo chmod -R 777 你要修改文件上层目录的路径 但是我们在对 usr/bin 目录下的文件进行操作的时...

Flume内存溢出错误

java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOf(Arrays.java:2367) at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.ja...

android中的内部存储与外部存储

我们先来考虑这样一个问题: 打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的时候又是清除的哪里的数据?读完本文相信你会有答案。 在android开发中我们常常听到这样几个概念,内存,内部存储,外部存储,很多人常常将这三个东西搞混,那么...

VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径

说明 $(RemoteMachine) 设置为“调试”属性页上“远程计算机”属性的值。有关更多信息,请参见更改用于 C/C++ 调试配置的项目设置。 $(References) 以分号分隔的引用列表被添加到项目中。 $(ConfigurationName) 当前项目配置的名称(例如“Debug”)。 $(PlatformName) 当前项目平台的名称(例...