浅谈PHP序列化,反序列化

1.序列化是什么意思呢?

序列化就是把本来不能直接存储的数据转换成可存储的数据,并且不会丢掉数据格式  serialize(); 

2.反序列化是什么意思呢?

其实就是字面的意思,把序列化的数据,转换成我们需要的格式      unserialize();

那么什么是序列化呢,序列化说通俗点就是把一个对象变成可以传输的字符串。举个例子,不知道大家知不知道json格式,这就是一种序列化,有可能就是通过array序列化而来的。而反序列化就是把那串可以传输的字符串再变回对象。

相关网站

https://www.cnblogs.com/junyi-bk/p/11631685.html

直接上例子便于理解:

我们先讲一讲比较简单的序列化,我们就用序列化json来举例子吧。虽然序列化Json和我们讲PHP反序列化的漏洞没有什么关系。但是在理解序列化这个概念和之后的内容会有所帮助

json_encode()

json_decode()

json_decode( )    ---- json 转 对象/数组

当第二个参数为true返回 array ,默认是false返回object。

json_encode( )    ---- 对象/数组 转 json

成功返回 json 编码的 string ,失败返回 false 。

相应网站

https://www.runoob.com/php/php-json.html

上代码

<?php

$book = array('book1'=>'1','book2'=>'2','Book3'=>'3','Book4'=>'4');

$json = json_encode($book);

var_dump($book);

echo $json;

?>

这边有一个book的数组

‘book1′=>’1’,

‘book2′=>’2’,

‘Book3′=>’3’,

‘Book4′=>’4’

  如果我们想传输这个数组怎么办呢,我们就可以请json_encode()这个函数帮助我们将这个数组序列化成一串字符串

  所以在这里,我们将数组序列化成json格式的字串的目的就是为了方便传输。我们可以看见,这里json格式来保存数据主要是使用键值对的形式。

好啦,接下来我们要开始深入一步,来讲讲如何把一个对象序列化成一串字符串。

假设,我们写了一个class,这个class里面存有一些变量。当这个class被实例化了之后,在使用过程中里面的一些变量值发生了改变。以后在某些时候还会用到这个变量,如果我们让这个class一直不销毁,等着下一次要用它的时候再一次被调用的话,浪费系统资源。当我们写一个小型的项目可能没有太大的影响,但是随着项目的壮大,一些小问题被放大了之后就会产生很多麻烦。这个时候PHP就和我们说,你可以把这个对象序列化了,存成一个字符串,当你要用的时候再放他出来就好了。

那么,怎么才能把一个对象序列化呢?

<?php

class DemoClass

{

public $name = "";

public $sex = "";

public $age = "";

}

$example = new DemoClass();

$example ->name ="111";

$example ->sex ="woman";

$example ->age ="18";

echo(一:);

var_dump($example);

$val = serialize($example);

echo(二:);

echo($val);

echo(三:);

var_dump($val);

$Newex = unserialize($val);

echo(四:);

var_dump($Newex);

echo(五:);

echo $Newex ->age;

?>

这里,我们先创了个DemoClass,里面存了点信息,后来我们new了一个实例$example的时候,将这个class里的一些信息给改变了。

如果我们之后还要用到这个实例怎么办呢,我们就先将他序列化存起来,到时候用的时候再放出来就好啦。

只要用serialize()这个函数就行了,反之利用unserialize()就可以将其进行反序列化回来。

serialize() 函数用于序列化对象或数组,并返回一个字符串。

serialize() 函数序列化对象后,可以很方便的将它传递给其他需要它的地方,且其类型和结构不会改变。

如果想要将已序列化的字符串变回 PHP 的值,可使用 unserialize()


相应网站

https://www.runoob.com/php/php-serialize-function.html

这个时候,我们发现这次序列化出来的格式,和我们上一个序列化json的格式有点不同呢,解释一波:


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

private 的属性序列化后变成 <0x00>对象<0x00>属性名

public 没有任何变化

protected 的属性序列化后变成 <0x00>*<0x00>属性名

特殊十六进制<0x00>表示一个坏字节,就是空字节

3. 为什么会产生这个漏洞?

那么,问题来了,这么序列化一下然后反序列化,为什么就能产生漏洞了呢?

这个时候,我们就要了解一下PHP里面的魔术方法了,魔法函数一般是以__开头,通常会因为某些条件而触发不用我们手动调用:

在研究反序列化漏洞的时候,碰见这几个魔法函数就要仔细研究研究了:

__construct()  // 当一个对象创建时被调用,

__destruct()    // 当一个对象销毁时被调用,

__toString()    // 当一个对象被当作一个字符串被调用。

__wakeup()      // 使用unserialize()会检查是否存在__wakeup()方法,如果存在则会先调用,预先准备对象需要的资源

__sleep()      // 使用serialize()会检查是否存在__wakeup()方法,如果存在则会先调用,预先准备对象需要的资源

__destruct()    // 对象被销毁时触发

__call()        // 在对象上下文中调用不可访问的方法时触发

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

__get()        // 用于从不可访问的属性读取数据

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

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

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

__toString()    // 把类当作字符串使用时触发,返回值需要为字符串

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

相关网站

https://www.php.net/manual/zh/language.oop5.magic.php

如果服务器能够接收我们反序列化过的字符串、并且未经过滤的把其中的变量直接放进这些魔术方法里面的话,就容易造成很严重的漏洞了。

举个别人的例子:

<?php

class A{

    var $test = "demo";

    function __destruct(){

            echo $this->test;

    }

}

$a = $_GET['test'];

$a_unser = unserialize($a);

?>

这里我们只要构造payload:

test=O:9:"DemoClass":3:{s:4:"name";s:5:"Harry";s:3:"sex";s:5:"woman";s:3:"age";s:2:"18";}

就能控制echo出的变量,比如你能拿这个来进行反射型xss。(听你扯了半天你就给我看这个,别打我!)

参考网站:http://www.manongjc.com/detail/12-lbohplauhhknatd.html#!/h

https://www.cnblogs.com/xiaoqiyue/articles/10951836.html

注:本博客所引用的博客仅用与学术交流。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容