ctf show web入门110

这是一道典型的 PHP 代码审计与绕过题(通常出现在 CTF 比赛中)。题目核心在于通过 eval() 函数执行任意代码以获取 Flag。

执行点:

php 复制代码
eval("echo new $v1($v2());");

但是v1v2都被正则限制

被禁用的字符包括:绝大多数特殊符号(包括括号 ()、分号 ;、美元符号 KaTeX parse error: Undefined control sequence: \、 at position 6: 、反斜杠 \̲、̲引号等)以及所有数字 [0-9...v1 和 $v2 中只能包含纯英文字母。

致命细节:注意到 v2 在 eval 中是以 v2() 的形式被调用的,而正则中禁用了括号 ()。因此,我们不能在 v2 的输入中自带括号,必须让它保持纯字母,依赖代码原本自带的 () 执行。例如,若 v2 = 'phpinfo',则会被解析执行为 phpinfo()

因为受到严格的字母限制无法使用 system() 等需要传参的函数,我们必须利用 PHP 的内置类 来读取文件

我们需要寻找一个满足以下条件的 PHP 内置类:

类名完全由纯字母组成(配合 $v1)。

其构造函数接受一个字符串参数。

或者是可以通过 echo 直接输出该对象的实例(即该类实现了 __toString() 魔术方法)。

核心武器:FilesystemIterator 或 GlobIterator

FilesystemIterator:用于遍历文件系统目录。

GlobIterator:可以通过匹配模式遍历文件目录(支持通配符 *)。

当使用 echo 打印这些类的实例时,它们会默认返回当前目录下的第一个文件名。

  1. 具体构造与构造链步骤
    第一步:查看当前目录下的文件
    由于 v2 会以 v2() 形式执行,我们需要找到一个不需要参数、返回值为字符串或可用路径的内置函数。

getcwd:这是一个完美的函数。getcwd() 不需要参数,返回当前工作目录的绝对路径(字符串)。

如果我们传入:

v1 = FilesystemIterator

v2 = getcwd

eval 实际执行的语句将是:

php 复制代码
echo new FilesystemIterator(getcwd());

发现有一个文件名为fl36dga.txt的我们尝试访问

这里直接在原url后加上文件名就可以访问

在原 URL 后面加上 fl36dga.txt 就能直接访问,这并不是因为题目代码执行了什么逻辑,而是因为 Web 服务器(如 Apache、Nginx)的核心工作原理。

我们可以把这个过程拆解为两个层面:

  1. Web 服务器的"文件映射"机制(为什么能直接访问)
    当你访问一个网站时(例如 http://example.com/),Web 服务器的后台其实对应着服务器硬盘上的一个具体文件夹(通常称为 Web 根目录,比如 /var/www/html/)。

当你访问 http://example.com/index.php 时,服务器就会去根目录下找到 index.php 这个文件,通过 PHP 解释器执行它,然后把结果发给你的浏览器。

同理,如果你在上一阶段通过漏洞发现了当前目录下还有一个叫 flag.php 的文件,你直接在浏览器输入 http://example.com/flag.php,Web 服务器就会绕过原本的 index.php,直接去读取并执行 flag.php。

这就是为什么你不需要再去研究怎么构造复杂的 Payload,直接修改 URL 就能访问它的原因。

  1. 为什么有时候直接访问 flag.php 却看不到 Flag?
    虽然你可以直接访问它,但在实际的 CTF 比赛中,你大概率会遇到以下两种情况:

情况 A:页面是一片空白

原因:flag.php 内部的代码通常是这样写的:

PHP
<?php $flag = "flag{this_is_a_fake_flag}"; ?>

或者它只是把 Flag 赋值给了一个变量,但没有使用 echo 或 print 把它打印出来。

结果:Web 服务器确实执行了这个文件,但因为代码没有输出任何内容,所以你看到的浏览器页面是一片空白。

情况 B:权限被拒绝(403 Forbidden)或找不到(404 Not Found)

原因:出题人为了防止你"爆破文件名直接下载",通常会把 flag.php 放在 Web 根目录之外(例如放在 / 根目录下,或者 /var/ 目录下)。

结果:这时候,Web 服务器的 URL 根本无法直接映射到这个文件。你通过浏览器无论怎么输入 URL 都访问不到它。

总结:什么时候该用什么方法?

因此,在得到 Flag 的文件名或路径后,最稳妥的思路是:

先尝试直接访问:在 URL 后面直接改成 flag.php。如果出题人偷懒,Flag 直接写在 HTML 里面,或者直接 echo 出来了,你就能直接秒杀此题(右键查看网页源代码防止被浏览器隐藏)。

如果直接访问失败(空白或403):说明必须通过题目自带的漏洞去读取文件内容。这时候就需要用上一步提到的 SplFileObject 配合 session_id() 的方法,强行让后台代码把 flag.php 的内部源码读出来并打印在网页上。

相关推荐
拉拉肥_King1 小时前
Vue 3 主题切换深度解析:从炫酷动画到零闪烁方案
前端·vue.js
excel1 小时前
为什么 Pinia + localForage 持久化后,页面初始化拿不到数据?
前端
雨雨雨雨雨别下啦1 小时前
vant介绍
前端
小小小小宇1 小时前
大模型失忆问题探讨
前端
wordbaby1 小时前
rn-cross-calendar:一个兼容 React 18/19、RN/RNOH 的跨平台日历组件
前端·react native·harmonyos
weixin_523185321 小时前
Collections.unmodifiableMap详解:真的不可修改吗?
java·linux·前端
江米小枣tonylua1 小时前
关掉 VSCode:在 NeoVim12 上配置 Claude Code
前端·程序员
道一231 小时前
Windows系统查看端口占用进程的3种实用方法
windows·笔记
2301_773643621 小时前
ceph镜像
前端·javascript·ceph