打开靶场观察本题的正则过滤

flag | system | php | cat | sort | shell | . (点) | (空格) | ' (单引号) | " (双引号)都被过滤了
我们可以考虑构造一个无字母数字(或无特定关键字)RCE 技巧,利用 PHP 的内部函数嵌套来一步步定位并读取文件,完全避开 system、cat、flag、点号和空格等所有黑名单限制。payload如:show_source(next(array_reverse(scandir(pos(localeconv())))));

让我们从内向外层层拆解该payload:
- 核心层:定位当前目录
localeconv(): 这个函数返回一个包含本地化数字和货币格式信息的数组。在 PHP 中,它返回的数组第一个元素通常是一个 . (点号)。
pos(): 它是 current() 函数的别名,用于返回数组中的第一个元素。
结果:pos(localeconv()) 得到了字符串 .。这样就巧妙地绕过了黑名单对 . 的过滤。 - 目录扫描层:获取文件列表
scandir('.'): 这个函数会扫描指定目录下的所有文件和目录。
结果:它返回一个数组,包含了当前目录下的所有文件名(例如:['.', '...', 'index.php', 'flag.php'])。
array_reverse(...): 将 scandir 返回的文件数组顺序反转。
为什么反转? 在 CTF 题目中,flag.php 通常按字母排序排在后面,反转后它会排在前面,方便提取。 - 提取层:选中目标文件
next(...): 将数组内部指针向前移动一位,并返回该元素。
原因:反转后的数组第一个元素通常是刚才扫描到的目录标记,第二个元素(即 next 指向的)往往就是我们要找的 flag.php。 - 执行层:展示源代码
show_source(...): 它是 highlight_file() 的别名。它会读取 PHP 文件的内容,并将其进行语法高亮后输出到页面上。
结果:它直接读取并显示了 flag.php 的内容。