题目
1 |
|
不要被 \(|\)
吓住了,过滤的是中文括号。
直接看 payload 吧:
Payload1
1 | ?c=echo highlight_file(next(array_reverse(scandir(pos(localeconv()))))); |
解析:
localeconv()
返回包含本地化数字和货币格式信息的关联数组(有关各种货币相关符号与货币数据格式,有兴趣可自行找资料看看,本处只涉及小数点),**该数组的第一个元素通常是小数点.
**(如['.', ...]
),被我们借来表示当前目录。pos()
**别名current()
**,返回数组内部指针当前位置的值。PHP数组有一个隐藏的 “内部指针”,初始指向第一个元素。此处指向localeconv()
生成数组中的第一个元素.
,用于表示当前目录( Linux 知识点)。scandir('.')
扫描当前目录,返回按升序排列的文件列表,例如:['.', '..', 'flag.php', 'index.php']
。array_reverse()
反转数组顺序,得到:['index.php', 'flag.php', '..', '.']
。next()
将数组内部指针从第一个元素(index.php
)后移一位,返回第二个元素flag.php
。
关于数组指针操作函数,参考以下表格。
数组指针操作函数返回值规则函数 是否移动指针 返回值 current()
/pos()
否 当前指针位置的值(越界返回 false
)next()
是(后移) 新位置的值(越界返回 false
)prev()
是(前移) 新位置的值(越界返回 false
)reset()
是(重置) 数组第一个元素(空数组返回 false
)end()
是(跳末) 数组最后一个元素(空数组返回 false
)key()
否 当前指针位置的键名(越界返回 null
)highlight_file('flag.php')
高亮显示flag.php
的源码,直接输出文件内容。
最终 flag.php 回显到前端。若输出的不是 flag.php 文件的内容,可能需要自行移动指针位置来找找。
Payload2
1 | ?c=eval(next(reset(get_defined_vars())));&pay=system("tac flag.php"); |
解析
get_defined_vars()
:返回当前作用域中所有变量的数组,包括超全局变量(如$_GET
)。
超全局变量(如 $_GET
、$_POST
、$_SERVER
等)默认位于返回数组的最前端。它们会以固定的顺序排列,但具体顺序由 PHP 内核决定,第一个通常是 $_GET
。
用户定义的变量(如 $a = 1;
)会紧随超全局变量之后。它们的排列顺序通常与代码中的定义顺序一致,但某些情况下可能受 PHP 优化影响(例如变量未使用时可能被忽略)。
其他数组指针操作函数参考上面的表格。
$_GET
数组的元素顺序按照 URL 中参数顺序排列,所以最后 eval()
函数会执行 $_GET
数组的第二个元素,也就是 URL 中第二个参数 pay
的值。