免责声明
本公众号提供的工具、教程、学习路线、精品文章均为原创或互联网收集,旨在提高网络安全技术水平为目的,只做技术研究,谨遵守国家相关法律法规,请勿用于违法用途,如果您对文章内容有疑问,可以尝试加入交流群讨论或留言私信,如有侵权请联系小编处理。
2
内容速览
注意:更改配置之后记得重启服务器
# shell.php → 测试所用的phpinfo
<?php phpinfo(); ?>
准备工作:准备好
.jpg
/.png
/.gif
三种类型的图片,图片大小越小越好,推荐使用截图工具的截图;准备好webshell文件,将图片与文件放到一个目录下
copy 01.png/b + test.php/a shell.png
[01.png
为图片,大小不宜过大 | test.php
为webshell | shell.png
为生成的图片马文件]8enk0
题目:
绕过方法:
因为Pass15和Pass16我们是使用图片马绕过,这一题我们使用第一种方法尝试,我们以较为简单的gif图为例(有兴趣的朋友们可以去试试其它的文件格式),步骤:在原有webshell代码前添加字符串GIF89a
第一步:上传webshell
可以看到,webshell被自动识别为了gif文件
第二步:利用文件包含漏洞访问图片马
题目:
绕过方法:
上传图片马绕过
第一步:上传图片马
第二步:使用利用文件包含漏洞访问图片马
ypj3j
题目:别忘记打开php_exif模块
绕过方法:
上传图片马绕过
第一步:上传图片马
第二步:使用利用文件包含漏洞访问图片马
rlpub
题目:
# 使用二次渲染过滤
$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'];
$target_path=UPLOAD_PATH.'/'.basename($filename);
// 获得上传文件的扩展名
$fileext= substr(strrchr($filename,"."),1);
//判断文件后缀与类型,合法才进行上传操作
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 if(($fileext == "png") && ($filetype=="image/png")){<!-
- -->
if(move_uploaded_file($tmpname,$target_path)){<!-
- -->
//使用上传的图片生成新的图片
$im = imagecreatefrompng($target_path);
if($im == false){<!-
- -->
$msg = "该文件不是png格式的图片!";
@unlink($target_path);
}else{<!-
- -->
//给新图片指定文件名
srand(time());
$newfilename = strval(rand()).".png";
//显示二次渲染后的图片(使用用户上传图片生成的新图片)
$img_path = UPLOAD_PATH.'/'.$newfilename;
imagepng($im,$img_path);
@unlink($target_path);
$is_upload = true;
}
} else {<!-
- -->
$msg = "上传出错!";
}
}else if(($fileext == "gif") && ($filetype=="image/gif")){<!-
- -->
if(move_uploaded_file($tmpname,$target_path)){<!-
- -->
//使用上传的图片生成新的图片
$im = imagecreatefromgif($target_path);
if($im == false){<!-
- -->
$msg = "该文件不是gif格式的图片!";
@unlink($target_path);
}else{<!-
- -->
//给新图片指定文件名
srand(time());
$newfilename = strval(rand()).".gif";
//显示二次渲染后的图片(使用用户上传图片生成的新图片)
$img_path = UPLOAD_PATH.'/'.$newfilename;
imagegif($im,$img_path);
@unlink($target_path);
$is_upload = true;
}
} else {<!-
- -->
$msg = "上传出错!";
}
}else{<!-
- -->
$msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";
}
}
绕过方法:
这里作者使用文章中介绍的GIF绕过方法进行打靶,其它方法比较麻烦,想玩玩的朋友们可以自行尝试
第一步:上传一个gif图片马,上传之后,将网站回显的图片下载下来进行比较
发现少了一堆的数据,很不幸,写入的webshell被删了 第二步:找一个数据没有被更改的地方插入webshell代码
如果显示不为gif图片,则需要重新挑选一个位置插入webshell
第三步:上传图片马,并测试是否成功
题目:
绕过方法:
根据题目可知,此操作是先将文件移动至目录,再判定是否符合上传规范,若不符合则删除文件。我们可以利用php代码生成新的webshell文件,再利用条件竞争在上传的文件未被删除之前访问它,则可以添加webshell文件至服务器
第一步:制作创建webshell的代码
若上传一句话木马,需要特别注意引号的问题:写入数据的时候需要使用单引号包裹,因为使用双引号会解析里面的$变量
<?php
fputs(fopen('shell.php','w'), '<?php phpinfo(); ?>');
?>
第二步:利用Burp的爆破模块制造条件竞争访问创建webshell的代码
访问文件的爆破模块出现长度不同的返回包即可停止爆破,查看包的内容
由返回包可知访问成功
第三步:访问创建的webshell代码
题目:
绕过方法:
绕过白名单过滤:利用apache的后缀名识别漏洞 —— 从右往左依次识别后缀,遇到不能识别的后缀名便跳过 ,因此可以文件名改为
create.php.7z
(.7z
这个后缀apache不能识别)
绕过重命名(因为重命名会把shell.php
重命名为其它的字符串,导致后缀名识别漏洞不可用):利用条件竞争绕过
只需要对添加了.7z
后缀的文件进行条件竞争绕过即可,步骤与Pass18一致,这里就不做演示
./
绕过黑名单检测】题目:
绕过方法:
就是一个很简单的一个绕过黑名单检测,不明白为什么会放到Pass20来。只需要修改POST传参中的
save_name
参数即可,点绕过、大小写绕过啥的都可以
为了弄清楚这一题的考点,我去看了其它的靶场教程,发现是考move_uploaded_file()
会忽略掉文件末尾的/.
,也就是将save_name
的参数改为shell.php/.
,亲测有效,应该是黑名单检测补充的一个新方法,这种方法没有系统的限制
/.
绕过白名单检测】题目:
$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){<!-
- -->
//检查MIME
$allow_type = array('image/jpeg','image/png','image/gif');
if(!in_array($_FILES['upload_file']['type'],$allow_type)){<!-
- -->
$msg = "禁止上传该类型文件!";
}else{<!-
- -->
//检查文件名
# 如果save_name存在则使用save_name的数据,否则使用upload_file的数据
$file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];
# 通过.将文件名分为一个数组
if (!is_array($file)) {<!-
- -->
$file = explode('.', strtolower($file));
}
# 提取数组的最后一项作为后缀名进行后缀名判定
$ext = end($file);
# 白名单检测后缀名
$allow_suffix = array('jpg','png','gif');
if (!in_array($ext, $allow_suffix)) {<!-
- -->
$msg = "禁止上传该后缀文件!";
}else{<!-
- -->
# 将file的第一个元素与位于数组长度-1的元素拼接组成保存用的文件名
$file_name = reset($file) . '.' . $file[count($file)
- 1];
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH . '/' .$file_name;
if (move_uploaded_file($temp_file, $img_path)) {<!-
- -->
$msg = "文件上传成功!";
$is_upload = true;
} else {<!-
- -->
$msg = "文件上传失败!";
}
}
}
}else{<!-
- -->
$msg = "请选择要上传的文件!";
}
绕过方法:
由代码审计可得,是通过读取数组的最后一个元素来进行后缀名白名单检测,通过位于数组长度-1的元素拼接文件名作为保存所用的文件数据。我们只需要让数组的最后一个元素符合条件,让数组长度-1的元素为空即可完成绕过
第一步:修改webshell的文件类型为白名单内的文件类型 第二步:修改请求包,将save_name空出来,不填入数据
Note:这一题的save_name参数最好要加上在结尾加上/
,利用/.
绕过,而不要单纯的使用.
绕过,因为.
绕过只适用于Windows系统
第三步:访问上传的文件
以下为注释内容 条件竞争:多个线程或进程在读写一个共享数据时结果依赖于它们执行的相对时间
[1]upload-labs:https://github.com/c0ny1/upload-labs