(日更)PHP反序化漏洞解析(2) PHP序列化/反序列化过程

上文中我们简单介绍了下PHP序列化,及为什么要序列化。

弄清楚前面2个知识点后,理解这个过程会更容易。

*****PHP语言中常用的序列化和反序列化函数有serialize,unserialize,json_encode和json_decode.

*****这里介绍serialize,unserialize函数。

目录

serialize函数

unserialize函数


serialize函数

当序列化对象时,PHP在序列化动作之前调用魔法函数 __sleep,这样就允许对象在被序列化之前做任何清楚操作

魔法函数:在php的语法中,有一些系统自带的方法名,均以双下划线开头,它会在特定的情况下被调用。即所谓的魔法函数。

__sleep() 当调用searialize()方法时调用,返回值为数组,表示需要序列化的数据项.

总结:serialize函数使用之前,必须要先调用___sleep函数。

 这里简单介绍一个例子。

<?php

class Student
{
	public $name = '';
	public $num = 0;
	public $subject='';
	public $grade='';
}

$student = new Student();
$student->name = 'OTTO';
$student->num = 1;
$student->subject='math';
$student->grade=65;
	

$str = serialize($student);
echo $str.'<br>';

输出如下:

O:7:"Student":4:{s:4:"name";s:4:"OTTO";s:3:"num";i:1;s:7:"subject";
s:4:"math";s:5:"grade";i:65;}<br>

O:7:"Student":4:{s:4:"name";s:4:"OTTO";s:3:"num";i:1;s:7:"subject";
s:4:"math";s:5:"grade";i:65;}

首先 O:7:"Student"

其中

O表示object                                                                                                                           

7表示对象的类名的字符串长度为7

Student表示对象的类名是Student

4 表示有四个数据字段(类成员)

之后{s:4:"name";s:4:"OTTO";s:3:"num";i:1;s:7:"subject";s:4:"math";s:5:"grade";i:65;}

表示具体的数据字段与字段值。

第一个字段 s:4:"name";s:4:"OTTO";

s:4:"name"; s表示字段的类型是s(string),字段长度是4,字段名称是name

s:4:"OTTO"; s表示字段的类型是s(string),字段的长度是4,字段是OTTO(注意比上面多了一个’值‘

第二个字段s:3:"num";i:1;

s:3:"num"; s表示字段的类型是s(string ),字段长度是3,字段名称是num

i:1;i表示字段值的类型是i(integer),字段值为1.

第三,第四个字段自己可以试一下能不能想出什么样。

unserialize函数

顾名思义,有个un开头,反序列化函数,

unserialize()将之前序列化的结果转化为对象。

serialize使用前要调用魔法函数__sleep() ,而unserialize使用前要调用魔法函数__wakeup()

​  __wakeup() 当类被unserialize()时调用 __wakeup 方法,预先准备对象需要的资源

这里存在一个问题:

序列化过程中,serialize() 会调用sleep()函数,返回值为数组表示需要保存的属性项, 对于文件句柄,数据库连接等资源类型的数据是不能被序列化保存的。

同理unserialize()唤醒对象时,php会调用__wakeup()方法,但与__sleep()不同的是,它返回值为空。被保存的属性都会被解开。

searialize是不能保存资源的。那么唤醒时如果我们想用到这些资源怎么办?回答很肯定,重新创建?那在哪里创建合适呢?当然是__wakeup()方法里面,因为每次唤醒时都会调用此方法嘛。这下我们很清楚这两个方法的用途了。(参考了一位博主的文章)

这样我们基本就了解了这4个函数的关系与作用了。

下面给出将我们得到的字符串转化为Student对象

的代码。

<?php

class Student
{
	public $name = '';
	public $num = 0;
	public $subject='';
	public $grade='';
}

$student = new Student();
$student->name = 'OTTO';
$student->num = 1;
$student->subject='math';
$student->grade=65;
	

$str = serialize($student);
echo $str;
$student='O:7:"Student":4:{s:4:"name";s:4:"OTTO";s:3:"num";i:1;s:7:"subject";s:4:"math";s:5:"grade";i:65;}';
var_dump(unserialize($student));
	?>

结果

O:7:"Student":4:{s:4:"name";s:4:"OTTO";s:3:"num";i:1;s:7:"subject";s:4:"math";s:5:"grade";i:65;}object(Student)#1 (4) {
  ["name"]=>
  string(4) "OTTO"
  ["num"]=>
  int(1)
  ["subject"]=>
  string(4) "math"
  ["grade"]=>
  int(65)
}

下一篇我们介绍简单利用反序化漏洞的产生条件和简单利用。

参考链接PHP魔法方法/函数详解https://blog.csdn.net/inqihoo/article/details/9235103

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值