0x00  前言

    今天在Seebug的公众号看到了Typecho的一个前台getshell分析的文章,然后自己也想来学习一下。保持对行内的关注,了解最新的漏洞很重要。

0x01  什么是反序列化漏洞

    如题所说,这是一个反序列化导致的代码执行。看过我之前文章的人应该不会陌生。PHP在反序列化一个字符串时,相当于激活了之前休眠的一个对象。当在激活的时候,会调用几个魔法方法来进行初始化以及相关操作。而如果魔法方法中存在危险操作,比如数据库操作,文件读写操作,系统命令调用等,那么就有可能会造成相应的漏洞。用户通过可控变量调整系统运行流程。进入到危险函数,从而导致漏洞。

0x02  分析

    官方在前两天已经做了修复。现在已经不存在这个漏洞了。我们找到以前的版本进行安装。链接如下:

https://github.com/typecho/typecho/releases/tag/v1.1-15.5.12-beta

  

在根目录的install.php中我们发现:

我们定位到了漏洞现场。然后问题来了,反序列化是将一个休眠对象(字符串)激活为一个对象。那么我们接下来找到在激活的过程中,有哪些方法可以调用,它们才是利用的关键。我们来搜索这三个方法:

__toString()

__destruct()

__Wakeup()

  我没有找到wakeup方法,然后destruct方法也不能使用。然后搜索__toString()的时候发现有三处,分别如下:

var\Typecho\Config.php

public function __toString()
{
return serialize($this->_currentConfig);
} var\Typecho\Db\Query.php public function __toString()
{
switch ($this->_sqlPreBuild['action']) {
case Typecho_Db::SELECT:
return $this->_adapter->parseSelect($this->_sqlPreBuild);
case Typecho_Db::INSERT:
return 'INSERT INTO '
. $this->_sqlPreBuild['table']
. '(' . implode(' , ', array_keys($this->_sqlPreBuild['rows'])) . ')'
. ' VALUES '
. '(' . implode(' , ', array_values($this->_sqlPreBuild['rows'])) . ')'
. $this->_sqlPreBuild['limit'];
case Typecho_Db::DELETE:
return 'DELETE FROM '
. $this->_sqlPreBuild['table']
. $this->_sqlPreBuild['where'];
case Typecho_Db::UPDATE:
$columns = array();
if (isset($this->_sqlPreBuild['rows'])) {
foreach ($this->_sqlPreBuild['rows'] as $key => $val) {
$columns[] = "$key = $val";
}
} return 'UPDATE '
. $this->_sqlPreBuild['table']
. ' SET ' . implode(' , ', $columns)
. $this->_sqlPreBuild['where'];
default:
return NULL;
}
} \var\Typecho\Feed.php public function __toString()
{
。。。后边再贴代码
}

但是一定能用吗?

我们可以看到随后的$config进入了Typecho_Db类的构造方法,我们来跟进:

在第120行的时候,发现传入的参数用来做字符串拼接。这样就会调用__toString()方法了.

  

然后我们对之前搜索到的方法跟进,发现前两个是没法用的。然后我们重点关注最后一个。这个函数主要的目的是拼接xml文件。然后在整个过程中,并没有直接进入危险函数,所以此时陷入僵局。但是就这样就无解了吗?

0x03  __get()方法的逆袭

__get()方法在调用一个对象不存在的成员变量时候将会调用此方法。可以参考我之前的文章。

那么这样的话我们只要能够找到一个get方法中存在危险操作,这样的话,这个漏洞还是可能的。我们来试试看。

全局来搜索__get()方法,然后在\var\Typecho\Request.php

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

我们跟进:

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

在方法的最后调用了_applyFilter()方法,继续跟进:

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

我们来梳理一下整个逻辑,install.php (反序列化) ==> Db.php (将$config中的参数拿来拼接,调用toString方法) ==> Feed.php (调用一个不存在成员变量,将会调用__get()方法) ==> Request.php (调用get()方法,然后调用_applyFilter(), 然后调用call_user_func()导致了代码执行)

0x03  利用方法

完整的利用过程,我们可以看

p0的文章 http://p0sec.net/index.php/archives/114/ 或者

Seebug的公众号 http://mp.weixin.qq.com/s?__biz=MzAxNDY2MTQ2OQ==&mid=2650942666&idx=1&sn=5c84d6d69463a0a430e01dfa68c2d3ab&chksm=80796ef8b70ee7ee8ba5d88feb8d794bee19a55b6e17dff45fcee6ba6ee726fb4e2e029d50bd&scene=0#rd

0x04  思考

    这个其实是当时看到122行的时候:

我想这里直接调用了call_user_func()函数,$adapterName我是可控的,我们不直接可以命令执行吗?还要长长的执行链干什么啊?

然后我查了call_user_func()的使用方法:

如果传入的是数组,那么数组中的第一个值是一个类名,第二个是类中的一个方法。但是怎么样第一个值才能是类呢?这个时候我想到了匿名类。在函数式编程中经常会用到匿名函数,匿名类。于是我去查了一下发现在PHP7中加入了匿名类的定义,所以如下代码是可以的:

