PHP序列化思考(9.14已修改)
今天去看社团大佬总结了一遍PHP序列化/反序列化,学了点新知识,也冒出一些问题
关于PHP序列化的方法,参考我的另一篇博客:
PHP实战总结3:https://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 "\n"; 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语句。反序列化函数只负责传参并执行类的代码,并不会返回结果。
之后,如果存在传参,我们可以将参数(恶意代码)进行序列化,来得到我们想要的结果。但要注意的是序列化以后字符串可能会吃掉一些不识别的字符,如\n等,可以的话先用base64进行加密,避免出错。
参考我的另一篇博客:https://www.cnblogs.com/echoDetected/p/12336205.html