RSS Feed
更好更安全的互联网

Typecho 前台 getshell 漏洞分析

2017-10-26

作者:LoRexxar’@知道创宇404实验室

0x01 简述

Typecho是一个简单,轻巧的博客程序。基于PHP,使用多种数据库(Mysql,PostgreSQL,SQLite)储存数据。在GPL Version 2许可证下发行,是一个开源的程序,目前使用SVN来做版本管理。

2017年10月13日,Typecho爆出前台代码执行漏洞,知道创宇404团队研究人员成功复现了该漏洞。

经过分析确认,该漏洞可以无限制执行代码,通过这种方式可以导致getshell。

0x02 复现

打开安装好的Typecho

生成对应的payload

设置相应的cookie并发送请求向

成功执行phpinfo

0x03 漏洞分析

漏洞的入口点在install.php,进入install.php首先经过两个判断

只要传入GET参数finish,并设置referer为站内url即可。

跟入代码,找到漏洞点入口点,install.php 232行到237行

看起来比较清楚,一个比较明显的反序列化漏洞

问题在于如何利用,反序列化能够利用的点必须要有相应的魔术方法配合。其中比较关键的只有几个。

其中__destruct()是在对象被销毁的时候自动调用,__Wakeup在反序列化的时候自动调用,__toString()是在调用对象的时候自动调用。

这里如果构造的反序列化是一个数组,其中adapter设置为某个类,就可以触发相应类的__toString方法

寻找所有的toString方法,我暂时只找到一个可以利用的的类方法。

/var/Typecho/Feed.php 文件223行

顺着分析tostring函数

290行 调用了$item['author']->screenName,这是一个当前类的私有变量

358行 同样调用了同样的变量,这里应该也是可以利用的

这里要提到一个特殊的魔术方法__get__get会在读取不可访问的属性的值的时候调用,我们可以通过设置item来调用某个位置的__get魔术方法,让我们接着寻找。

/var/Typecho/Request.php 第269行应该是唯一一个可利用的__get方法.

跟入get函数

最后进入159行 applyFilter函数

我们找到了call_user_func函数,回溯整个利用链

我们可以通过设置item['author']来控制Typecho_Request类中的私有变量,这样类中的_filter_params['screenName']都可控,call_user_func函数变量可控,任意代码执行。

但是当我们按照上面的所有流程构造poc之后,发请求到服务器,却会返回500.

回顾一下代码

在install.php的开始,调用了ob_start()

在php.net上关于ob_start的解释是这样的。

因为我们上面对象注入的代码触发了原本的exception,导致ob_end_clean()执行,原本的输出会在缓冲区被清理。

我们必须想一个办法强制退出,使得代码不会执行到exception,这样原本的缓冲区数据就会被输出出来。

这里有两个办法。
1、因为call_user_func函数处是一个循环,我们可以通过设置数组来控制第二次执行的函数,然后找一处exit跳出,缓冲区中的数据就会被输出出来。
2、第二个办法就是在命令执行之后,想办法造成一个报错,语句报错就会强制停止,这样缓冲区中的数据仍然会被输出出来。

解决了这个问题,整个利用ROP链就成立了

0x04 poc

0x05 Reference

0x06 后记

我们在10月25日收到p0的漏洞分析投稿http://p0sec.net/index.php/archives/114//http://p0sec.net/index.php/archives/114/,与我们撞洞了,这里一并表示感谢。

作者:dawu | Categories:安全研究技术分享 | Tags: