文件上传漏洞简单总结+白名单+黑名单+内容、头+解析漏洞/修补方案
问题什么是文件上传漏洞?危害?防御措施?文件上传(验证/绕过)措施?前端js类绕过?后端黑名单绕过特殊解析后缀.htaccess解析大小写绕过点绕过空格绕过::$DATA绕过配合解析漏洞(*待补充)双后缀名绕过白名单绕过MIME绕过%00截断0x00截断0x0a截断内容及其他绕过?文件头检测二次渲染条件竞争突破getimagesize突破exif_imagetype漏洞/修补*解析漏洞IIS 6.0/7.XIIS6.0目录解析IIS6.0文件解析IIS6.0默认解析IIS7.0/7.5 PHP FastCGI解析ApacheApache后缀名解析NginxNginx PHP CGI解析问题
之前在学习文件上传漏洞时,只是粗略的了解了一下并没有详细深入去思考问题,这篇博客是自己最近对文件上传漏洞的简单总结和整理,方便自己以后查看,因为文笔较差、技术比较菜,内容引用了多位大佬的文章,外加时间跨度有点长,部分内容有可能没有将大佬原文博客附加,所有希望大佬多多包涵告知,好及时添加;如果内容有错误的地方,还请麻烦指出,万分感谢!
什么是文件上传漏洞?
如果对文件上传路径变量过滤不严,并且对用户上传的文件后缀以及文件类型限制不严,攻击者可通过 Web 访问的目录上传任意文件,包括网站后门文件(webshell),进而远程控制网站服务器。
所以一般需注意:
在开发网站及应用程序过程中,需严格限制和校验上传的文件,禁止上传恶意代码的文件 限制相关目录的执行权限,防范 webshell 攻击
危害?
上传网站后门文件(获取webshell)防御措施?
上传文件的存储位置与服务器分离;上传的文件重新修改文件名、文件后缀名;(如何确定后缀名防止修改:前端传递,后端再校验)文件上传的上传保存路径根据业务进行分离;下载时根据重新生成的文件名进行下载;文件上传(验证/绕过)措施?
前端
js类绕过?
页面直接修改js上传文件方法(添加类型等);抓包改包,将上传的文件后缀进行修改;(例如:a.jsp.jpg ——抓包修改为——a.jsp)复制页面,重新构建新页面,获取方法,并修改;后端
黑名单绕过
Web系统可能会采用黑名单的方式进行过滤。而过滤的方式存在一定的缺陷,比如存在过滤的黑名单不全,未考虑大小写,以及要上传文件的名称存在敏感字符。
基于黑名单验证:只针对黑名单中没有的后缀名,文件才能上传成功。
使用黑名单过滤方式,肯定会存在缺陷;【对上传文件名称进行敏感字符清除。】
特殊解析后缀
很多语言都存在,有多个可以解析后缀。当目标站点采用黑名单时,往往包含不全面;
例如:
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
实际操作:
web站点架构为:php+apache , 保证文件上传到本地 , apache开启对.htaccess支持;
黑名单没有过滤.htaccess
;
编辑.htaccess文件,写入
//1.这将把目录下的shell.jpg的文件当做可执行的php脚本进行解析并执行。[优先]<FilesMatch "shell.jpg">SetHandler application/x-httpd-php</FilesMatch>//2.上传后缀为.aaa的文件,让其做为php类型文件进行解析AddType application/x-httpd-php .aaa
上传一句话木马并以.jpg结尾, 写入<?php @eval($_POST['pass']);?>
菜刀或蚁剑连接,完成!
参考:
参考连接-文章
大小写绕过
背景原因:
后缀名黑名单过滤不全面导致!
虽然设置了黑名单对常见的后缀进行过滤,但并未对后缀名大小写进行统一。可以利用大小写进行绕过。
例如:.phP
示例:
代码只对后缀名为.php
的文件进行了拦截,并未对.pHp
后缀名的文件拦截上传后缀名为.pHp
的文件
点绕过
背景原因:(windows特性)
Windows 系统下,文件后缀名最后一个点会被自动去除。
Linux 系统下,文件后缀名最后一个点不会被自动去除。
利用 BurpSuite 工具截断 HTTP 请求,上传文件后缀名加.
绕过上传。
使用条件:
只能在Windows系统下方能生效;
利用示例:
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::$DATA
Windows会自动去掉末尾的::$DATA变成phpinfo.php
利用示例:
通过BurpSuite截断 HTTP 请求之后,在对应的文件后缀名处添加::$DATA
。
a.php::$DATA
特别说明:
在windows下,无法直接测试::$DATA,因为windows不允许后缀名中存在特殊字符;
配合解析漏洞(*待补充)
双后缀名绕过
背景原因:
文件上传过滤代码,会将文件名称进行敏感字符清除。
文件上传过滤代码,后缀名黑名单过滤不全面导致!
例如:如果上传的代码后缀名为.php
,那么就将后缀名舍弃;如:a.php——>a
;
利用示例:
对要上传的文件添加重复后缀名,如:a.php——>a.p
phphp
过滤掉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/*") @ResponseBodypublic 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中%00表示ASCII码中的0 ,而ascii中0作为特殊字符保留,表示字符串结束*,所以**当url中出现%00时就会认为读取已结束。
例如:
就绕过了后缀限制,可以上传webshell啦。
利用示例:
一、前端使用%00截断
打开BurpSuite抓包工具,找到上传文件后缀名位置;
**%00截断百分之百绕过前端校验;**例如:a.php%00.jpg
在上传文件后缀名处,直接用%00就可以了。示例:a.php%00.jpg
某些情况下,直接在文件名中加 %00 进行截断不生效无法起到相应的作用,因为 %00 会以字符串的形式解析了。(不认为是空(NULL)字符,认为只是普通拼接的字符串);
解决方法如下:
是我们需要对 %00 做一个URL解码,也就是URL-decode;(在BurpSuite内选中%00右键convent selection——>URL——>URL-decode)通过 burpsuite修改 hex 值为 00 (URL decode)进行截断;
为什么两者用法不同?
这是因为%00 截断在 GET 中被 url 解码之后是空字符。但是在 POST 中 %00 不会被 url 解码,所以只能通过 burpsuite 修改 hex 值为 00 (URL decode)进行截断。
如果是存在后端校验;%00截断只能绕过前端校验,达不到预想结果;
二、后端使用%00路径截断(后端校验一般为后缀名,考虑%00截断文件路径)
如果在Burp中直接改filename,根本无法起作用,因为截断的只是后缀名,只能绕过简单的前端验证,如果遇到后端校验,在提取上传文件后缀的时候后缀还是.php,肯定会被拦,也就是说这里00截断没有发挥任何“绕过”后端验证的作用。知道了基本原理之后,我们还要分析它怎么起作用,如果按照上述的做法来做,则00绕过只能绕过前端验证,因为如果是后端验证,那么即使后缀被截断了,处理之后为.php,还是会被后端验证拦截,所以不是什么情况下00截断都有用的,不过这里至少可以确定,在绕过前端验证可以用。在文件名中插入空字符进行00截断,只适合前端绕过,后端绕过无效。
这里想绕过,必须要知道文件上传的条件:1.后缀检测,合格则进行上传路径拼接 2.拼接路径和文件名,组成文件上传路径
参考连接:
文件上传绕过之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
文件头代码拦截示例:
文件上传接口,读取文件,并将文件转为输入流;截取文件流的前四个字节,并将其转成16进制,并转为大写比较截取的字符与常见的文件类型头部字符进行比对,返回文件的类型正常通过,存在异常则报错;
文件头利用示例:
方法一:
先将一句话木马写入txt文件,改文件后缀为png格式;用winhex打开,找到你所改成图片的文件头(例如我想改成的是png格式,也可以jpg等,png图片的格式头是89504E47),只要将其放在文件头部(也就是放在一句话的前面),保存即可。上传,用bp抓包,然后修改文件后缀为.php格式,放包即可,用蚁剑连接即可。
方法二:
准备一个要上传的图片;一个一句话木马.php
执行命令:
## CSDN.png 为要上传的图片【必须加/b】;## 1.php 为一句话木马【必须加/a】;## phpinfo 为重新定义的文件名;copy CSDN.png/b+1.php/a phpinfo.png
上传图片!
方法三:
BurpSuite抓包上传文件时,部分上传功能代码会展示文件流输出直接在文件流的最前方,添加文件头(png格式文件头,jpg格式文件头)
doc、pdf、excel文件头木马写入:
准备word文档.doc
+.exe
木马文件
执行命令
copy CSDN.doc/b + 1.exe/a phpinfo.doc
发送给朋友;
参考链接引用:
【知识点】文件头部校验spring boot案例
图片写入一句话木马
编写WORD木马
二次渲染
出现的原因:
处于安全方面的考虑,不信任用户输入、上传的任何数据、图片;因此,对于用户上传的图片等信息,都需要开发人员对图片文件重新生成!;这就是防止图片中参杂恶意代码的防御措施;(即,对图片文件流,只保留可以生成图片的最基本部分,其他地方舍弃!)
二次渲染意义:
二次渲染过滤掉图片中掺杂的恶意代码
二次渲染利用方式:
结合文件包含漏洞利用
二次渲染绕过方式:
.gif绕过
将包含恶意代码的图片phpinfo.gif
,上传到服务器;服务器上传图片功能代码,对图片进行过滤,只保存最基本的部分,并返回到前端页面展示;下载上传后的图片,并用winhex.exe
打开,发现图片末尾处的一句话木马消失;使用winhex对比功能,找到原图片与上传后图片的相同之处,并在该位置插入恶意代码;实际操作:winhex——》工具——》比较——》搜索相同;展示区,蓝色部分是没有发生变化的,在图片相同处,蓝色部分位置中间插入恶意代码,并上传,成功绕过;
.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】
产生原因:
例如创建目录wooyun.asp,那么**/wooyun.asp/1.jpg**将被当作asp文件来执行。假设可以控制上传文件夹路径,就可以不管你上传后你的图片改不改名都能拿shell了。在网站下建立文件夹的名字为 .asp、.asa 的文件夹,其目录内的任何扩展名的文件都被IIS当作asp文件来解析并执行。
IIS6.0文件解析
【wooyun.asp;.jpg】
产生原因:
在IIS6.0下,分号后面的不被解析,也就是说wooyun.asp;.jpg,会被服务器看成是wooyun.asp。
IIS6.0默认解析
/wooyun.asa/wooyun.cer/wooyun.cdxIIS6.0 默认的可执行文件除了asp后缀名外,还包含这三种
链接引用:
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和FastCGIFastCGI
知识准备:如何让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--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】文件,通过并执行?需要配置那些东西?
方式一:
Apache多后缀名的解析规则特性,本身就可以正常解析【a.php.qwer】文件,不需要修改任何东西;
方式二:
开启.htaccess文件(参考黑名单绕过,.htaccess解析)上传.htaccess文件,添加可解析后缀.qwer
添加可解析后缀名.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服务漏洞详解