文件上传漏洞
文件上传漏洞
判断流程
绕过方式:
客户端js检测绕过攻击
- 抓包修改后缀
- 更改客户端js
文件类型绕过
Content-Type类型改为:image/jpeg
后缀绕过
.htaccess
黑名单无过滤.htaccess
上传.htaccess
内容为:
1 | #能够解析.php .phtml .phps .php5 .pht |
.user.ini
借助.user.ini
轻松让所有php文件都“自动”包含某个文件,而这个文件可以是一个正常php文件,也可以是一个包含一句话的webshell
1 | auto_prepend_file=1.png |
user.ini.
它比.htaccess
用的更广,不管是nginx/apache/IIS,只要是以fastcgi运行的php都可以用这个方法。
条件:
服务器脚本语言为PHP
对应目录下面有可执行的php文件,如index.php
服务器使用CGI/FastCGI模式
常用绕过后缀
1 | PHP: |
%00截断
0x00是字符串的结束标识符,攻击者可以利用手动添加字符串标识符的方式来将后面的内容进行截断,而后面的内容又可以帮助我们绕过检测
利用条件
1 | 1.php版本<5.3.4(不包括5.3.4) |
错误使用
在文件名后直接%00
截断,是错误的例如:shell.php%00test.jpg
,截断后提取的后缀还是.php
正确路径使用
为什么修改path才可以,因为程序中检测的是文件的后缀名,如果后缀合法则拼接路径和文件名,那么攻击者修改了path以后的拼接结果为:uploads/shell.php%00/2018051413370000.jpg
,移动文件的时候会将文件保存为uploads/shell.php
%00和%00(urldecode)
%00(urldecode)
需要urldecode
操作,原因在于上传的表单中有enctype
的属性,并且需要enctype="multipart/form-data"
(不对表单中数据进行编码),path
大多数都是存放在表单中的,因此需要在数据包中进行urldecode操作使%00
变成字符串结束符号。
%00
因为path也可以存放在URL或者Cookie中,而在提交数据的时候,浏览器会对数据做一次urldecode
的操作,而到服务端,会对数据进行一次urldecode的操作,因此如果path在非enctype=multipart/form-data
的表单中或URL or Cookie中的时候,就可以直接写%00
不需要进行URLdecode操作,让服务端对%00
进行URL解码即可。
内容过滤
过滤关键字
短标签,绕过php
1 | eval($_POST[1]); |
竞争条件
检查上传的文件是否包含WebShell脚本,如果包含就删除。上传成功和删除文件存在时间差。
先上传webshell文件10.php 10.php生成新的脚本shell.php
1 |
|
漏洞在系统中的差异
常用的web容器有IIS、Tomcat、Nginx、Apache等
IIS 5.x/6.0解析漏洞
1 | 1、当创建.asp的文件目录的时候,在此目录下的任意文件,服务器都解析为asp文件。例如如下: |
漏洞产生的原因参考详细文章内容:https://www.cnblogs.com/l1pe1/p/9210094.html
可以理解为的检测流程为:
1 | www.xxx.com/xxx.asp;xxx.jpg |
因此,.asp将最终被保存下来,IIS6只简单地根据扩展名来识别,所以从脚本映射表中里查找脚本与扩展名对比,并利用asp.dll来解析。导致最终的问题产生。
对于此问题,微软并不认为这是一个漏洞,同样也没推出IIS6.0解析漏洞的补丁。因此在IIS6.0的网站下,此问题仍然可以尝试是否存在。
Nginx 解析漏洞
在低版本Nginx中存在一个由PHP-CGI导致的文件解析漏洞。为什么是由于PHP-CGI的原因呢,因为在PHP的配置文件中有一个关键的选项cgi.fix_pathinfo
在本机中位于php.ini
配置文件中,默认是开启的,当URL中有不存在的文件时,PHP就会默认向前解析。
普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME
。访问 www.xx.com/phpinfo.jpg/1.php
这个URL时,$fastcgi_script_name
会被设置为phpinfo.jpg/1.php
,然后构造成SCRIPT_FILENAME
传递给PHP-CGI,但是PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析呢?这就要说到fix_pathinfo
这个选项了。如果开启了这个选项,那么就会触发在PHP中的如下逻辑:PHP会认为SCRIPT_FILENAME
是phpinfo.jpg
,而1.php
是PATH_INFO
,所以就会将phpinfo.jpg
作为PHP文件来解析了
在默认Fast-CGI开启状况下上传名字为xx.jpg,内容为:
1 | 'shell.php','w'),'<?php eval($_POST[cmd])?>'); fputs(fopen( |
然后访问xx.jpg/.php
,在这个目录下就会生成一句话木马shell.php
。
Apache 解析漏洞
Apache是世界使用排名第一的Web服务器软件。它可以运行在几乎所有广泛使用的计算机平台上,由于其跨平台和安全性被广泛使用,是最流行的Web服务器端软件之一。它快速、可靠并且可通过简单的API扩充,将Perl/Python等解释器编译到服务器中。
Apache 在1.x和2.x版本中存在解析漏洞,例如如下地址格式:
1 | www.xxxx.com/apache.php.bbb.aaa |
Apache从右至左开始判断后缀,若aaa非可识别后缀,再判断bbb,直到找到可识别后缀为止,然后将该可识别后缀进解析,因此如上地址解析为访问apache.php文件。
那么为什么会产生此问题原因,在Apache的官方网站上,有一句这么关于“extension”的解释:
1 | 地址:http://httpd.apache.org/docs/current/mod/directive-dict.html |
通过这个解释可以看出来,Apache允许文件有多个后缀名,并会按照第一个点来分析文件后缀,例如file.html.en
。Apache按照每个点来分割后缀名,因此此文件名为.html.en
。由于en后缀不被识别,便继续向前解析。
另外对于Apache解析漏洞的正确说法应该是,使用module模式与php结合的所有版本 apache存在未知扩展名解析漏洞,使用fastcgi模式与php结合的所有版本apache不存在此漏洞。而是否解析的后缀名在文件mime.types
中查找是否出现。