call_user_func(array(
new class(){
public function isAvaliable() {
echo "Hello, World";
}
},
'isAvaliable'
)
); //执行结果
Hello, World

这里不能用的原因在于被之前的$adapterName = 'Typecho_Db_Adapter_' . $adapterName;给打断掉了。如果你用类和字符串做拼接。很明显是不行的。

  

Typecho V1.1反序列化导致代码执行分析的更多相关文章

  1. 转载--Typecho install.php 反序列化导致任意代码执行

    转载--Typecho install.php 反序列化导致任意代码执行 原文链接(http://p0sec.net/index.php/archives/114/) 0x00 前言 漏洞公布已经过去 ...

  2. Spring框架的反序列化远程代码执行漏洞分析(转)

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  3. ecshop SQL注入漏洞导致代码执行

    漏洞名称:ecshop SQL注入漏洞导致代码执行补丁编号:11208761补丁文件:/includes/libinsert.php补丁来源:云盾自研漏洞描述:ecshop的/includes/lib ...

  4. Scrapy研究探索(三)——Scrapy核心架构与代码执行分析

    学习曲线总是这样,简单样例"浅尝".在从理论+实践慢慢攻破.理论永远是基础,切记"勿在浮沙筑高台". 一. 核心架构 关于核心架构.在官方文档中阐述的非常清晰, ...

  5. 《暗黑世界V1.6》服务器代码执行图

    <暗黑世界V1.6>服务器代码执行图 (原文地址:http://www.9miao.com/forum.php?mod=viewthread&tid=44016&highl ...

  6. 高危!Fastjson反序列化远程代码执行漏洞风险通告,请尽快升级

    据国家网络与信息安全信息通报中心监测发现,开源Java开发组件Fastjson存在反序列化远程代码执行漏洞.攻击者可利用上述漏洞实施任意文件写入.服务端请求伪造等攻击行为,造成服务器权限被窃取.敏感信 ...

  7. s2-029 Struts2 标签远程代码执行分析(含POC)

    1.标签介绍 Struts2标签库提供了主题.模板支持,极大地简化了视图页面的编写,而且,struts2的主题.模板都提供了很好的扩展性.实现了更好的代码复用.Struts2允许在页面中使用自定义组件 ...

  8. Samba远程代码执行-分析(CVE-2017-7494)

    经历了前一阵windows的EternalBlue之后,某天看见了360的 samba高危预警,这个号称linux端的EternalBlue(EternalRed),于是便研究了一波 概述(抄) Sa ...

  9. cve-2019-2725 反序列化远程代码执行

    描述:部分版本WebLogic中默认包含的wls9_async_response包,为WebLogic Server提供异步通讯服务.由于该WAR包在反序列化处理输入信息时存在缺陷,攻击者可以发送精心 ...

随机推荐

  1. linq join一些忘记的操作

  2. Docker添加官方加速源(必须)

    在国内使用Docker必须用加速镜像不然的话无论是pull 官方的还是私有的镜像都会WAIT TIME EXCEED 下面给出macos的添加方式,非常简单 macOS 对于使用 macOS 的用户, ...

  3. pcd转obj

    文件转换 从PCD文件写入和读取点云数据:https://www.cnblogs.com/li-yao7758258/p/6435568.html 点云数据格式PCD(Point Cloud Data ...

  4. Java 高级基础——反射

    Java 高级基础--反射 反射的意义:Java 强类型语言,但是我们在运行时有了解.修改信息的需求,包括类信息.成员信息以及数组信息. 基本类型与引用类型 基本类型,(固定的 8 种) 整数:byt ...

  5. 团体程序设计天梯赛L1-017 到底有多二 2017-03-22 17:31 155人阅读 评论(0) 收藏

    L1-017. 到底有多二 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 一个整数"犯二的程度"定义为该数 ...

  6. B-spline Curves 学习之B样条基函数的定义与性质(2)

    B-spline Basis Functions 本博客转自前人的博客的翻译版本,前几章节是原来博主的翻译内容,但是后续章节博主不在提供翻译,后续章节我在完成相关的翻译学习. (原来博客网址:http ...

  7. FMX.Platform.TApplicationEvent

    FMX.Platform.TApplicationEvent http://docwiki.embarcadero.com/Libraries/Seattle/en/FMX.Platform.TApp ...

  8. Unity3d中使用Lua

    对于手机游戏,如果可以在线更新以实现bug修复.新功能添加等等,其好处自不必多说. 通过C#的反射机制,也可以实现某种程度上的脚本级更新,具体可以参考 http://docs.unity3d.com/ ...

  9. mysql 删表引出的问题

    背景 将测试环境的表同步到另外一个数据库服务器中,但有些表里面数据巨大,(其实不同步该表的数据就行,当时没想太多),几千万的数据!! 步骤 1. 既然已经把数据同步过来的话,那就直接delete掉就行 ...

  10. VS2015 IIS Express 无法启动 解决办法(转)

    因为安装各种乱七八糟的软件,然后不小心把IIS Express卸载掉了,网上下载了一个IIS Express 7,安装之后本地使用VS 2015无法启动调试,F5 无法启动IIS, 再次F5调试,没有 ...