PHP序列化思考(9.14已修改)

今天去看社团大佬总结了一遍PHP序列化/反序列化,学了点新知识,也冒出一些问题

关于PHP序列化的方法,参考我的另一篇博客:

PHP实战总结3https://www.cnblogs.com/echoDetected/p/12527895.html

序列化是怎么造成读取文件内容的?

1.相关PHP魔术化方法:__toSring,类被当做字符串时回应的方法

  配合file_get_contents()读取flag文件内容

  源码:

 1 <?php
 2 class flag{
 3 
 4     public $file;
 5 
 6     public function __tostring(){
 7 
 8     echo file_get_contents($this->file);
 9 
10 return'yes';
11 
12 }
13 
14 }
15 
16 $a= new flag();
17 
18 $a->file= 'php://filter/convert.base64-encode/resource=flag.php';
19 
20 $data= serialize($a);
21 
22 echo $data.'';
23 
24 echo "
";
25 
26 echo unserialize($data);
27 
28 ?>

  第8行,flag类调用后会打印file文件的内容

  第22行,打印序列化以后的data变量的值

  第26行,打印反序列化以后的data变量

  按照常理来说,我们构造file文件为php伪协议的读取语句,使得传参之后类访问flag.php文件的base64加密数据,结果就会先输出data的序列化字符串,然后输出反序列化以后的类(仔细想想的话并不会),然后输出flag.php内容的base64编码值

  运行结果:

  第一行,显示序列化的结果

  第二行,除去+yes就是base64加密的flag.php文件内容

2.反序列化的值是靠什么传进去的?

  以我的理解,变量a新建了flag类,变量data序列化了a,通常讲序列化时会调用__sleep()魔术方法(这里没有给出),使类“休眠”;之后反序列化会调用__wake up()魔术方法,使类“苏醒”;  

  这里的反序列化值,其实就是靠反序列化函数unserialize()传进去的,一旦执行反序列化,字符串就会转换成“活着的”类。

  但是如果没有echo输出,最后的类并不会自输出内容,即使类内存在echo语句。反序列化函数只负责传参并执行类的代码,并不会返回结果。

  

  之后,如果存在传参,我们可以将参数(恶意代码)进行序列化,来得到我们想要的结果。但要注意的是序列化以后字符串可能会吃掉一些不识别的字符,如 等,可以的话先用base64进行加密,避免出错。

  参考我的另一篇博客https://www.cnblogs.com/echoDetected/p/12336205.html

原文地址:https://www.cnblogs.com/echoDetected/p/13662823.html