反序列化基础学习

一、类与对象

php类与对象举例

<?php

class animal {

public $name = 'dahuang';//define a virable

public function sleep(){//define a simpe method

echo $this->name . " is sleeping...\n";

}

}

$dog = new animal();

$dog->sleep();

?>

PHP常见的magic方法:

方法名 触发点

__construct 在创建对象时候初始化对象,一般用于对变量赋初值

__destruct 和构造函数相反,在对象不再被使用时(将所有该对象的引用设为null)或者程序退出时自动调用

__toString 当一个对象被当作一个字符串被调用,把类当作字符串使用时触发,返回值需要为字符串

__wakeup() 使用unserialize时触发,反序列化恢复对象之前调用该方法

__sleep() 使用serialize时触发 ,在对象被序列化前自动调用,该函数需要返回以类成员变量名作为元素 的数组 (该数组里的元素会影响类成员变量是否被序列化。只有出现在该数组元素里的类成员变 量才会被序列化)

__destruct() 对象被销毁时触发

__call() 在对象上下文中调用不可访问的方法时触发,即当调用对象中不存在的方法会自动调用该方法

__callStatic() 在静态上下文中调用不可访问的方法时触发

__get() 用于从不可访问的属性读取数据,即在调用私有属性的时候会自动执行

__set() 用于将数据写入不可访问的属性

__isset() 在不可访问的属性上调用isset()或empty()触发

__unset() 在不可访问的属性上使用unset()时触发

__invoke() 当脚本尝试将对象调用为函数时触发

实例

<?php

class animal {

public $name = 'dahuang';//define a virable

public function sleep(){//define a simpe method

echo $this->name . " is sleeping...\n";

}

public function __construct(){

echo "the method:__construct is called\n";

}

public function __destruct(){

echo "the method:__destruct is called\n";

}

public function __toString(){

return "the method:__toString is called\n";

}

}

$dog = new animal();

$dog->sleep();

echo $dog;

?>

二、PHP 对象序列化

在PHP网站中的定义

所有PHP里面的值都是可以使用函数serialize()来返回一个包含字节流的字符串表示。

unserialize()函数能够重新把字符串。

变回PHP原来的值。序列化一个对象将会保存对象的所有变量,但不会保存对象的方法,只会保存类的名字。

简单的理解序列化:就是把一个类的实例变成一个字符串;

简单的理解反序列化:就是把一个特殊的字符串转换成一个实例。

现在,我们将0x02中的dog对象进行序列化,即将最后一行代码:echo $dog;

改为echo serialize( $dog);

输出结果:高亮部分即为序列化的dog对象

img

序列化后的字符串格式如下:

0:6:"animal":1:{s:4:"name";s:7:"dahuang";}

对象类型:长度:"名字":类中变量的个数:{类型:长度:"名字";类型:长度:"值";......}

序列化格式中的字母含义:

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

三、*PHP反序列化漏洞/PHP对象注入***

例题:

img

题目非常明了,只有一个类site 和一个魔法函数_destruct

unserialize(反序化前自动调用_destruct)

关键 在$a($this->title)

明显的是a参数执行(this->title)

所以在这里可以构造命令执行,利用assert函数执行system系统命令。

在线php网站运行

img

O:4:"site":3:{s:3:"url";s:14:"www.whalwl.com";s:4:"name";s:6:"assert";s:5:"title";s:10:"system(ls)";}

放在Hackbar里 post参数dage

img