🧪 Upload Lab

官网:[Git Hub]

upload-labs 是一个使用 php 语言编写的,专门收集渗透测试和 CTF 中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共 20 关,每一关都包含着不同上传方式。

🎈 靶机包含漏洞类型分类

🎈 如何判断上传漏洞类型?


🎠 一句话木马

请参考下面的文章

https://blog.uash.xyz/archives/jgfZ5zTd

🕐 Pass-01

🔍 源码解析

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

💡 关键代码

js 源码中变量 allow_ext 定义了白名单

var allow_ext = ".jpg|.png|.gif";

且 if 语句只允许 .jpg|.png|.gif 后缀文件上传,判断为前端过滤。

if (allow_ext.indexOf(ext_name + "|") == -1) {
        var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
        alert(errMsg);
        return false;
    }

🧠 思路

  1. php 文件无法上传;

  2. 可以上传 png 文件;

  3. 弹窗提示:该文件不允许上传,请上传.jpg|.png|.gif类型的文件,当前文件类型为:.php 说明有白名单;

  4. 且 bp 可以抓到包,修改后可上传,前端过滤。

🛠️ 解题方法

💡 方法一

使用浏览器禁用 js 后直接上传 php 文件。

💡 方法二

将木马文件后缀改为 png 后上传,使用 bp 抓包,将后缀名改回 php 后放行即可。

🕑 Pass-02

🔍 源码解析

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

💡 关键代码

$_FILES['upload_file']['type'] == 'image/jpeg') 

通过检测 content-type 判断上传文件内容

  • content-type:通常是 HTTP 协议中用于标识消息主体内容类型的头部字段。在文件上传场景里,当客户端(如浏览器)向服务器发送文件时,会在请求头中包含 content-type 字段,用来告知服务器所发送内容的类型。不过在 PHP 中处理文件上传时, $_FILES['upload_file']['type'] 本质上是客户端在上传文件时提供的 MIME 类型信息,虽然和 content-type 有一定关联,但它并非直接的 content-type 字段。

$_FILES 超全局变量

  • 在 PHP 里,当通过 HTML 表单上传文件时,上传的文件信息会被存储在 $_FILES 这个超全局变量中。$_FILES 是一个二维数组,其键名是 HTML 表单中 input 元素的 name 属性值。例如,若 HTML 表单中有一个 input 元素的 name 属性值为 upload_file,那么上传文件的相关信息就会存储在 $_FILES['upload_file'] 中。

$_FILES['upload_file']['type']

表示上传文件的 MIME 类型。

  • MIME(Multipurpose Internet Mail Extensions)类型是一种标准,用于表示文档、文件或字节流的性质和格式。在文件上传的场景中,它可以帮助我们识别上传文件的具体类型,比如图片、文本、音频等。

条件判断的意义

  • ($_FILES['upload_file']['type'] == 'image/jpeg') 这个条件判断会检查上传文件的 MIME 类型是否为 image/jpeg,也就是判断上传的文件是否为 JPEG 格式的图像。如果是,则条件成立,返回 true;如果不是,则条件不成立,返回 false

🧠 思路

  1. 可以上传 png 文件;

  2. bp 可以抓到包,修改后缀无效,后端过滤;

  3. 上传 php 提示:文件类型不正确,请重新上传!

  4. 看到文件类型不对,可以想到是 MIME 类型。

🛠️ 解题方法

💡 方法一

将 php 木马文件上传,使用 bp 抓包,将 MIME 信息改成 image/jpeg 后上传即可

💡 方法二

同第一题方法二,将木马文件后缀改为 png(此时 MIME 会自动识别为 image/png)后上传,使用 bp 抓包,将后缀名改回 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 . '文件夹不存在,请手工创建!';
    }
}

💡 关键函数

trim()

用于去除字符串首尾的空白字符。

在代码中,trim($_FILES['upload_file']['name']) 用于去除上传文件名首尾的空白字符。

strrchr()

用于查找字符串中最后一次出现某个字符的位置,并返回从该位置到字符串末尾的所有字符。

在代码中,strrchr($file_name, '.') 用于获取上传文件的扩展名。

