thinkphp5.0.24反序列化漏洞分析

本文深入分析了ThinkPHP5.0.24的反序列化漏洞,从反序列化起点开始,详细阐述了如何通过特定的类和方法组合触发文件写入。通过构造特定的对象并利用__call方法,最终能够在系统中写入文件,但内容不可控。同时,文章还探讨了在Windows环境下文件名的限制及其解决方案。

thinkphp5.0.24反序列化漏洞分析

thinkphp5框架:

image-20220615000257518

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

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

image-20220615000539160

具体分析

反序列化起点

写一个反序列化入口点

image-20220615001131637

全局搜索__destruct()函数

image-20220615001115342

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

image-20220615001339350

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

image-20220615001418986

全局搜索__toString方法

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

image-20220616230519422

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

image-20220616230630861

toArray

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

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

image-20220616231036322

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

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

getRelationData分析

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

image-20220616235535073

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

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

image-20220617230450476

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

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

image-20220617230828281

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

image-20220617231051519

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

该函数分析到这里

$modelRelation生成

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

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

image-20220617231704327

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

image-20220617232020032

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

if (method_exists($this, $relation))

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

在这里插入图片描述

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

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

进入__call前的两个if

接下来要分析两个if条件

image-20220617233102696

我们看第一个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()

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值