PHP反序列化深入理解

V站笔记

0x00 什么是序列化

在PHP中右serialize()unserialize()两个函数,php里面的值都可以使用函数serialize()来返回一个包含字节流的字符串来表示。unserialize()函数能够重新把字符串变回php原来的值。 序列化一个对象将会保存对象的所有变量,但是不会保存对象的方法,只会保存类的名字。


0x01 example

简单的一个例子

<?php
//序列化示例

//student类
class student{
    public $name = "DYBOY";
    public $sex = "boy";

    public function getInfo(){
        echo $this->$name;
    }
}

//实例化一个student对象
$person = new student();

//调用方法
$person->getInfo();

?>

访问得到如下结果:

这就是一个正常的例子 但是,在PHP中有一些魔术方法,会自动调用,比如常见的__construct()__destruct(),__toString()等等,下面修改上面的example得到如下代码:

<?php
<?php
//序列化示例

class student{
    public $name = "DYBOY";
    public $sex = "boy";

    public function getInfo(){
        echo $this->name;
        echo "<br/>";
    }

    public function __construct(){
        echo "对象被建立<br/>";
    }

    public function __destruct(){
        echo "对象被销毁<br/>";
    }

    public function __toString(){
        return "当对象当作字符串输出时调用<br/>";
    }
}

$person = new student();

$person->getInfo();
echo $person; //对象当作字符串输出

?>

访问文件,得到如下:

总结几个常见魔术函数:

__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发,返回值需要为字符串
__invoke() //当脚本尝试将对象调用为函数时触发
`

0x02 序列化

//接着上面的代码
echo serialize($person); 
//输出:O:7:"student":2:{s:4:"name";s:5:"DYBOY";s:3:"sex";s:3:"boy";}
echo unserialize($ser);
//输出:当对象当作字符串输出时调用 对象被销毁

字母类型解释:

a - array  
b - boolean  
d - double  
i - integer
o - common object
r - reference
s - string
C - custom object
O - class
N - null
R - pointer reference
U - unicode string

0x03 漏洞利用

原因:当使用反序列化时,如果魔术函数当中的参数时可控的,那么就能够造成XSS或着其他的漏洞 漏洞CTF参考题目:神盾局的秘密

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python攻城狮

Python数据科学(二)- python与数据科学应用(Ⅱ)1.Python3 语法之for循环、if分支语句2.函数3.导入模块4.Jupyter notebook内代码的保存与分享5.数据科学实

使用Jupyter notebook文档写好之后, 保存成为一般的.ipynb的格式, 但是也可以保存成其他的格式, 如: Python(.py), Markd...

852
来自专栏coding for love

JS进阶系列02-JS面向对象的三大特征之封装

JS 作为面向对象的一门语言,拥有和其他面向对象语言一样的三大特征,即封装(encapsulation)、继承(inheritance )和多态(polymor...

892
来自专栏用户2442861的专栏

Python基础学习篇——Global全局变量的使用

为了测试Python中全局变量的使用,我们试图撰写以下几个例子进行说明: #第一例子,是用来验证一个最基础的全局变量与局部变量的区别,内容如下: #-*- c...

850
来自专栏GreenLeaves

C# 命名空间和程序集

一、命名空间 1、通过使用using关键字引入命名空间,减少代码量 命名空间对相关的类型进行逻辑分组,通过命名空间能快速的定位到相关的类型,例如:在System...

2248
来自专栏强仔仔

AngularJS系列之表达式

这节介绍一下AngularJS中表示式的用法。使用表达式可以把数据绑定到HTML中去,使用起来非常方便。不过在使用之前得先引用AngularJS文件,这个文件可...

1827
来自专栏微信公众号:Java团长

触摸Java常量池

java常量池是一个经久不衰的话题,也是面试官的最爱,题目花样百出,这次好好总结一下。

2041
来自专栏思考的代码世界

Python编程从入门到实践之函数2|第9天

向函数传递列表很有用,这种列表包含的可能是名字、数字或更复杂的对象(如字典)。将列表传递给函数后,函数就能直接访问其内容。

3707
来自专栏转载gongluck的CSDN博客

c++ 中__declspec 的用法

c++ 中__declspec 的用法 语法说明: __declspec ( extended-decl-modifier-seq ) 扩展修饰符: ...

7357
来自专栏Java爬坑系列

【Java入门提高篇】Day11 Java代理——JDK动态代理

  今天来看看Java的另一种代理方式——JDK动态代理   我们之前所介绍的代理方式叫静态代理,也就是静态的生成代理对象,而动态代理则是在运行时创建代理对象。...

2067
来自专栏FreeBuf

从反射链的构造看Java反序列漏洞

概况 今天我想从构造反射链的从无到有到被利用来谈谈java的反序列化漏洞,从反射的最开始到执行payload,一个从无到有的过程,首先我们介绍一下Transfo...

2689

扫码关注云+社区

领取腾讯云代金券