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

  介绍

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

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

首先环境可以作曲家一键搭建,然后php想跑进行跑起来就可;

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

 protected  autosave 美元;=,真的;
  
  public  function  __destruct ()
  {
  ,,,if  (!, $ this→自动保存),{
  ,,,,,,,这个美元→保存();
  ,,,}
  }

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

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

 public  function 保存()
  {
  ,,,contents 美元;=,$ this→getForStorage ();
  
  ,,,这美元→存储→设置($ this→键,,内容、美元,美元这→到期);
  }

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

 public  function  getForStorage ()
  ,,,{
  ,,,,,,,cleaned 美元;=,$ this→cleanContents ($ this→缓存);
  
  ,,,,,,,return  json_encode([清洗,美元,美元这→完成]);
  }

发现首先调用了cleanContents方法,然后在调用了json_encode方法,这里首先回溯一下cleanContents方法;

 public  function  cleanContents (array  $内容)
  ,,,{
  ,,,,,,,cachedProperties 美元;=,array_flip ([
  ,,,,,,,,,,,& # 39;path & # 39;,, & # 39;目录名# 39;,,& # 39;basename # 39;,, & # 39;扩展# 39;,,& # 39;文件名# 39;
  ,,,,,,,,,,,& # 39;大小# 39;,,& # 39;mimetype # 39;,, & # 39;能见度# 39;,,& # 39;时间戳# 39;,,& # 39;类型# 39;
  ,,,,,,,,,,,& # 39;md5 # 39;
  ,,,,,,,);
  ,,,foreach  (contents 美元;as  path 美元;=祝辞,美元对象),{
  ,,,,,,,if  (is_array(对象)美元),{
  ,,,,,,,,,,,内容美元(美元路径),=,array_intersect_key($对象,cachedProperties美元);
  ,,,,,,,}
  ,,,}
  
  ,,,return  $内容;
  }

首先在这里看到了array_flip方法;这个方法是将数组的键名和键值进行替换,然后数组赋值给美元cachedProperties变量,然后将我们传入的参数按照路径和对象的美元格式来进行各个遍历,然后将键名经过is_array方法的判断如果为真则进行后续的函数处理,否则就直接返回$内容这个数组;经过这一系列操作完之后,最终是返回到了拯救函数里,然后接着去进行$ this→存储→设置(内容、美元$ this→键,这→到期);这里我们发现商店也可控,那么就有两种思路,第一个就是去实例化一个有集方法的类,或者我们实例化一个存在__call方法的类,从而可以因为访问不存在的方法去调用电话到魔术方法;这里我们先找到一个有集方法的类,在类文件中找到:

 public  function 设置(名称、美元,美元的价值,美元expire =, null): bool
  {
  ,,,这个→美元writeTimes + +;
  
  ,,,if  (is_null($)到期),{
  ,,,,,,,expire 美元;=,$ this→选项(& # 39;到期# 39;);
  ,,,}
  
  expire 美元,,,,,,=,$ this→getExpireTime(到期美元);
  ,,,filename 美元;=,$ this→getCacheKey($名称);
  
  ,,,dir 美元;=,目录名($ filename);
  
  ,,,if  (! is_dir (dir)美元),{
  ,,,,,,,try  {
  ,,,,,,,,,,,mkdir (dir美元,0755,,真的);
  ,,,,,,,},catch  (\ Exception  $ e), {
  ,,,,,,,,,,,//,创建失败
  ,,,,,,,}
  ,,,}
  
  ,,,data 美元;=,$ this→序列化(美元值);
  
  ,,,if  ($ this→选项(& # 39;data_compress& # 39;),,,, function_exists (& # 39; gzcompress& # 39;)), {
  ,,,,,,,//数据压缩
  ,,,,,,,data 美元;=,gzcompress ($ data, 3);
  ,,,}
  
  data 美元,,,,,,=,“& lt; ? php \ n//?只sprintf (& # 39; % 012 d # 39;,,到期美元),只“\ n 退出();?祝辞\ n",只美元数据;
  ,,,result 美元;=,写入(文件名,美元,美元数据);
  
  ,,,if (结果),{
  ,,,,,,,函数();
  ,,,,,,,return 真实;
  ,,,}
  
  ,,,return 假;
  }

这里可利用点在后面的序列化方法;直接追溯一下,

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