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 删除。

发表于

我来说两句

1 条评论
登录 后参与评论

相关文章

来自专栏python技术的魅力

更好的编写Python代码的方式

这段代码本身没有任何问题,但是写的时候需要记住Tuple里每个元素都是什么,才能打印出对的描述。为了让代码更容易看懂:

3379
来自专栏Java技术分享

XMLDTD语法详解

本文详细介绍DTD,包括其对元素的定义,属性的定义,以及实体的定义。

1909
来自专栏py+selenium

a=re.findall('b',c)报错提示:TypeError:expected string or buffer

目的:想通过findall选取某个unicode编码的字符串列表(列表里面有元组)

892
来自专栏流媒体

C++继承

class A中有x ;class B集成A,同时也有x。则b.x访问的是B中的x。如果要访问A中的x,则用b.A::x。

884
来自专栏lgp20151222

Class.forName()用法详解

主要功能 Class.forName(xxx.xx.xx)返回的是一个类 Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,...

711
来自专栏C语言及其他语言

[蓝桥杯]时间转换

题目描述 给定一个以秒为单位的时间t,要求用 “< H> :< M> :< S> ”的格式来表示这个时间。< H> 表示时间,< M> 表示分钟, 而< S...

35111
来自专栏猿人谷

Single Number and Single Number II

[1] Given an array of integers, every element appears twice except for one. Find...

1935
来自专栏贾老师の博客

Makefile 变量定义

1316
来自专栏运维技术迷

连仕彤博客[Python练习] 将字典扁平化

1.isinstance():判断v的类型是不是字典,如果不是就直接写入新字典; 2.递归(函数循环) 3.嵌套函数

852
来自专栏上善若水

005android初级篇之jni 一个简单的报错No implementation found for

原因: public class JniSocket { static { System.loadLibrary("SmartSocket"); }

693

扫码关注云+社区