upload-labs (更新至Pass-12

Pass-01

前端 js 绕过
设置禁用 java

Copy
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;
}
}

Pass-02

MME 验证
上传文件后缀如上
进行抓包
修改 Content-Type 类型
把 application/octet-stream 改成 image/png
即可上传

Copy
$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.'文件夹不存在,请手工创建！';
}
}

Pass-03

绕过黑名单
抓包，修改后缀后，可直接上传
但无法连接
后缀字母大写也无法上传，
可用 php1、pht、phtml、phps 绕过黑名单
根据网页源码找到文路径
连接 shell

Copy
$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); //收尾去空

Pass-04

绕过黑名单 -.htaccess

.htaccess

.htaccess 是 Apache 服务的一个配置文件，负责相关目录下的网页配置
可实现网页 301 重定向、自定义 404 错误页面、改变文件扩展名、允许 / 阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
其中.htaccess 文件内容：
SetHandler application/x-httpd-php
设置当前目录所有文件都使用 PHP 解析，那么无论上传任何文件，只要文件内容符合 PHP 语言代码规范，就会被当作 PHP 执行。不符合则报错。
故先上传一个.htaccess 的配置文件
然后在上传一字木马
连接 shell

Copy
$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");
$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); //收尾去空

Pass-05

大写绕过
通过混合随机大小写可绕过

Copy
$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 = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

Copy
$file_ext = strtolower($file_ext); //转换为小写

Pass-06

空格绕过
原理：Windows 系统下，对于文件名中空格会被作为空处理，程序中的检测代码却不能自动删除空格。从而绕过黑名单。
于是进行抓包，在文件后缀添加一个空格
成功绕过

Copy
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 = $_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

Copy
$file_ext = trim($file_ext); //首尾去空

Pass-07

. 号绕过
在后缀加上。成功绕过

Copy
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_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

Copy
$file_name = deldot($file_name);//删除文件名末尾的点

Pass-08

::$DATA 绕过
原理：在 window 的时候如果文件名 +"::$DATA" 会把::$DATA 之后的数据当成文件流处理，不会检测后缀名，且保持::$DATA 之前的文件名，他的目的就是不检查后缀名。如同空格一般

Copy
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 = trim($file_ext); //首尾去空

Copy
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

Pass-09

看看源码，抓包修改后缀
在 php 后缀加上 '. .‘
成功上传

Copy
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); //首尾去空

GPT 分析:
该 PHP 代码主要进行文件上传，先判断是否有通过 POST 请求提交表单的数据（是否点击了 submit 按钮），然后检查上传目录是否存在，并定义一个不允许上传的文件类型数组deny_ext。接着获取用户上传的文件名并删除末尾的点。接下来通过strrchr函数获取文件的扩展名，再将其转换为小写、去除字符串::DATA。接着获取用户上传的文件名并删除末尾的点。接下来通过 strrchr 函数获取文件的扩展名，再将其转换为小写、去除字符串::DATA、首尾去空格，以确保文件扩展名的一致性。最终可以根据这些信息来确定是否允许上传该文件，如果文件类型在 $deny_ext 数组中，则不允许上传，否则可以上传。

Pass-10

根据提示可知，本 pass 会从文件名中去除
即若上传以上后缀的文件，将会自动删除
例如 hack.php -->hack 后缀消失。
但只消除一次，利用双写字母即可绕过
双写格式应为 pphphp

Copy
$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");

$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;

ChatGPT：这段代码的原理是用于限制文件类型的上传以保护应用程序安全机制。该代码将定义一个名为 "$ deny_ext" 的数组，其中列出了不允许用户上传的文件类型。在上传文件之前，代码将获取上传文件的名称，将该名称的所有在 "{$deny_ext}" 数组中列出的文件类型从名称中移除，并将更改后的文件名重新赋值给 "$file_name" 变量。

接下来，代码将从 $ _FILES ['upload_file']['tmp_name'] 变量中获取临时文件的路径，并将它移动至 "$_SERVER ['DOCUMENT_ROOT'] . UPLOAD_PATH . '/' . $file_name" 目录中。此时，如果移动过程成功，应用程序将在以下的代码中标记上传已完成 （ $is_upload = true;），如果移动过程失败，应用程序将输出错误信息（ $msg = ' 上传出错！';）。

Pass-11 GET 00 截断

什么是 00 截断
无论是 0x00 还是 %00，最终被解析后都是一个东西： chr（0）
chr () 是一个函数，这个函数是用来返回参数所对应的字符的，也就是说，参数是一个 ASCII 码，返回的值是一个字符，类型为 string。
chr (0) 对应 NULL（空字符）
当一个字符串中存在空字符的时候，在被解析的时候会导致空字符后面的字符被丢弃
使用 00 截断的情况:

路径拼接直接使用的 $file_name 这个文件名

文件路径可控
根据提示可知上传路径可控
那么找到文件上传路径

Copy
<?php
include '../config.php';
include '../head.php';
include '../menu.php';
$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类型文件！";
}
}
?>

GPT 分析:
这段 PHP 代码包含了一个简单的文件上传功能：

首先，通过 include 语句引入了 config.php、head.php 和 menu.php 等其它文件。

接着，程序检查是否有 POST 数据提交，如果有，则继续执行；否则不做任何操作。

这里定义了一个允许上传的文件类型数组 $ext_arr，包含三种文件类型：jpg、png 和 gif。后面会用到。

程序通过 $_FILES 数组获取上传的文件名，并将其扩展名存储在变量 $file_ext 中。

如果 $file_ext 在 $ext_arr 数组中，则说明上传的文件类型符合要求，可以进行上传操作。

将临时文件存储在 $temp_file 变量中，并使用 rand () 函数生成一个随机数和当前日期时间作为新文件名，再加上原来的文件扩展名作为文件路径，存储在 $img_path 变量中。

使用 move_uploaded_file () 函数进行文件上传操作，如果上传成功，则 is_upload 变量设置为 true；否则，msg 变量设置为 "上传出错！"。

如果文件类型不符合要求，则 $msg 变量设置为 "只允许上传.jpg|.png|.gif 类型文件！"。

Pass-12 POST 00 截断

同样是 00 截断，但是 POST
通过 burp 抓包
通过 hex 修改
把 %00 的 hex 值改为 00000
即可上传