ctf show web入门110 这是一道典型的 PHP 代码审计与绕过题通常出现在 CTF 比赛中。题目核心在于通过 eval() 函数执行任意代码以获取 Flag。执行点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 或 GlobIteratorFilesystemIterator用于遍历文件系统目录。GlobIterator可以通过匹配模式遍历文件目录支持通配符 *。当使用 echo 打印这些类的实例时它们会默认返回当前目录下的第一个文件名。具体构造与构造链步骤第一步查看当前目录下的文件由于 $v2 会以 $v2() 形式执行我们需要找到一个不需要参数、返回值为字符串或可用路径的内置函数。getcwd这是一个完美的函数。getcwd() 不需要参数返回当前工作目录的绝对路径字符串。如果我们传入v1 FilesystemIteratorv2 getcwdeval 实际执行的语句将是echonewFilesystemIterator(getcwd());发现有一个文件名为fl36dga.txt的我们尝试访问这里直接在原url后加上文件名就可以访问在原 URL 后面加上 fl36dga.txt 就能直接访问这并不是因为题目代码执行了什么逻辑而是因为 Web 服务器如 Apache、Nginx的核心工作原理。我们可以把这个过程拆解为两个层面Web 服务器的“文件映射”机制为什么能直接访问当你访问一个网站时例如 http://example.com/Web 服务器的后台其实对应着服务器硬盘上的一个具体文件夹通常称为 Web 根目录比如 /var/www/html/。当你访问 http://example.com/index.php 时服务器就会去根目录下找到 index.php 这个文件通过 PHP 解释器执行它然后把结果发给你的浏览器。同理如果你在上一阶段通过漏洞发现了当前目录下还有一个叫 flag.php 的文件你直接在浏览器输入 http://example.com/flag.phpWeb 服务器就会绕过原本的 index.php直接去读取并执行 flag.php。这就是为什么你不需要再去研究怎么构造复杂的 Payload直接修改 URL 就能访问它的原因。为什么有时候直接访问 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 的内部源码读出来并打印在网页上。