Upload-labs(Pass-17--Pass-21)
Pass-17
二次渲染+图片马/条件竞争
二次渲染就是在我们上传的图片后,网站会对图片进行二次处理,比如对图片的尺寸、格式、以及网站对图片进行定义的一些要求等进行处理,并且服务器会对里面的内容进行二次替换更新,在处理完后,会生成一个合规的图片在网站上显示出来。
imagecreatefromjpeg()函数,二次渲染是由Gif文件或 URL 创建一个新图象。成功则返回一图像标识符/图像资源,失败则返回false,导致图片马的数据丢失,上传图片马失败。
查看源码
$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的图片文件!";
}
}
提示
网上大佬的二次渲染专用图片https://wwe.lanzoui.com/iFSwwn53jaf
本次关卡对上传的图片进行了处理,先进行二次渲染才进行的放入的,而渲染把图片马的当中的后门清除掉。所以本关的关键在于避开二次渲染。
二次渲染不是全部渲染,只渲染部分,所以把经过渲染的文件与未渲染的文件进行比较就可以得出不渲染的区域,随后把后门写在这里即可
上传文件,并修改url访问后
可以看到这里只是显示了图片的内容,没有解析到图片中的PHP代码。
因为系统把我上传的图片重新渲染了一遍,或者说是压缩了我所上传图片的内容。
接下来先把被渲染的图片下载下来,直接右键图片,点击“另存图像为”
将两个图像使用010工具中的比较文件打开
将被渲染后的图片与原来的图片进行对比,利用工具可以明显的看到渲染前后图像文件的异同
复制一句话木马的16进制
在已经被渲染的图像里面,未被渲染的区域插入一句话木马
保存后,上传被渲染过且被修改过的一句话木马图像
查看图像路径
访问文件路径时需要构造URL
利用文件包含漏洞upload-labs/include.php?file=upload/文件名
成功访问
文件上传:Upload靶场11到17关详解。_文件上传emeditor图片马-CSDN博客
Pass-18
(条件竞争)
查看源码
提示
上传图片木马配合解析漏洞进行getshell
准备工作:
新建一句话木马18.php,代码为:
<?php fputs(fopen('../upload/shell18.php','w'),'<?php phpinfo();?>');?>
只要被成功当作PHP文件解析,就会生成shell18.php 文件
上传文件18.php,并且使用bp抓包
点击右键或使用ctrl+i发送到lntruder
bp设置无限发送空的Payloads,来让它一直上传该文件
打开python脚本并运行
python代码
import requests
url = "http://upload-labs-master/upload/18.php"
while True:
html = requests.get(url)
if html.status_code == 200:
print("OK")
break
else:
print("发包中")
在python脚本运行后,burpsuite开始无限制重放数据包
直到python脚本出现OK,才关闭burpsuite
打开根目录,可以看见shell18文件已经被成功上传
使用文件包含漏洞upload-labs/include.php?file=upload/构造url
成功访问
Pass-19
(条件竞争+白名单+其他漏洞配合)
查看源码
//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
require_once("./myupload.php");
$imgFileName =time();
$u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
$status_code = $u->upload(UPLOAD_PATH);
switch ($status_code) {
case 1:
$is_upload = true;
$img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
break;
case 2:
$msg = '文件已经被上传,但没有重命名。';
break;
case -1:
$msg = '这个文件不能上传到服务器的临时文件存储目录。';
break;
case -2:
$msg = '上传失败,上传目录不可写。';
break;
case -3:
$msg = '上传失败,无法上传该类型文件。';
break;
case -4:
$msg = '上传失败,上传的文件过大。';
break;
case -5:
$msg = '上传失败,服务器已经存在相同名称文件。';
break;
case -6:
$msg = '文件无法上传,文件不能复制到目标目录。';
break;
default:
$msg = '未知错误!';
break;
}
}
//myupload.php
class MyUpload{
......
......
......
var $cls_arr_ext_accepted = array(
".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
".html", ".xml", ".tiff", ".jpeg", ".png" );
......
......
......
/** upload()
**
** Method to upload the file.
** This is the only method to call outside the class.
** @para String name of directory we upload to
** @returns void
**/
function upload( $dir ){
$ret = $this->isUploadedFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->setDir( $dir );
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->checkExtension();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
$ret = $this->checkSize();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
// if flag to check if the file exists is set to 1
if( $this->cls_file_exists == 1 ){
$ret = $this->checkFileExists();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
}
// if we are here, we are ready to move the file to destination
$ret = $this->move();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
// check if we need to rename the file
if( $this->cls_rename_file == 1 ){
$ret = $this->renameFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}
}
// if we are here, everything worked as planned :)
return $this->resultUpload( "SUCCESS" );
}
......
......
......
};
1.正常
2.文件已经被上传,但没有重命名。
3.上传失败,上传目录不可写。
4.上传失败,无法上传该类型文件。
5.上传失败,上传的文件过大。
6.上传失败,服务器已经存在相同名称文件。
7.文件无法上传,文件不能复制到目标目录。
8.未知错误!
对于文件类型检查:
(白名单)
“.doc”, “.xls”, “.txt”, “.pdf”, “.gif”, “.jpg”, “.zip”, “.rar”, “.7z”,“.ppt”,
“.html”, “.xml”, “.tiff”, “.jpeg”, “.png”
提示仍是代码审计
本关的页存在着条件逻辑漏洞,我们可以采用条件竞争的方式来绕过
上传图片马,在系统没有将图片马重命名之前,用文件包含漏洞将其解析,从而生成一个含有一句话木马的1.php文件。
查找许多资料后,仍然无法做出upload-labs-Pass-19
文件上传upload-labs 第19关 Apache解析漏洞配合条件竞争_upload-labs第19关-CSDN博客
upload-labs_pass19_条件竞争+apache解析漏洞_apache解析 upload-labs-CSDN博客
先暂告一段落,进一步深入了解后,再做尝试。
Pass-20
(黑名单+上传路径可控)
查看源码
提示
因为文件名可控,这题利用move_uploaded_file的一个特性,会自动忽略后面的/.
apache2.4.0~2.4.29版本 判断后缀时会带上末尾的换行符,也就是说.php%0A这个后缀和.php一样都会被apache当作php文件解析
可以在文件名后加/.这两个符号来绕过黑名单的限制。
上传一张图片马,代码如下
<?php phpinfo();?>
把文件保存改为1.php/.
上传成功后直接访问
成功
具体原理还不是太懂。
upload靶场后面几个题难度比较大,但不是越后面的题就越难,拿到题目后多加尝试,总会有解法的。
Pass-21
(MIME验证+白名单+上传路径可控)
查看源码
$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{
//检查文件名
$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_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 = "请选择要上传的文件!";
}
提示
补充知识:
end(array)函数,输出数组中的当前元素和最后一个元素的值。
reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值
count(array)函数,计算数组中的单元数目,或对象中的属性个数
explode(separator,string[,limit]) 函数,把字符串打散成数组。
题解
首先准备一张图片马phpinfo.png
<?php
phpinfo();
?>
上传后用bp拦截
修改后放行
找到一张大佬做的较为详细的图片
放行后,发现文件上传成功
成功访问
写在最后
极为艰难的勉强参照着大佬们的博客,将upload靶场上的题目全部做完一遍。尤为感受到,所知俞多,方知所知俞少之感。在文件上传的路上,在web的路上,在ctf的路上,在网络攻防的路上。都还有很长的一段路要走。一段煎熬,困难,波折,孤独的路,但我相信,前行总有曙光。如同此刻的夜晚,偶有残星闪烁,月牙勾起尖角,黑夜笼罩着黑夜。而明天,太阳照常升起。
静谧的夜晚,纷乱的思绪。反正也没什么人看见,我为我,写点东西。
晚安。2024.4.12
原文地址:https://blog.csdn.net/2301_81105268/article/details/137654545
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!