文件上传漏洞(upload靶场)
目录
Pass-01:前端绕过
方法一:浏览器禁用js
方法二:直接修改或删除js脚本
方法三:修改后缀绕过
Pass-02:服务器检测
Pess-03:黑名单绕过
Pass-04:.htaccess文件
Pass-05:windows特性和user.ini
方法一:php.自动解析为php(windows下)
方法二:.user.ini绕过
Pass-06:大小写绕过
Pass-07:空格绕过
Pass-08:尾部点绕过
Pass-09:::$DATA特殊符号绕过
Pass-10:利用 '. .'绕过
Pass-11:双写绕过
Pass-12:get %00截断
Pass-13:post %00截断
Pass-14:照片马(二进制过滤文件类型)
Pass-15:照片马(返回数组过滤文件类型)
Pass-16:照片马(第一字节过滤文件类型)
Pass-01:前端绕过
直接上传会被前端js代码过滤
代码分析第一关是前端过滤类型
方法一:浏览器禁用js
利用浏览器的设置可以禁用js,从而绕过过滤限制
方法二:直接修改或删除js脚本
用Burpsuit,开启拦截pass-01,打开burpsuit界面,Do intercept-Response to request选项,可以得到这次发包的响应包
forward放包找到前端验证部分
直接删除前端js白名单
上传成功
方法三:修改后缀绕过
使用Burpsuit抓包修改后缀达到绕过目的
先将web.php文件后缀修改为jpg(web.jpg绕过前端)
拦截到requset修改web.jpg
修改后send的一下
上传成功
Pass-02:服务器检测
直接上传,提示文件类型不正确
代码分析:
会判断upload_file的类型从而其实文件类型不正确
用BurpSuite抓包看到content-type:application/octet-stream
那就request修改类型为image/jpeg
成功上传
查看上传php文件
Pess-03:黑名单绕过
直接上传 提示不允许上传.asp、 .aspx、.php、 .jsp
代码分析:是一个文件后缀过滤的黑名单
Pass-04:.htaccess文件
源码分析:本关过滤了大多的后缀
但是没有过滤.htaccess .htaccess文件,指在特定的文档目录中放置一个包含一个或多个指令的文件,以作用于此目录及其所有子目录。
此功能在httpd.conf中的ALLowOverride ALL 字段决定
所以我们可以建立一个.htaccess文件,文件内容为:
php
<FilesMatch "web.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
//将该目录以及子目录下的web.jpg当作php文件执行
上传.htaccess文件
接着上传web.php修改后缀为web.jpg
访问上传文件web.jpg成功解析
Pass-05:windows特性和user.ini
和第四关相比.htaccess被过滤
方法一:php.自动解析为php(windows下)
在windows系统下可行
web.php. windows系统的特性自动过滤掉,成为web.php
而在Linux下环境
方法二:.user.ini绕过
.user.ini绕过
上传.user.ini
再上传web.jpg
但是当前是docker拉取的环境 失败
Pass-06:大小写绕过
分析代码:
相比前几个关少了 $file_ext = strtolower($file_ext); //转换为小写
所以大小写就可以绕过
Pass-07:空格绕过
代码分析:
少了$file_ext = trim($file_ext); //首尾去空
可以空格绕过
Pass-08:尾部点绕过
代码分析:
没有$file_name = deldot($file_name);//删除文件名末尾的点
可以用点绕过
Pass-09:::$DATA特殊符号绕过
代码分析:
没有$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
可以用::$DATA特殊符号绕过
Pass-10:利用 '. .'绕过
尾部去点去空格
依旧可以用web.php. .来绕过
Pass-11:双写绕过
代码分析:
依旧是黑名单但是 代码:$file_name = str_ireplace($deny_ext,"", $file_name);
从文件名 $file_name 中删除所有在 $deny_ext 列表中定义的被禁止的扩展名,替换为空
所以可以双写绕过
Pass-12:get %00截断
换成了白名单
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
下面的$file_ext匹配上传文件名中的.最后一次出现位置+1后面的所有字符串
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
使用get传参 重置上传路径
所以可以使用%00截断的方法
web.php%00+xxxxxx.jpg绕过白名单
当执行move_uploaded_file函数时,服务器会对路径中%00后的内容不做解析,默认迁移文件为web.php
Pass-13:post %00截断
和12关区别就是13关换为了post传参
Pass-14:照片马(二进制过滤文件类型)
代码分析:
getReailFileType()用于检测文件头部两个字节的信息(前两个字节是文件格式的标识),并且通过二进制码判断其文件的类型,然后控制文件的上传
直接上传web.php的web.jpg文件上传是失败的
对比正常的照片和web.jpg的文件 头部有明显不同,恰巧代码就是通过头字段来判断的
所以这里使用png照片和web.php代码结合
Pass-15:照片马(返回数组过滤文件类型)
这里用上一题的照片码上传失败显示文件未知,上传失败!
按理说可以用上一题的照片马,
会不会是照片大小的问题
重新截取小照片整合php
GIF89a ? !?
, D ;
<?php
phpinfo();
?>
后面发现上传成功
Pass-16:照片马(第一字节过滤文件类型)
代码分析:
通过exif_imagetype($filename);函数取一个图像的第一个字节并检查其签名。
仍可以用上一关的图片马,