当前位置: 首页 > news >正文

文件上传漏洞(upload-labs)

目录

Pass-01(前端绕过)

(1)JavaScript

(2)Burpsuite(改后缀)

Pass-02(IMME类型 )

burpsuite(改文件类型)

Pass-03(黑名单绕过)

修改后缀

Pass-04(.htaccess)

.htaccess

Pass-05(文件后缀绕过)

burpsuite(. .绕过)

Pass-06(文件后缀绕过)

大小写绕过

Pass-07()

burpsuite(空格绕过)

Pass-08(文件后缀绕过)

burpsuite(. 绕过 )

Pass-09(文件后缀绕过)

burpsuite(::$DATA 特殊符号绕过 )

Pass-10(文件后缀绕过)

burpsuite(. .绕过)

Pass-11(文件后缀绕过)

双写绕过

Pass-12(白名单绕过)

%00截断(GET型)

​编辑

Pass-13(白名单绕过)

%00截断(POST型)

Pass-14(文件包含 )

图片马

Pass-15(文件包含)图片马

Pass-16(文件包含)图片马

Pass-17(二次渲染绕过)


Pass-01(前端绕过)

首先,尝试上传一个php文件

内容为:<?php phpinfo(); ?>

我们可以看到它不允许上传.php文件,只能上传.jpg|.png|.gif类型的文件

function checkFile() {var file = document.getElementsByName('upload_file')[0].value;if (file == null || file == "") {alert("请选择要上传的文件!");return false;}//定义允许上传的文件类型var allow_ext = ".jpg|.png|.gif";//提取上传文件的类型var ext_name = file.substring(file.lastIndexOf("."));//判断上传文件类型是否允许上传if (allow_ext.indexOf(ext_name + "|") == -1) {var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;alert(errMsg);return false;}
}

其次,我们通过查看源码发现,它只是在前端页面对输入的文件进行检查,所以我们有以下两种方法解决:

(1)JavaScript

设置→隐私与安全→网站设置→JavaScript→不允许网站使用 JavaScript

测试:在清空上传文件并刷新网页后,我们重新上传成功,但因为不是图片所以无法显示,我们通过“在新标签页中打开图片”就可以看到上传成功

(2)Burpsuite(改后缀)

用抓包工具Burpsuite对上传的包进行改包

将.php文件改为.jpg|.png|.gif类型的文件,打开burpsuite、代理(8080),上传文件

在repeater中修改文件后缀为.php后send,我们可以在response中查看到.php文件

结果:在上传文件中我们查看到shell.php文件上传成功

Pass-02(IMME类型 )

我们尝试用.php文件上传,显示文件类型不正确,所以我们可以直接用bs来解决

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '文件类型不正确,请重新上传!';}} else {$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';}
}
burpsuite(改文件类型)

上传.php文件,用burpsuite抓包,修改文件类型

找到文件类型将application改为image/png,然后send

multipart/form-data:一般用于文件上传;又是一个常见的 POST 数据提交的方式。与application/x-www-form-urlencoded不同,这是一个多部分多媒体类型。application/x-www-form-urlencoded:最常见的 POST 提交数据的方式,一般用于表单提交。application/json:服务端/客户端会按json格式解析数据。需要参数本身就是json格式的数据,参数会被直接放到请求实体里,不进行任何处理

结果:在上传文件中我们查看到shell.php文件上传成功

