php 序列化的字母标识

ctf比赛中经常出现php反序列化的题,所以写一篇博客来记一下php序列化中的字符标识,可能以后会有补充

a:array 数组

php > echo serialize(array());
a:0:{}
php > echo serialize(array(1,2));
a:2:{i:0;i:1;i:1;i:2;}

i:integer 整数

php > echo serialize(14);
i:14;

b:boolean bool值

php > echo serialize(true);
b:1;

d:double 小数

php > echo serialize(1.1);
d:1.1;

O:class 对象

php > class a{}
php > echo serialize(new a());
O:1:"a":0:{}
//解释一下,O表示对象,1表示对象名的字符串长度,'a'是对象名,0是对象内属性个数

s:string 字符串

php > echo serialize('a');
s:1:"a";

N:null NULL值

php > echo serialize(NULL);
N;

r:reference 对象引用

<?php
echo "<pre>";
class SampleClass1
{}
class SampleClass
{
    public $value;
    public $test;
    public function __construct()
    {
        $this->value = new SampleClass1();
        $this->test = $this->value;
    }
}
$a = new SampleClass();
echo serialize($a);
?>
输出O:11:"SampleClass":2:{s:5:"value";O:12:"SampleClass1":0:{}s:4:"test";r:2;}
r:<number> number 的大小:
O:11:"SampleClass" 表示 1 
s:5:"value" 表示 2
r:2表示 s:5:"value" 的引用
注意,值的引用,也就是值的标识符中有R或r,则不计数,如果后面还有属性 比如
O:11:"SampleClass":2:{s:5:"value";O:12:"SampleClass1":0:{}s:4:"test";r:2;s:6:"value1";s:1:"a"}
s:6:"value1" 代表 3 
R和r同理

R:pointer reference

<?php
echo "<pre>";
class SampleClass1
{}
class SampleClass
{
    public $value;
    public $test;
    public function __construct()
    {
        $this->value = new SampleClass1();
        $this->test = &$this->value;
    }
}
$a = new SampleClass();
echo serialize($a);
// O:11:"SampleClass":2:{s:5:"value";O:12:"SampleClass1":0:{}s:4:"test";R:2;}
?>

利用R我们可以在反序列化的时候,将两个属性的值关联起来,是的两个属性值反序列化之后一直相同

<?php
error_reporting(0);
echo "<pre>";

class SampleClass
{
    public $value;
    public $test;
    public function __construct()
    {
        $this->value = 'a';
        $this->test = &$this->value;
    }
}
$a = new SampleClass();
echo serialize($a)."</br>";
$b = serialize($a);
$b = unserialize($b);
$b->value='new value';
echo serialize($b);
//O:11:"SampleClass":2:{s:5:"value";s:1:"a";s:4:"test";R:2;}
O:11:"SampleClass":2:{s:5:"value";s:9:"new value";s:4:"test";R:2;}
?>

以上输出结果表明第二次序列化不改变引用的关系

C:custom object 自定义对象序列化

php有一个接口 Serializable,有两个方法serialize()和unserialize(),在序列化的时候,按照用户自定义方法序列化
c的格式如下

C:<name length>:"<class name>":<data length>:{<data>}

其中 表示类名 的长度, 表示自定义序列化数据 的长度,而自定义的序列化数据 是完全的用户自己定义的格式,与 PHP 序列化格式可以完全无关,这部分数据由用户自己实现的序列化和反序列化接口方法来管理。
例子

class MyClass implements Serializable
{
    public $member;

    function MyClass()
    {
        $this->member = 'member value';
    }

    public function serialize()
    {
        return ($this->member);
    }

    public function unserialize($data)
    {
        $this->member = ($data);
    }
}
$a = new MyClass();
echo serialize($a);
echo "\n";
print_r(unserialize(serialize($a)));
// C:7:"MyClass":12:{member value} MyClass Object ( [member] => member value )

S:encoded string

可以将16进制编码成字符,可以进行绕过特定字符

<?php
class test{
    public $value;
    function __construct(){

    }
}
echo serialize(new test);
$a='O:4:"test":1:{s:5:"value";S:1:"\61";}';
$a=unserialize($a);
var_dump($a);

结果 
O:4:"test":1:{s:5:"value";N;}
object(test)[2]
  public 'value' => string 'a' (length=1)

最后,来个大总结
在这里插入图片描述

参考链接
https://www.evonide.com/fuzzing-unserialize/#comments
https://www.cnblogs.com/wayne173/p/3747465.html

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值