pass11
查看代码
这里我们先解读下代码
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
# 定义了白名单数组
$ext_arr = array('jpg','png','gif');
# 截取上传文件名最后一个带点的文件后缀
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
# 判断后缀名是否都在白名单中
if(in_array($file_ext,$ext_arr)){
$temp_file = $_FILES['upload_file']['tmp_name'];
# 用$_GET来拼接上传路径 取上传文件的末尾点后缀名 并对文件进行重命名
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
# 移动临时文件到上传目录
if(move_uploaded_file($temp_file,$img_path)){
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
}
代码漏洞点就在于 用$_GET['save_path']来组成上传的文件路径 而这个get传参是我们可以控制的地方
因此我们考虑用是否能进行截断 例如形成../upload/www.php/截断后面的(xxx.jpg)
这样就通过了白名单校验 并且保存成了php文件
继续使用burp进行抓包使用%00进行截断
%00能进行截断的原因
url中的%00(只要是这种%xx)的形式,webserver会把它当作十六进制处理,
然后把16进制的hex自动翻译成ascii码值“NULL”,实现了截断burpsuite中16进制编辑器将空格20改成了00。
本质上来说,都是利用0x00是字符串的结束标识符,进行截断处理。
只不过GET传参需要url编码成%00而已
原理:php的一些函数的底层是C语言,而move_uploaded_file就是其中之一,遇到0x00会截断,0x表示16进制,URL中%00解码成16进制就是0x00。
%00的使用是在路径上,如果在文件名上使用,就无法正常截断了。如:aaa.php%00bbb.jpg
需要满足的条件
00截断的限制条件是PHP<5.3.29,且GPC关闭
因为当 magic_quotes_gpc 打开时,所有的 ' (单引号), " (双引号), \ (反斜线) and 空字符会自动转为含有反斜线的转义字符。
magic_quotes_gpc 着重偏向数据库方面,是为了防止sql注入,但magic_quotes_gpc开启还会对$_REQUEST, $_GET,$_POST,$_COOKIE 输入的内容进行过滤
pass-12
查看代码
同第12关做法相同 只不过上传路径在$_POST数据中 不需要url编码
这里说一个小技巧 不需要修改hex值那么麻烦 只要在burp里面输入%00 然后进行url解码即可 得到就是0x00
pass13
这里查看代码发现他是审查开始的两个字节
所以这里我们要上传图片当然图片里要包含你写的一句话木马
我们可以利用电脑的命令行来完成
首先准备一张正常的图片和一个写有一句话木马的php文件放在一个文件夹下
执行此语句
copy 1.jpg(你的文件名/b + 2.php(文件名)/a 2,jpg
上传
通过代码发现我我们上传的文件参数时file,这里我们使用文件包含漏洞
http://upload-labs/include.php?file=http://upload-labs/upload/4620240318182534.jpg
成功
pass-14
查看提示发现这里使用
getimagesize()函数:
返回一个具有四个单元的数组。
索引 0 包含图像宽度的像素值,
索引 1 包含图像高度的像素值。
索引 2 是图像类型的标记:1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM。这些标记与 PHP 4.3.0 新加的 IMAGETYPE 常量对应。
索引 3 是文本字符串,内容为"height="yyy" width="xxx"",可直接用于 IMG 标记。
做法和上关相同
pass-15
查看提示
做法还是一样
pass-16
查看提示可知这里使用二次渲染
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
// 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
$filename = $_FILES['upload_file']['name'];
$filetype = $_FILES['upload_file']['type'];
$tmpname = $_FILES['upload_file']['tmp_name'];
# 拼接上传路径 例如上传17.png 则 $target_path=../upload/17.png
$target_path=UPLOAD_PATH.'/'.basename($filename);
// 获得上传文件的扩展名
$fileext= substr(strrchr($filename,"."),1);
//判断文件后缀与MIME类型,合法才进行上传操作
if(($fileext == "jpg") && ($filetype=="image/jpeg")){
// 这里存在逻辑缺陷 是先上传保存的图片 然后再去验证 如果不满足就删除上传的文件
if(move_uploaded_file($tmpname,$target_path)){
//使用上传的图片生成新的图片
$im = imagecreatefromjpeg($target_path);
if($im == false){
$msg = "该文件不是jpg格式的图片!";
@unlink($target_path); // 删除上传的原来的文件
}else{
//给新图片指定文件名
srand(time());
$newfilename = strval(rand()).".jpg";
//显示二次渲染后的图片(使用用户上传图片生成的新图片)
$img_path = UPLOAD_PATH.'/'.$newfilename;
imagejpeg($im,$img_path);
@unlink($target_path);
$is_upload = true;
}
} else {
$msg = "上传出错!";
}
}else{
$msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
}
}
通过查看代码发现它是会把上传上去的图片重新打乱再组合因此这里我们要对比原图片和打乱后的图片看看哪里没有发生变化再把木马放在没有变的地方
这里我们使用01editor进行
这里我们看到match就是没有变的地方我们吧木马放在这里
但是有时候放的位置会导致图片损坏因此要多试几次(如果想成功的快一点可以使用.gif的图片因因为动图有大量的空白区)
插入后上传
pass-17
查看代码
$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_name = $_FILES['upload_file']['name'];
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_ext = substr($file_name,strrpos($file_name,".")+1);
$upload_file = UPLOAD_PATH . '/' . $file_name;
if(move_uploaded_file($temp_file, $upload_file)){
if(in_array($file_ext,$ext_arr)){
$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
rename($upload_file, $img_path);
$is_upload = true;
}else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
unlink($upload_file);
}
}else{
$msg = '上传出错!';
}
}
这里是先上传再删除掉不符合的文件因此我们要赶在文件删除前把木马上传到上一级目录里
php文件内容如下
php fputs(fopen('../shell.php','w'),'<?php phpinfo() ?>');?>
这里我们可以使用burp suite一直让他发包并访问来执行它
上传成功