typecho反序列化漏洞复现

0x01前言

再杭州西湖线下打AWD的时候web1就是这个漏洞,在这里复现一下,刚好巩固一下前几天学习的反序列化漏洞。

0x02漏洞分析

这是一个由unserialize()导致的一个反序列化漏洞,全局搜索unserialize(),在install.php的232行发现

<?php
  $config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config')));
  Typecho_Cookie::delete('__typecho_config');
  $db = new Typecho_Db($config['adapter'], $config['prefix']);
  $db->addServer($config, Typecho_Db::READ | Typecho_Db::WRITE);
  Typecho_Db::set($db);
 ?>

利用Typecho_Cookie的get方法获取Cookie当中的__tyoecho_config的值,然后base解码在进行反序列化,get方法如下:

public static function get($key, $default = NULL)
{
    $key = self::$_prefix . $key;
    $value = isset($_COOKIE[$key]) ? $_COOKIE[$key] : (isset($_POST[$key]) ? $_POST[$key] : $default);
    return is_array($value) ? $default : $value;
}

通过给 v a l u e 赋 值 我 们 可 以 看 出 来 , 传 值 的 方 式 可 以 是 value赋值我们可以看出来,传值的方式可以是 value_COOKIE也可以是$_POST。找到了输入点,回头找一下,看看运行到这一步需要那些条件

//判断是否已经安装
if (!isset($_GET['finish']) && file_exists(__TYPECHO_ROOT_DIR__ . '/config.inc.php') && empty($_SESSION['typecho'])) {
exit;
}

// 挡掉可能的跨站请求
if (!empty($_GET) || !empty($_POST)) {
if (empty($_SERVER['HTTP_REFERER'])) {
    exit;
	}

$parts = parse_url($_SERVER['HTTP_REFERER']);
if (!empty($parts['port'])) {
    $parts['host'] = "{$parts['host']}:{$parts['port']}";
	}

if (empty($parts['host']) || $_SERVER['HTTP_HOST'] != $parts['host']) {
    exit;
	}
}

需要finish不为空,同时需要满足REFERER检测,必须为站内的地址。
根据上面的代码继续运行会调用$config来实例化Typecho_Db这个类,跟进去看一下在Db.php中。在Typecho_Db类中发现了一个构造函数:

    public function __construct($adapterName, $prefix = 'typecho_')
{
    /** 获取适配器名称 */
    $this->_adapterName = $adapterName;

    /** 数据库适配器 */
    $adapterName = 'Typecho_Db_Adapter_' . $adapterName;

    if (!call_user_func(array($adapterName, 'isAvailable'))) {
        throw new Typecho_Db_Exception("Adapter {$adapterName} is not available");
    }

    $this->_prefix = $prefix;

    /** 初始化内部变量 */
    $this->_pool = array();
    $this->_connectedPool = array();
    $this->_config = array();

    //实例化适配器对象
    $this->_adapter = new $adapterName();
}

发现了 a d p t e r N a m e 和 字 符 串 进 行 了 拼 接 , 而 adpterName和字符串进行了拼接,而 adpterNameadapterName是我们传入的$config[‘adapter’]里面adapter的值,如果adpter是一个类,就形成了类和字符串的拼接,这样就可以触发这个类__toString()方法

$adapterName = 'Typecho_Db_Adapter_' . $adapterName;

全局搜索__toString()方法,找到了三处,只在Feed.php中可进行利用

       	 	foreach ($this->_items as $item) {
            $content .= '<item>' . self::EOL;
            $content .= '<title>' . htmlspecialchars($item['title']) . '</title>' . self::EOL;
            $content .= '<link>' . $item['link'] . '</link>' . self::EOL;
            $content .= '<guid>' . $item['link'] . '</guid>' . self::EOL;
            $content .= '<pubDate>' . $this->dateFormat($item['date']) . '</pubDate>' . self::EOL;
            $content .= '<dc:creator>' . htmlspecialchars($item['author']->screenName) . '</dc:creator>' . self::EOL;    

i t e

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值