strtolower()

用于将字符串转换为小写。代码中使用它将文件扩展名转换为小写,以便进行不区分大小写的比较。

str_ireplace()

用于在字符串中进行不区分大小写的替换操作。

在代码中,str_ireplace('::$DATA', '', $file_ext) 用于去除文件扩展名中的 ::$DATA 字符串,这是为了防止 Windows 系统下的 NTFS 流攻击。

🧠 思路

  1. bp 可以抓到包,修改后缀无效,后端过滤;

  2. 上传 php 获取到 提示:不允许上传.asp,.aspx,.php,.jsp后缀文件! 是一个黑名单;

  3. 后缀修改为 PHP、Php 皆不可,说明有转小写或者别的什么;

  4. 后缀修改为 pphphp 上传成功但是没对 php 进行过滤上传文件后缀就是 pphphp。

🛠️ 解题方法

💡 前提条件

需要修改配置 apache/nginx(取决于你的选择)的配置文件,对特殊后缀进行解析。

💡 特殊后缀绕过

后缀修改为 php3、php5、phtml 等后缀皆可(前提要对特殊后缀进行解析)。

🕓 Pass-04

🔍 源码解析

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

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

代码跟上一题一样,但是基本能想到的特殊后缀都被过滤了。

🧩 前置知识

以下内容基于 Apache

.htaccess 文件

  • 作用:分布式配置文件,一般用于 url 重写、认证、控制访问等

  • 作用范围:特定目录(一般是网站根目录),及其子目录

  • 优先级:较高,可覆盖 apache 的主要配置文件(httpd-conf)

  • 生效方式:修改后立刻生效

httpd-conf 文件

  • 作用:包含 apache·HTTP 服务器的全局行为和默认设置

  • 作用范围:整个服务器

  • 优先级:较低

  • 生效方式:管理员权限,重启服务器后生效

Apache 服务器中 AllowOverride 指令用于指定 .htaccess 文件可以覆盖哪些服务器配置。它的取值决定了用户通过 .htaccess 文件对服务器设置的控制程度

AllowOverride 的常用值说明如下

None:这是最严格的设置。当设置为 None 时,服务器将完全忽略并不允许 .htaccess 文件覆盖任何配置选项。这通常是为了提升性能和安全性。

All:这是最宽松的设置。当设置为 All 时,服务器允许 .htaccess 文件覆盖所有配置选项。这给予了目录最大的灵活性,但也需要更高的安全关注。

AuthConfig:此选项允许 .htaccess 文件覆盖与身份验证(Authorization) 相关的配置选项。常用的指令包括 AuthType、AuthName、AuthUserFile 等,常用于设置目录的密码保护。

FileInfo:此选项允许 .htaccess 文件覆盖与文件和文档类型 相关的配置选项。常用的指令包括 DirectoryIndex(默认首页)、DefaultType(默认 MIME 类型)、ErrorDocument(自定义错误页面)等。

Indexes:此选项允许 .htaccess 文件覆盖与目录索引(Indexing) 相关的配置选项。常用的指令包括 Options(用于启用或禁用目录列表等功能)、IndexOptions、IndexIgnore 等,这些指令控制着当目录中没有默认文件时,如何向访问者显示文件列表。

Limit:此选项允许 .htaccess 文件覆盖与访问控制(Access Control) 相关的配置选项,例如 Require 指令,可以基于 IP 地址、用户等因素来限制对目录的访问。

Options:此选项允许 .htaccess 文件覆盖与目录特性(Options) 相关的配置选项,主要是指 Options 指令本身,用于启用或禁用特定的目录功能,例如是否允许执行 CGI 脚本、是否支持服务器端包含(SSI)等。

🧠 思路

  1. bp 可以抓到包,修改后缀无效,后端过滤;

  2. 可以上传 png 文件

  3. 使用上一题思路发现无解,特殊后缀都被过滤了 提示:此文件不允许上传!

  4. 可以上传 .htaccess 文件;

🛠️ 解题方法

创建一个.htaccess 文件,写入以下内容(二选一)

