[代码审计] ThinkPHP V6.0.12LTS 反序列化漏洞

前言

前段时间参加了信息安全国赛,其中有一个题是ThinkPHP6 反序列化,当时只是做了一些简单的审计,最后直接用网上的 EXP 打。现在比赛结束了,所以特地花点时间重新审计一番,小记一下。

1. 利用链分析
1.1 反序列化的思考

在PHP中,反序列化分为有类无类两种,无类的反序列化利用比较简单直接。有类的时候一般需要挖掘利用链,其中起到关键作用的就是魔术方法,魔术方法是连接利用链的桥梁。

在挖掘反序列化的时候,一般来说首先要找的就是__destruct()__wakeup 两个函数

__destruct()	// 对象被销毁的时候调用
__wakeup()		// 反序列化的时候调用
1.2 寻找触发条件

废话不多说了,知道了入口点以后,现在开始漏洞挖掘,首先寻找入口点__destruct()

  • Seay全局搜索存在__destruct()的地方
    在这里插入图片描述
  • 然后找可利用的点,在/vendor/topthink/think-orm/src/Model.php中发现__destruct() 调用了save()方法,只需要$this->lazySavetrue 即可,并且这个参数是可控的
    在这里插入图片描述
/**
 * 析构方法
 * @access public
 */
public function __destruct()
{
   
   
    if ($this->lazySave) {
   
   
        $this->save();
    }
}
  • 跟进save()方法,关键点如下,需要进入到updateData()函数,要绕过位置1处的判断和$this->existstrue
  • $this->exists是可控的,所以关键点是绕过前面的判断
    在这里插入图片描述

接下来查看$this->isEmpty()函数和$this->trigger()函数

  • 查看isEmpty()函数,使用empty()函数对$this->data进行判断,不为空即可,且参数可控
    -
  • trigger()函数默认返回的是true,所以也能绕过
    在这里插入图片描述
  • 接下来跟进updateData()方法,只要前面的绕过了,就会来到如下位置
  • 所以$this->checkAllowFields()默认就会被调用,继续跟进
    在这里插入图片描述
  • 跟进checkAllowFields()函数,$this->field参数和$this->schema默认为空数组,所以默认会直接调用db()函数
    在这里插入图片描述
  • 继续跟进db()函数,这里的$this->table是可控的,所以可以进入到位置2,并且这里将$this->table当作了字符串使用,如果$this->table是一个对象,那么就可以触发__toString()魔术方法的执行
    在这里插入图片描述
1.3 __toString() 挖掘利用

上面的分析找到通过__destruct()一步步触发执行__toString() ,接下来继续寻找__toString()函数中可用于利用的点

  • 还是全局搜索__toString(),在/vendor/topthink/think-orm/src/model/concern/Conversion.php中找到一个__toString()方法,里面调用了toJson()方法
    在这里插入图片描述
  • 跟进toJson()方法,这里调用了toArray()方法
    在这里插入图片描述
  • 跟进toArray()方法,关键代码如下,这里将$this->data$this->relation两个数组合并,然后进行遍历,在默认情况下会调用到最下面的$this->getAttr($key),其中$this->data是可控的,所以这里传入的$key也能被控制
    在这里插入图片描述
  • 跟进getAttr()函数,$relation默认为false,然后$value的值从getData()函数中获取,然后将参数传入getValue()函数中
    -
  • 先查看一下getData()函数做了什么,这里调用了getRealFieldName()函数(实际上只是对内容进行了一下检测而已),只要内容合法,那么最后返回的$fieldName$name实际上是一样的
  • 然后array_key_exists()函数判断检测后的内容在$this->data中是否存在,实际上可以理解为检测$name而已,只要内容合法,那么就一定存在,所以最后能执行位置2
V6.0.7版本发布,本版本主要针对上个版本做了一些路由修正,还意外收获了一些性能提升,是一个建议更新的版本。主要更新 修正Validate类的PHP8兼容性 改进redis驱动的append方法 修正路由匹配检测问题 优化路由变量正则规则生成 改进responseView的内容渲染 安装和更新 V6版本开始仅支持Composer安装及更新,支持上个版本的无缝更新,直接使用composer update 更新到最新版本即可。如果需要全新安装,使用:composer create-project topthink/think tpThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。全面的WEB开发特性支持最新的ThinkPHPWEB应用开发提供了强有力的支持,这些支持包括:MVC支持-基于多层模型(M)、视图(V)、控制器(C)的设计模式ORM支持-提供了全功能和高性能的ORM支持,支持大部分数据库模板引擎支持-内置了高性能的基于标签库和XML标签的编译型模板引擎RESTFul支持-通过REST控制器扩展提供了RESTFul支持,为你打造全新的URL设计和访问体验云平台支持-提供了对新浪SAE平台和百度BAE平台的强力支持,具备“横跨性”和“平滑性”,支持本地化开发和调试以及部署切换,让你轻松过渡,打造全新的开发体验。CLI支持-支持基于命令行的应用开发RPC支持-提供包括PHPRpc、HProse、jsonRPC和Yar在内远程调用解决方案MongoDb支持-提供NoSQL的支持缓存支持-提供了包括文件、数据库、Memcache、Xcache、Redis等多种类型的缓存支持安全性框架在系统层面提供了众多的安全特性,确保你的网站和产品安全无忧。这些特性包括:XSS安全防护表单自动验证强制数据类型转换输入数据过滤表单令牌验证防SQL注入图像上传检测
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值