Pass-03(黑名单绕过)
修改后缀
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {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;            if (move_uploaded_file($temp_file,$img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

通过查看源码,我们得到.asp .aspx .php .jsp都被不允许,并且对一些特殊字符进行过滤,所以我们可以上传一些没有限制的后缀,如:php3 php4 php5 phtml的文件进行上传

结果:成功上传,但是还是没有成功解析

建议用apache/php最低版本

Pass-04(.htaccess)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");$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.'/'.$file_name;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

查看源码我们得到它过滤了很多后缀,但是.htaccess没有过滤

.htaccess

.htaccess是apache的根目录的配置文件,该配置文件是用来做伪静态的

伪静态就比如你不想让别人知道你上传的.php文件,那么就将.php文件伪装成.html文件

我们可以创建一个.htaccess文件,在该文件中写入一个规则,如下,然后上传一个.jpg文件

AddType application/x-httpd-php .jpg#无论什么文件只要包含了jpg都视为php来解析

最后访问该图片就可以成功的将jpg文件当做php文件解析

Pass-05(文件后缀绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");$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.'/'.$file_name;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

通过查看源码,我们可知连.htaccess也过滤了,但它对文件的末尾点只限制了一次,所以我们可以双写“.”来绕过

burpsuite(. .绕过)

首先上传一个.php文件,抓包(可以drop放一下)

其次在request中修改后缀为.php. .来绕过

结果:在上传文件中我们查看到shell.php文件上传成功

Pass-06(文件后缀绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$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;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

通过查看源码,我们可知第6关没有第5关的大小写过滤,所以我们可以通过大小写绕过

大小写绕过
 $file_ext = strtolower($file_ext); //转换为小写

结果:解析成功

Pass-07()
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = $_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);//去除字符串::$DATAif (!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;if (move_uploaded_file($temp_file,$img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件不允许上传';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

通过查看源码,我们发现相比上一关它少了个去空格的操作,所以我们可以通过用burp suite抓包在首尾添加空格

$file_ext = trim($file_ext); //首尾去空注:window下,文件后缀有空格\点(.)\::$DATA,都会自动去掉,而linux下不会,因此这种绕过方式只能在windows中使用
burpsuite(空格绕过)

上传.php文件,抓包,首尾添加空格后send

结果:在上传文件中我们查看到shell.php文件上传成功

Pass-08(文件后缀绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = trim($_FILES['upload_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.'/'.$file_name;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

通过查看源码,我们发现它少了文件名末尾的点的过滤,所以我们可以通过在末尾加一个“.”来绕过

$file_name = deldot($file_name);//删除文件名末尾的点
burpsuite(. 绕过 )

上传.php文件,抓包,添加“.”后send

结果:在上传文件中我们查看到shell.php文件上传成功

Pass-09(文件后缀绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$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;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

通过查看源码,我们发现它少了字符串::$DATA的过滤,所以我们可以通过在末尾加一个“::$DATA”来绕过

$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
burpsuite(::$DATA 特殊符号绕过 )

上传.php文件,抓包,添加“::$DATA”后send

结果:在上传文件中我们查看到shell.php文件上传成功

Pass-10(文件后缀绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$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.'/'.$file_name;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

通过查看源码,我们可知同第5关一样,它对文件的末尾点只限制了一次,所以我们可以双写“.”来绕过

burpsuite(. .绕过)

我们通过上传一个.php文件,抓包,后缀添加“. .”来绕过

结果:在上传文件中我们查看到shell.php文件上传成功

Pass-11(文件后缀绕过)
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = str_ireplace($deny_ext,"", $file_name);$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.$file_name;        if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

通过查看源码,我们可得通过双写来绕过,我们直接上传.pphphp这样的文件,使其删除一次后恢复为正确的文件后缀进行绕过

双写绕过

结果:.php文件在新标签页中正常解析

Pass-12(白名单绕过)
$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'];$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类型文件!";}
}

通过查看源码,我们可知它只允许上传.jpg|.png|.gif类型文件,但是我们的上传路径是可控的(通过GET方式传参),所以我们可以使用%00截断来绕过

%00截断(GET型)

上传.jpg文件,抓包,修改上传路径后send

注:这种漏洞仅存在于php5.2中

Pass-13(白名单绕过)
$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'];$img_path = $_POST['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类型文件!";}
}

通过查看源码,我们可知它与第12关相同,但是它是通过POST方式传参,所以我们也使用%00截断来绕过

%00截断(POST型)

上传.jpg文件,抓包,修改上传路径后send

上传路径不能像GET那样写,我们可以通过十六进制来改写,查看时可以点\n则可以看到\0

同理:这种漏洞仅存在于php5.2中

Pass-14(文件包含 )
​
上传图片马到服务器。注意:1.保证上传后的图片马中仍然包含完整的一句话或webshell代码。2.使用文件包含漏洞能运行图片马中的恶意代码。3.图片马要.jpg,.png,.gif三种后缀都上传成功才算过关!function getReailFileType($filename){$file = fopen($filename, "rb");$bin = fread($file, 2); //只读2字节fclose($file);$strInfo = @unpack("C2chars", $bin);    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    $fileType = '';    switch($typeCode){      case 255216:            $fileType = 'jpg';break;case 13780:            $fileType = 'png';break;        case 7173:            $fileType = 'gif';break;default:            $fileType = 'unknown';}    return $fileType;
}$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$temp_file = $_FILES['upload_file']['tmp_name'];$file_type = getReailFileType($temp_file);if($file_type == 'unknown'){$msg = "文件未知,上传失败!";}else{$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}

查看源码和提示我们只能读取内容的开头的两个字节,并且只能上传图片,那么我们就可以尝试使用图片马的方式

图片马

将一句话木马与图片进行融合

\Desktop>copy lyy.png /b + shell.php /a test.png

可以用记事本打开检查末尾是否包含

上传文件复制图片地址,点击“文件包含漏洞”补全url访问(失败了可以换图再尝试)

http://10.10.155.236/uploadlabs/include.php?file=http://10.10.155.236/uploadlabs/upload/7520250308223010.png

成功:

Pass-15(文件包含)图片马
function isImage($filename){$types = '.jpeg|.png|.gif';if(file_exists($filename)){$info = getimagesize($filename);$ext = image_type_to_extension($info[2]);if(stripos($types,$ext)>=0){return $ext;}else{return false;}}else{return false;}
}$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$temp_file = $_FILES['upload_file']['tmp_name'];$res = isImage($temp_file);if(!$res){$msg = "文件未知,上传失败!";}else{$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}

本关与上一关类似,只是判断文件的函数方法略有区别,也可以通过图片马进行访问

getimagesize() 是 PHP 中用于获取图像尺寸和类型的函数。它返回一个包含图像信息的数组,如果图像文件不存在或无法读取,getimagesize() 会返回 false

方法同上,上传图片马

Pass-16(文件包含)图片马
function isImage($filename){//需要开启php_exif模块$image_type = exif_imagetype($filename);switch ($image_type) {case IMAGETYPE_GIF:return "gif";break;case IMAGETYPE_JPEG:return "jpg";break;case IMAGETYPE_PNG:return "png";break;    default:return false;break;}
}$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$temp_file = $_FILES['upload_file']['tmp_name'];$res = isImage($temp_file);if(!$res){$msg = "文件未知,上传失败!";}else{$img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = "上传出错!";}}
}

这关和之前两个也类似,仅仅是使用函数变化,原理相同,用之前的图片马上传+文件包含漏洞即可利用

exif_imagetype() 是 PHP 中用于快速确定图像类型的函数。它通过读取图像文件的前几个字节来检测图像的类型,并返回一个与图像类型对应的常量值

Pass-17(二次渲染绕过)
$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的图片文件!";}
}

imagecreatefromgif()函数:会将上传的图片中的内容打乱,(则一句话木马也被打乱)生成 一张新的图片,但是看不出来改变了

将图片马上传成功后下载下来,进行对比,找到文件前后内部编码没有改变的部分,然后我们在上传前文件中没有改变部分中加入代码

可以借用工具(如:winhex(不怎么好用))

相关文章:

文件上传漏洞(upload-labs)

目录 Pass-01(前端绕过) &#xff08;1&#xff09;JavaScript &#xff08;2&#xff09;Burpsuite&#xff08;改后缀&#xff09; Pass-02&#xff08;IMME类型 &#xff09; burpsuite&#xff08;改文件类型&#xff09; Pass-03&#xff08;黑名单绕过&#xff09; …...

图片的拖拽+缩放

效果图&#xff1a; <script setup lang"ts"> import { onMounted, ref } from vue; import ImgBg from /assets/img/bg.jpg import Img1 from /assets/img/1.jpgconst innerStyle ref({left: 0,top: 0,width: 100,height: 0 }) const wrapStyle ref({width:…...

Windows软件插件-音视频文件读取器

下载本插件 本插件读取音频和视频文件&#xff0c;输出音频样本和视频样本&#xff0c;音频样本为16位PCM&#xff0c;采样率48000&#xff1b;视频样本为RGB32。大部分音频和视频文件格式都可以读取。本插件类型为DLL。 本插件是通过创建媒体基础“源读取器”对象实现读取音视…...

考研数一复习之拉格朗日中值定理求解函数极限

最近在复习考研数学,只是简单做题过于乏味,因此便总结了一些笔记,后续若有空,也会将自己的复习笔记分享出来。本篇&#xff0c;我们将重点讲解拉格朗日中值定理在求解函数极限中的应用。同时,作者本人作为python领域创作者&#xff0c;还将在本文分享使用sympy求解高数中函数极…...

聊天服务器分布式改造

目前的聊天室是单节点的&#xff0c;无论是http接口还是socket接口都在同一个进程&#xff0c;无法承受太多人同时在线&#xff0c;容灾性也非常差。因此&#xff0c;一个成熟的IM产品一定是做成分布式的&#xff0c;根据功能分模块&#xff0c;每个模块也使用多个节点并行部署…...

C++11的一些特性

目录 一、C11简介 二、统一的列表初始化 2.1 &#xff5b;&#xff5d;初始化 2.2 std::initializer_list 三、声明 3.1 auto 3.2 decltype 3.3 nullptr 四、范围for循环 五、智能指针 5.1 RAII 5.2 智能指针的原理 5.3 std::auto_ptr…...

【打卡day3】字符串类

例如统计字符个数&#xff0c;字符大小写转换 题目描述&#xff1a;输入一行字符串&#xff0c;计算A-Z大写字母出现的次数 思路&#xff1a; 1 定义一个整型数组&#xff0c;初始化为0&#xff0c;存储每个字母出现的次数&#xff0c;下标0对应字母A, 2&#xff0c;定义字…...

图像滑块对比功能的开发记录

背景介绍 最近&#xff0c;公司需要开发一款在线图像压缩工具&#xff0c;其中的一个关键功能是让用户直观地比较压缩前后的图像效果。因此&#xff0c;我们设计了一个对比组件&#xff0c;它允许用户通过拖动滑块&#xff0c;动态调整两张图像的显示区域&#xff0c;从而清晰…...

【音视频】ffplay常用命令

一、 ffplay常用命令 -x width&#xff1a;强制显示宽度-y height&#xff1a;强制显示高度 强制以 640*360的宽高显示 ffplay 2.mp4 -x 640 -y 360 效果如下 -fs 全屏显示 ffplay -fs 2.mp4效果如下&#xff1a; -an 禁用音频&#xff08;不播放声音&#xff09;-vn 禁…...

初识Linux

文章目录 初识Linux&#xff1a;从开源哲学到技术生态的全面解析一、Linux的背景与发展简史&#xff1a;从代码实验到数字基础设施1.1 起源与开源基因1.2 技术哲学之争1.3 GNU/Linux的融合 二、开源&#xff1a;Linux的核心竞争力与生态力量2.1 法律保障与四大自由2.2 社区协作…...

基于遗传算法的IEEE33节点配电网重构程序

一、配电网重构原理 配电网重构&#xff08;Distribution Network Reconfiguration, DNR&#xff09;是一项优化操作&#xff0c;旨在通过改变配电网中的开关状态&#xff0c;优化电力系统的运行状态&#xff0c;以达到降低网损、均衡负载、改善电压质量等目标。配电网重构的核…...

manus对比ChatGPT-Deep reaserch进行研究类学术相关数据分析!谁更胜一筹?

没有账号&#xff0c;只能挑选一个案例 一夜之间被这个用全英文介绍全华班出品的新爆款国产AI产品的小胖刷频。白天还没有切换语言的选项&#xff0c;晚上就加上了。简单看了看团队够成&#xff0c;使用很长实践的Monica创始人也在其中。逐渐可以理解&#xff0c;重心放在海外产…...

线程通信---java

线程 我们知道&#xff0c;线程是进程的最小执行单位&#xff0c;一个进程可以拥有多个线程&#xff0c;那么就会引入两个问题&#xff1a; 多个线程之间如何进行通信多个线程对同一个数据进行操作&#xff0c;如何保证程序正确执行&#xff0c;也就是线程安全问题 线程的常…...

python面试常见题目

1、python 有几种数据类型 数字:整形 &#xff08;int&#xff09;,浮点型 &#xff08;float&#xff09;布尔 &#xff08; bool&#xff09;:false true字符串 &#xff08;string&#xff09;列表 &#xff08;list&#xff09;元组 &#xff08;tuple&#xff09;字典 &…...

Python中与字符串操作相关的30个常用函数及其示例

以下是Python中与字符串操作相关的30个常用函数及其示例&#xff1a; 1. str.capitalize() 将字符串的第一个字符大写&#xff0c;其余字符小写。 s "hello world" print(s.capitalize()) # 输出: Hello world2. str.lower() 将字符串中的所有字符转换为小写。…...

2025年渗透测试面试题总结-小某鹏汽车-安全工程师(题目+回答)

网络安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 小鹏汽车-安全工程师 一、XXE漏洞与SSRF漏洞 1. XXE&#xff08;XML External Entity&#xff09;漏洞…...

kafka + flink +mysql 案例

假设你有两个Kafka主题&#xff1a;user_activities_topic 和 product_views_topic&#xff0c;并且你希望将user_activities_topic中的数据写入到user_activities表&#xff0c;而将product_views_topic中的数据写入到product_views表。 maven <dependencies><!-- …...

Windows下配置Flutter移动开发环境以及AndroidStudio安装和模拟机配置

截止 2025/3/9 &#xff0c;版本更新到了 3.29.1 &#xff0c;但是为了防止出现一些奇怪的bug&#xff0c;我安装的还是老一点的&#xff0c;3.19&#xff0c;其他版本的安装同理。AndroidStudio用的是 2024/3/1 版本。 — 1 环境变量&#xff08;Windows&#xff09; PUB_H…...

【工具类】Springboot 项目日志打印项目版本和构建时间

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

p5.js:模拟 n个彩色小球在一个3D大球体内部弹跳

向 豆包 提问&#xff1a;编写一个 p5.js 脚本&#xff0c;模拟 42 个彩色小球在一个3D大球体内部弹跳。每个小球都应留下一条逐渐消失的轨迹。大球体应缓慢旋转&#xff0c;并显示透明的轮廓线。请确保实现适当的碰撞检测&#xff0c;使小球保持在球体内部。 cd p5-demo copy…...

RISC-V医疗芯片工程师复合型转型的路径与策略

从RISC-V到医疗芯片:工程师复合型转型的路径与策略 一、引言 1.1 研究背景 在科技快速发展的当下,芯片技术已然成为推动各行业进步的核心驱动力之一。其中,RISC-V 架构作为芯片领域的新兴力量,正以其独特的优势迅速崛起,对整个芯片产业的格局产生着深远影响。RISC-V 架…...

HTML 文本格式化

HTML 文本格式化 在构建网页的过程中&#xff0c;文本的格式化是一个至关重要的环节。HTML&#xff08;HyperText Markup Language&#xff09;提供了丰富的标签和属性来帮助我们实现各种文本格式化的需求。本文将详细介绍HTML中常见的文本格式化方法&#xff0c;包括字体、颜…...

基于RNN+微信小程序+Flask的古诗词生成应用

项目介绍 平台采用B/S结构&#xff0c;后端采用主流的Flask框架进行开发&#xff0c;古诗词生成采用RNN模型进行生成&#xff0c;客户端基于微信小程序开发。是集成了Web后台开发、微信小程序开发、人工智能&#xff08;RNN&#xff09;等多个领域的综合性应用&#xff0c;是课…...

【算法】图论 —— Dijkstra算法 python

引入 求非负权边的单源最短路 时间复杂度 O( m l o g n mlogn mlogn) 模板 https://www.luogu.com.cn/problem/P4779 import heapq as hq def dijkstra(s): # dis表示从s到i的最短路 dis [float(inf)] * (n 1) # vis表示i是否出队列 vis [0] * (n 1) q [] dis[s…...

Java:LocalDatTime(代替Calendar)、ZoneDateTime(时区时间)

文章目录 Local(代替Calendar)方法&#xff1a;获取当前代码 LocalDate&#xff08;年月日星期&#xff09;LocalTime&#xff08;时分秒纳秒&#xff09;LocalDateTime(最常用&#xff1a;年月日时分秒纳秒)ZoneId 时区表示方法 ZoneDateTime(时区时间)方法世界标准时间&#…...

HOW - React 如何在在浏览器绘制之前同步执行 - useLayoutEffect

目录 useEffect vs useLayoutEffectuseEffectuseLayoutEffect主要区别总结选择建议注意事项 useLayoutEffect 使用示例测量 DOM 元素的尺寸和位置示例&#xff1a;自适应弹出框定位 同步更新样式以避免闪烁示例&#xff1a;根据内容动态调整容器高度 图像或 Canvas 绘制前的准备…...

PyTorch系列教程:编写高效模型训练流程

当使用PyTorch开发机器学习模型时&#xff0c;建立一个有效的训练循环是至关重要的。这个过程包括组织和执行对数据、参数和计算资源的操作序列。让我们深入了解关键组件&#xff0c;并演示如何构建一个精细的训练循环流程&#xff0c;有效地处理数据处理&#xff0c;向前和向后…...

VS2019,VCPKG - 为VS2019添加VCPKG

文章目录 VS2019,VCPKG - 为VS2019添加VCPKG概述笔记前置条件迁出vcpkg到本地验证库安装更新已经安装的库删除指定的包安装VS2019能用的boostvcpkg 2025.02.14 版本可以给VS2019用用VCPKG的好处备注END VS2019,VCPKG - 为VS2019添加VCPKG 概述 开源工程用到了VCPKG管理的包。…...

linux下 jq 截取json文件信息

背景&#xff1a;通过‘登录名‘ 获取该对象的其他个人信息如名字。 环境准备&#xff1a;麒麟操作系统V10 jq安装包 jq安装包获取方式&#xff1a;yum install jq 或 使用附件中的rpm 或 git自行下载 https://github.com/stedolan/jq/releases/download/ 实现过程介绍&am…...

测试大语言模型在嵌入式设备部署的可能性-ollama本地部署测试

前言 当今各种大语言模型百花齐放&#xff0c;为了方便使用者更加自由的使用大模型&#xff0c;将大模型变成如同棒球棍一样每个人都能用&#xff0c;并且顺手方便的工具&#xff0c;本地私有化具有重要意义。 本次测试使用ollama完成模型下载&#xff0c;过程简单快捷。 1、进…...

C语言基础系列【21】memcpy、memset

博主介绍&#xff1a;程序喵大人 35- 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章&#xff0c;首发gzh&#xff0c;见文末&#x1f447;&#x1f…...

云曦春季开学考复现(2025)

Crypto 划水的dp和dq 下载附件后是简单的RSA算法题&#xff0c;之所以说简单是因为给了公钥e 趁热打铁&#xff0c;昨天刚学的RSA&#xff0c;既然有p有q&#xff0c;也有e&#xff0c;而np*q&#xff0c;可以算出欧拉函数值phi&#xff08;p-1&#xff09;*&#xff08;q-1&…...

探秘 Netty 通信中的 SslHandler 类:保障网络通信安全的基石

引言 在当今数字化时代&#xff0c;网络安全是每一个应用程序都必须重视的关键因素。尤其是在数据传输过程中&#xff0c;防止数据被窃取、篡改至关重要。Netty 作为一个高性能的网络编程框架&#xff0c;为开发者提供了强大的功能来构建可靠的网络应用。其中&#xff0c;SslH…...

Llama factory微调后的模型怎么通过ollama发布

接上一篇博客:用Llama Factory单机多卡微调Qwen2.5时报torch.OutOfMemoryError: CUDA out of memory的解决办法_llama-factory cuda out of memory-CSDN博客 把Lora模块和其基模型merge到一起之后,就可以通过ollama之类的框架提供服务了。不过还是有些格式转换的工作要做: …...

ubuntu 20.04下ZEDmini安装使用

提前安装好显卡驱动和cuda&#xff0c;如果没有安装可以参考我的这两篇文章进行安装&#xff1a; ubuntu20.04配置YOLOV5&#xff08;非虚拟机&#xff09;_ubuntu20.04安装yolov5-CSDN博客 ubuntu20.04安装显卡驱动及问题总结_乌班图里怎么备份显卡驱动-CSDN博客 还需要提前…...

CmBacktrace的学习跟移植思路

学习移植CmBacktrace需要从理解其核心功能、适用场景及移植步骤入手&#xff0c;结合理论学习和实践操作。以下是具体的学习思路与移植思路&#xff1a; 一、学习思路 理解CmBacktrace的核心功能 CmBacktrace是针对ARM Cortex-M系列MCU的错误追踪库&#xff0c;支持自动诊断Har…...

Android Glide 缓存模块源码深度解析

一、引言 在 Android 开发领域&#xff0c;图片加载是一个极为常见且关键的功能。Glide 作为一款被广泛使用的图片加载库&#xff0c;其缓存模块是提升图片加载效率和性能的核心组件。合理的缓存机制能够显著减少网络请求&#xff0c;降低流量消耗&#xff0c;同时加快图片显示…...

蓝桥杯备赛:炮弹

题目解析 这道题目是一道模拟加调和级数&#xff0c;难的就是调和级数&#xff0c;模拟过程比较简单。 做法 这道题目的难点在于我们在玩这个跳的过程&#xff0c;可能出现来回跳的情况&#xff0c;那么为了解决这种情况&#xff0c;我们采取的方法是设定其的上限步数。那么…...

死锁问题分析工具

使用 gdb 调试 gdb ./your_program (gdb) run (gdb) thread apply all bt还可以分析pthread_mutex内部&#xff0c;查看owen字段分析哪个线程占用的锁&#xff0c;一个可能的 pthread_mutex 内部结构可以大致表示为&#xff1a; typedef struct pthread_mutex_t {int state; …...

装饰器模式--RequestWrapper、请求流request无法被重复读取

目录 前言一、场景二、原因分析三、解决四、更多 前言 曾经遇见这么一段代码&#xff0c;能看出来是把request又重新包装了一下&#xff0c;核心信息都不会改变 后面了解到这叫 装饰器模式&#xff08;Decorator Pattern&#xff09; &#xff1a;也称为包装模式(Wrapper Pat…...

MTK Android12 桌面上显示文件管理器图标

文章目录 需求解决 需求 在MTK平台上&#xff0c;Android12的文件管理器图标未显示在桌面&#xff0c;但在设置里面可以看到&#xff0c;文件管理器是安装的。根据客户要求&#xff0c;需要将文件管理器的图标显示在桌面上。解决 路径&#xff1a;packages/apps/DocumentsUI/…...

SpringBoot实现文件上传

1. 配置文件上传限制 application.yml spring:servlet:multipart:max-file-size: 10MBmax-request-size: 10MB2. 创建文件上传控制器 import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import…...

【开源免费】基于SpringBoot+Vue.JS青年公寓服务平台(JAVA毕业设计)

本文项目编号 T 233 &#xff0c;文末自助获取源码 \color{red}{T233&#xff0c;文末自助获取源码} T233&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

django中视图作用和视图功能 以及用法

在 Django REST Framework(DRF)中,视图(View)是处理 HTTP 请求并返回响应的核心组件。DRF 提供了多种视图类,适用于不同的场景和需求。以下是 DRF 中常见的视图类及其作用、使用方法的详细说明: 一、DRF 视图的分类 DRF 的视图可以分为以下几类: 基于函数的视图(Func…...

大语言模型在患者交互任务中的临床使用评估框架

An evaluation framework for clinical use of large language models in patient interaction tasks An evaluation framework for clinical use of large language models in patient interaction tasks | Nature Medicine 2025.1 收到时间&#xff1a;2023 年 8 月 8 日 …...

Python—类class复习

Python——类&#xff08;class&#xff09;复习 根据类来创建对象的方法被称为实例化 因此学会使用类&#xff08;class&#xff09;来进行编程就是初步进入面向对象编程的大门 1.1 创建和使用类 首先编写一个小狗的简单类Dog&#xff0c;它表示的不是特定的小狗&#xff…...

QT | 信号与槽(超详解)

前言 对qt信号和槽的详细解释 &#x1f493; 个人主页&#xff1a;普通young man-CSDN博客 ⏩ 文章专栏&#xff1a;C_普通young man的博客-CSDN博客 ⏩ 本人giee: 普通小青年 (pu-tong-young-man) - Gitee.com 若有问题 评论区见&#x1f4dd; &#x1f389;欢迎大家点赞&am…...

Codecraft-17 and Codeforces Round 391 E. Bash Plays with Functions 积性函数

题目链接 题目大意 定义函数 f r ( n ) f_r(n) fr​(n) : 在 r 0 r0 r0时&#xff0c;为满足 p p p ⋅ \cdot ⋅ q n qn qn , 且 g c d ( p , q ) 1 gcd(p,q)1 gcd(p,q)1 的有序对 ( p , q ) (p,q) (p,q) 个数&#xff1b;在 r r r ≥ \geq ≥ 1 1 1时&#xff0…...

粉尘环境下的智能生产革命 ——助力矿山行业实现高效自动化作业

在矿山开采领域&#xff0c;运输系统是保障生产连续性的核心环节。然而&#xff0c;粉尘弥漫、环境恶劣、设备分散等问题&#xff0c;长期制约着矿山运输的效率与安全性。传统的集中式控制系统难以适应复杂工况&#xff0c;而远程分布式 IO 模块与 PLC 的深度融合&#xff0c;正…...

更新vscode ,将c++11更新到c++20

要在CentOS系统中安装最新版本的GCC&#xff0c;你可以使用SCL&#xff08;Software Collections&#xff09;仓库&#xff0c;它提供了开发工具的最新版本。以下是安装步骤&#xff1a; 1、 添加SCL仓库&#xff1a; 首先&#xff0c;添加CentOS的SCL仓库&#xff0c;该仓库…...