AddType application/x-httpd-php .jpg .txt // 将txt文件与jpg文件当作php文件解析(其他没被过滤的文件后缀皆可)
AddType application/x-httpd-php           // 不写后缀则表示所有文件都将解析为php文件

上传.htaccess 文件后,再修改木马文件后缀为 .jpg/.txt 进行上传

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

这次和上一题差不多,但是大小写没被过滤

🧩 前置知识

针对大写绕过,Windows 大小写不敏感,Linux 大小写敏感(无法解析大写 Php),所以要看看目标服务器是什么系统

🧠 思路

  1. bp 可以抓到包,修改后缀无效,后端过滤;

  2. 依旧 提示:此文件类型不允许上传!

  3. 这次 .htaccess 文件也无法上传了;

  4. 发现大写 PHP 可以上传。

🛠️ 解题方法

💡 方法一:大小写绕过(Windows 限定)

直接将后缀改成 Php、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");
        $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
        
        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 . '文件夹不存在,请手工创建!';
    }
}

这次是少了个首尾去空

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

🧩 前置知识

window 中保存文件时,会将后缀名后面的空格去掉后保存

也就是.php ==>.php(第一个 php 后面有空格)

linux 中保存文件时,会保留空格

🧠 思路

  1. 可以上传 png 文件;

  2. bp 可以抓到包,修改后缀无效,后端过滤;

  3. 特殊后缀(大小写双写)无法上传;

  4. .htaccess 文件无法上传;

  5. 尝试空格绕过。

🛠️ 解题方法

💡 方法一:空格绕过 (Windows 限定)

将 [php] 后缀改为 [.php] 后上传

💡方法二

🕖 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");
        $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);//删除文件名末尾的点

🧩前置知识

window 中,会将后缀名之后的点去掉

如.php. ==> .php

但是如果是 a.txt.php 最后会被识别成 php 文件

🧠 思路

  1. 可以上传 png 文件;

  2. bp 可以抓到包,修改后缀无效,后端过滤;

  3. 特殊后缀(大小写双写)无法上传;

  4. .htaccess 文件无法上传;

  5. 尝试空格绕过无解;

  6. 尝试在末尾加点;

🛠️ 解题方法

💡 方法一(Windows 限定)

将 [php] 后缀改为 [.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");
        $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

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

🧩 前置知识

🧠 思路

  1. 可以上传 png 文件;

  2. bp 可以抓到包,修改后缀无效,后端过滤;

  3. 特殊后缀(大小写双写)无法上传;

  4. .htaccess 文件无法上传;

  5. 尝试空格绕过无解;

  6. 尝试在末尾加点无解;

  7. 利用 NTFS 特性

🛠️ 解题方法

💡 方法一(Windows 限定)

上传 php 文件后抓包修改后缀为.php::$DATA,验证时不匹配黑名单绕过过滤,成功上传后,系统则根据 NTFS 规则,自动忽略文件后的::$DATA,将其解释为 php 文件

注意连接时要删去::$DATA 后缀

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

🧠 思路

🛠️ 解题方法

🕙 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","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;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

🧠 思路

  1. 可以上传 png 文件;

  2. bp 可以抓到包,修改后缀无效,后端过滤;

  3. 双写可以上传。

🛠️ 解题方法

💡双写绕过

抓包修改后缀为.pphphp,中间的 php 会被识别过滤,剩下的 p 与 hp 又组成了.php 后缀,是文件得以正常执行

注意系统识别是从左往右扫描,所以只能写成.pphphp

如果写成.phphpp 则会被去掉前面的 php,导致后缀变成.hpp

🕚 Pass-11

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕛 Pass-12

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕐 Pass-13

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕑 Pass-14

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕒 Pass-15

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕓 Pass-16

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕔 Pass-17

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕕 Pass-18

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕖 Pass-19

🔍 源码解析

🧠 思路

🛠️ 解题方法

🕗 Pass-20

🔍 源码解析

🧠 思路

🛠️ 解题方法

参考文献

https://www.cnblogs.com/xuanxian/articles/19145657

https://blog.csdn.net/2302_80442799/article/details/1538489933