任意文件上传
0x00 前言
任意文件上传是由于没有严格检测和过滤用户上传的文件而导致的一种漏洞,属于getshell的一种方法。如修改头像、上传资料等处,都有可能存在任意文件上传。
0x01 危害:
上传脚本文件,导致代码执行。
上传Flash策略文件crossdomain.xml,导致Flash在该域下的行为可控。
上传木马病毒,导致服务器被控制。
0x02 主流绕过方法
1、条件竞争:
服务器对上传的文件合法性进行检测,若文件不合法则删除,合法则进行重命名、拷贝等操作。
而在对文件进行检测时需要一小段时间,这段时间内上传的木马文件会存在服务器中,因此可以利用条件竞争漏洞:
写一个木马文件,执行生成一个新的一句话,如:
1 | <?php $txt = '<?php @eval($_REQUEST[\'1234\'])?>';file_put_contents('1.php',$txt)?> |
这时可以利用Burpsuite跑包,一边不断进行上传操作,一边去访问这个文件。
直到某个时刻,上传的文件还未被服务器删除时,我们访问了这个文件,新的一句话木马1.php被生成。
2、解析漏洞
当服务器设置黑名单检测时,可以改变后缀名绕过,同样可以解析。
如
Apache 1.x 2.x解析漏洞:
Apache的解析顺序为从右至左,当遇到不认识的后缀名时,会向左读取。因此在某些情况下,可以使用
1 | a.php.xxxx |
绕过
IIS 5.x/6.0解析漏洞:
apa、cer、cdx当做asp文件解析。是由于IIS6.0默认配置中,这些文件都会调用asp.dll。如
1 | a.apa |
IIS6.0在处理含有特殊符号的文件路径时会出现逻辑错误:
①、当文件名中出现 ; / 和 . 时都会将后面的截断,只解析前面的部分,如:
1 | a.asp;.jpg |
②、当目录名为 *.asp *.asa时,会将目录下的所有文件当做asp解析,如:
1 | D:/a.asp/1.jpg |
IIS 7.0/7.5 | Nginx < 8.03 | Lighttpd 解析漏洞
在任意文件名后面加 * / *.php ,都会将这个文件当做php解析,如
上传一个图片马 a.jpg
访问
1 | http://www.test.com/uploads/a.jpg/.php |
图片马就会被解析
原理其实就是 CGI 解析漏洞 :
当访问 a.jpg/1.php 时,认为1.php是请求文件,但是1.php不存在,因此会向上读取,读到a.jpg,若存在,则直接执行,中间少了一步文件类型的验证,因此最终 a.jpg 会当做不存在的 1.php 执行。
操作系统的特性:
Windows环境下,会自动将文件名最后的点或空格去掉,因此可以使用 php. 或 php空格 绕过
Windows文件流绕过:在文件名后面添加 ::$DATA ,会自动删除。
3、图片马绕过
将一个小尺寸的图片和木马制作成图片马,可以绕过 php_exif图像类型检测 、getimagesize图像尺寸大小检测等
常用格式有jpg、png、gif等
上传完图片马后,需要结合解析漏洞、.htaccess文件、任意文件包含等漏洞进行利用
需要注意的是服务器可能会对上传的图像进行二次渲染,需要进行对比,将一句话插入没有被二次渲染的地方。相对来说gif可以更好绕过二次渲染,jpg、png较为复杂,可以使用脚本生成。
4、00截断:
若服务器设置的是白名单,则可以尝试00截断
00截断存在于PHP版本低于5.3.4,且magic_quotes_gpc设置为off (on 会将%00转义掉) 的环境中
改文件名:
在ASCII中,0表示结束符,URL编码为%00,因此可以使用%00进行绕过,如
GET:
1 | http://www.test.com/upload.php?filename=a.php%00.jpg |
POST:
由于%00是URL编码,POST传参并不会自动URL解码。所以POST传参需要在Hex中修改
如先将文件命名为a.phpa.jpg,再在Hex中将第二个a的Hex值修改为00
改上传路径:
有时候传参中包含了上传文件的路径,因此可以在路径中使用00截断,绕过文件名的检测
0x04 其他绕过方法
.htaccess绕过 (伪静态的网站)
后缀大小写、双写绕过
修改 Content-Type绕过
能被解析的文件后缀:
jsp: jpsx jspf
asp: asa cer aspx
php: php3 php4 phtml
exe: exee
0x05 靶场复现
0x06 防御措施
1、检查文件上传路径,并且设置上传路径为不可执行
2、后缀名白名单限制
3、检查文件MIME类型
4、检查文件内容,避免插入一句话等
5、二次渲染
6、对上传的文件重命名