....//绕过str_replace过滤→php://filter读源码→目录穿越读/flag
四、WEB-Enterprise_OA
|
题目名称 |
OA 系统目录穿越 |
|
题目难度 |
初级 |
|
题目分类 |
WEB |
|
题目分值 |
250 |
|
漏洞类型 |
PHP 文件包含 + 目录穿越 + 伪协议 |
◆ 题目描述
这是一道第十届御网杯网络安全线上挑战赛的 PHP 目录穿越题目。页面显示一个企业 OA 系统,包含公告、关于我们、联系方式等模块。通过观察 URL 参数发现,页面通过 ?module=xxx.php 来动态加载不同的模块文件,这是典型的文件包含入口。

◆ 信息收集
访问靶机首页,观察 HTML 结构中的导航链接:
<div class="nav">
<a href="?module=public_notices.php">Notices</a>
<a href="?module=about.php">About Us</a>
<a href="?module=contact.php">Contact</a>
</div>
从 HTTP 响应头可以确认服务器环境为 Apache/2.4.51 + PHP/7.4.27。关键发现:页面通过 ?module=xxx.php 参数动态加载不同的 PHP 模块文件,这是典型的文件包含(LFI)入口。
◆ 源码审计 — 读取核心代码

使用 php://filter 伪协议读取 index.php 源码:
?module=php://filter/convert.base64-encode/resource=index.php
将响应中的 Base64 字符串解码后,得到以下核心代码:
|
php — index.php 核心代码 <?php $module = isset($_GET['module']) ? $_GET['module'] : 'public_notices.php'; $module = str_replace('../', '', $module); ?> ... <div class="content"> <?php include($module); ?> </div> |
以上就是漏洞的全部核心。程序使用 str_replace('../', '', $module) 来过滤路径穿越,但这个过滤存在一个非常经典的绕过方式。过滤后的 $module 被直接传入 include() 执行,形成了完整的文件包含漏洞。
◆ 漏洞分析 — str_replace 绕过原理

这道题的核心难点在于绕过 str_replace('../', '', $module) 这个过滤。很多人可能会觉得 str_replace 已经把 ../ 删掉了,应该安全了才对。但实际上,str_replace 只做一次性的简单字符串替换,不是递归的。这就意味着我们可以通过精心构造输入,让它删除一部分后,剩余的部分拼接起来刚好又是一个有效的 ../ 。
绕过原理图解
关键思路是构造 ....// 这样的输入:
|
输入 |
过滤后 |
说明 |
|
../ |
“” (空字符串) |
直接被删除 |
|
....// |
../ |
中间的 ../ 被删除,剩余部分拼接成 ../ |
|
....//....// |
../../ |
两组绕过,得到两层穿越 |
更直观的图解如下:
|
输入: ....// ↑↑↑↑ 删除中间的 "../" 剩下: ../ ← 恰好构成一个有效的路径穿越 |
这个绕过的本质原理是:str_replace 是从左到右单次扫描替换的。当它遇到 ....// 时,会匹配到中间的 ../ 并将其删除,剩下的 .. 和 / 拼接在一起,刚好又形成了一个新的 ../ 。而因为 str_replace 不会再次扫描,这个新的 ../ 就被保留下来了。
|
❗ 核心知识点:PHP str_replace 只做单次替换,不是递归的,可被 ....// 绕过。安全做法是使用 realpath() 白名单检查。 |
◆ 构造 Payload 读取 Flag
知道绕过原理后,接下来就是构造实际的攻击 payload。Web 根目录为 /var/www/html/,flag 文件位于 /flag.txt,需要向上穿越 4 层目录到达根目录。每组 ....// 代表一层穿越,因此需要 4 组:
?module=....//....//....//....//flag.txt
使用 curl 发送请求:
curl 'http://47.99.147.34:18941/?module=....//....//....//....//flag.txt'
响应中直接输出了 flag。为了验证穿越的有效性,还可以读取 /etc/passwd 文件:
curl -s 'http://47.99.147.34:18941/?module=....//....//....//etc/passwd'
# 输出:
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
成功读取到 /etc/passwd 证实了目录穿越的有效性,攻击成功。
◆ 总结
本篇两道题目分别涉及了 SSTI 模板注入和 PHP 伪协议与目录穿越,难度相对上篇有所提升。TaxSystem_SSTI 考察的是 Flask 应用中模板注入与 Session 伪造的组合攻击,而 Enterprise_OA 则是经典的 PHP 文件包含与过滤绕过。两道题都需要对 Web 安全的基本原理有较好的理解,建议大家在学习时多动手实践,加深对这类漏洞的理解。
知识点回顾
|
题目 |
核心知识点 |
|
TaxSystem_SSTI |
SSTI 模板注入 + itsdangerous Session 伪造 |
|
Enterprise_OA |
php://filter 伪协议 + str_replace 单次替换绕过 |

1万+

被折叠的 条评论
为什么被折叠?



