php反序列化(小白学习心得)

首先问自己一个问题为什么要进行序列化与反序列化?
例如我们平时写的字符abcdef可以进行一个显示,但在网络上它是不能进行一个正常的传输的,所以序列化就是需要规定一种格式用来作用于网络的传输。

abcdef+空格,加了空格你看不到,你认为这里没有字符,但实际在url栏里它就是%20;
回车换行就是:%0a %0d;

php的序列化

php提供序列化和反序列化的函数serialize和unserialize,序列化之后的内容是简单的文本格式,但是对字母大小写和空白敏感(空
格,回车,换行)

序列化后字母标示及其含义:

a - array(数组),b-boolean(布偶类型),d-double(双精度浮点数),i-integer (整数),o- common object (对象,php4以后
被O取代了) , r-references (引用) .
s-string (字符串)O-class (类),N-null (空),R-pointer reference(指针),U-unicode string (unicode字符率,
php6才引入) ,C -custom object(自定义对象,php5引入)

N表示的是NULL,而b、d、i、 s表示的是四种标量类型,目前其它语言所实现的PHP序列化程序基本上都实现了对这些类型的序列化和反序列化,不过有—些实现中对s(字符串)的实现存在问题。
a、O属于最常用的复合类型,大部分其他语言的实现都很好的实现了对a的序列化和反序列化,但对О只实现了PHP4中对象序列化格式,而没有提供对PHP 5中扩展的对象序列化格式的支持。
r、R分别表示对象引用和指针引用

标量类型:
b:;
其中为0或1,当boolean型数据为false时,<digit为0,否则为1。bool类型的true和任何字符串弱类型比较为真
i:;
其中为一个整型数,范围为:-2147483648到2147483647。数字前可以有正负号,如果被序列化的数字超过这个范围,则会被序列化为浮点数类型而不是整型。如果序列化后的数字超过这个范围(PHP本身序列化时不会发生这个问题),则反序列化时,将不会返回期望的数值。
s::"";
其中是的长度,是非负整数,数字前可以带有正号(+)。为字符串值,这里的每个字符都是单字节字符,其范围与ASCII码的0 -255的字符相对应。每个字符都表示原字符含义,没有转义字符,两边的引号("")是必须的,但不计算在当中。这里的相当于一个字节流,而是这个字节流的字节个数。
d:;
其中为一个浮点数,其范围与PHP中浮点数的范围一样。可以表示成整数形式、浮点数形式和科学技术法形式。如果序列化无穷大数,则<number为INF,如果序列化负无穷大,则<number为-INF。序列化后的数字范围超过PHP能表示的最大值,则反序列化时返回无穷大(INF),如果序列化后的数字范围超过PHP所能表示的最小精度,则反序列化时返回0。
首先序列化的是对象是类本身,编号为1
R:1表示指针指向本身,2表示非本身的第一个参数,如果改变它的值将会把本身的类型改变表示对象在序列化中第一次出现的位置。
r;1表示引用对象本身,2表示非本身的第一个对象,如果改变它的值就只会改变引用对象的参数值。

<?php
class a{
    public $username='a' ;
    public $password='p';
    public $admin = '123';
    public function add(){
        echo "111";
    }
}
$b =new a();
$c = array('a','b');
echo serialize($c);
echo "<br />";
echo serialize($b);

运行结果:
a:2:{i:0;s:1:"a";i:1;s:1:"b";}<br />O:1:"a":3:{s:8:"username";s:1:"a";s:8:"password";s:1:"p";s:5:"admin";s:3:"123";}

php代码可以在网页上在线运行
在这里插入图片描述
r是个指针类型:1指向password本身,2指向前面的’a’也就是非本身的第一个数,3就是非本身的第二个数。

简单复合的序列化
4.1.数组的序列化
数组(array)通常被序列化为:
a:cn>:{<key 1><value 1><key 2><value 2> …}
其期<表示数组元素的个数,<key 1>、<key 2 .key i>表示数组下标,<value 1>、<value 2 …value n表示与下标相对应的数组元素的值。
仍如🅰️3:{:0;i:1,i:1;s:3:“123”;i:2;1:3,4.2.
4.2对象的序列化
对象(object)通常被序列化为:
0:clength .“class name> “.cn>:{(<field name 1><field value 1><field name 2><field value 2> …cfield name n>]
其中表示对象的类名的字符串长度。<>表示对象中的字段1个数。这些字段包括在对象所在类及其祖先类中用var、public、protected和private声明的字段,但是不包括static和const声明的静态字段。也就是说只有实例(instance)字段。
<liled name 1>、c<led name 2 …filed name n>表示每个字段的字段名,而<iled value 1>、<liled value 2 .…. .liled value n>则表示与字段名所对应的字段值。
字段名是字符串型,序列化后格式与字符串型数据序列化后的格式相同。
字段值可以是任意类型,其序列化后的格式与其所对应的类型序列化后的格式相同。例如:O:8:“stdClass”:3:{s:1:“c”;s:5:”$flag”;s:1:“d”;s:3:“123”;s:1:“f”;N;}
4.3.对象字段名的序列化
var和public声明的字段都是公共字段,因此它们的字段名的序列化格式是相同的。公共字段的字段名按照声明时的字段名进行序列化,但序列化后的字段名中不包括声明时的变量前缀符号S.
protected声明的字段为保护字段,在所声明的类和该类的子类中可见,但在该类的对象实例中不可见。因此保护字段的字段名在序列化时,字段名前面会加上
10*Y0
public声明不需要做任何添加
private声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,字段名前面会加上
1010为声明这个私有类的类名
包含php漏洞的网站: https://bugs.php.net

php反序列化的原理
php的序列化函威: serialize (),反序列化函激数: unserialize ()序列化通俗的讲就是把一个对象变成可以传输的字符串
在这里插入图片描述
产生漏洞的原因:php的魔术方法
魔法函数一般以__开头,通常因为某些条件而触发不用我们手动调用
5个魔法函数:
_construct()当一个对象创建时被调用
destruct()当一个对象销毁时被调用
_toString()当一个对象被当作一个字符串使用
_sleep()在对象在被序列化之前运行
_wakeup将在序列化之后立即被调用

字符串逃逸问题
造成的原因;
字符过滤器放在序列化之后,替换字符串只会替换掉敏感字符串而不会里新修改字符丰的长度;从而导致后文被吃掉字符串导致逃逸或者
顶出亨符串导致逃逸。
; )作为结束,如果后面还有多余内容就不会解析。

过滤器:

1.多换少吃字符把zz替换为a
序列化过后的局部: s:5:“users”;s:3:“zz1”;s:4:“pass”;s:2:“1"11”;
变为s:5:“users”;s:3:“a1”;s:4: “pass”;s:2:11";
此时users的键值只有一个字符但是序列化的标识却有2个字符,也就是说第一个键值会往后吃掉一个字符,如我们能吃到pass前面的一个“,我们就可以自己构造想要的第二个键值对。
于是,需要吃掉的字符就是第一个键值的第二个”到第二个键的第一个“,就可以根据自己的需要构造想要的字符串了。
2.少换多,顶字符
把a换为zz:
s:5:“users”;s:1:“a”;s:4:“pass”;s:2:“11”;
s:5:“users”;s:1:“zz2zzzz s:4:“pass”;s:zzzz2zzzz2:“11”;zzzz”;s:4:“pass”;s:zzzzzzzz2:“11”;
例如我们需要构造的亨符—共有42个那么
s:1: " ax 42+需要的字符“(需要的字符里得闭合前面的”)
这个就可以顶出我们需要的字符,从而构造我们想要的序列化内容

核心: a的字符数+需要的字符数= a被替换后的字符数,这样就只会把a被替换掉的字符数解析完,后面的内容就可以是我们精心构
造的.(重点)
private修饰的变量反序列化后悔会变为(%00类名%00变量名)
public反序列化后内容啥也不加,就正常变量名
protected反序列化后的内容为%00*%00加变量名

不足之处还请师傅们指正!

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: PHP 反序列化是一种常见的安全漏洞,攻击者可以利用这个漏洞来执行恶意代码或者控制 Web 应用程序。要学习 PHP 反序列化,您可以按照以下步骤进行: 1.了解序列化和反序列化的基本概念。序列化是将对象转换为字符串的过程,反序列化则是将字符串转换为对象的过程。在 PHP ,可以使用 serialize() 和 unserialize() 函数进行序列化和反序列化。 2.学习 PHP 反序列化的原理和技术。了解攻击者是如何利用反序列化漏洞来执行恶意代码的,以及如何使用一些工具和技术来发现和利用这些漏洞。 3.掌握 PHP 反序列化的实际操作。可以通过创建漏洞靶场或者参加 CTF 活动来进行实践,学习如何编写和利用反序列化漏洞的利用代码。 4.学习防御 PHP 反序列化漏洞的方法。了解一些常见的防御技术和最佳实践,以减少应用程序受到攻击的风险。 在学习 PHP 反序列化时,建议您选择一些优质的在线资源、书籍、博客或者论坛来学习,例如 OWASP 和 PHP 官方文档。此外,也可以加入一些安全社区或者参加一些培训课程,与其他安全从业者交流和学习经验。 ### 回答2: 学习PHP反序列化的过程可以分为以下几个步骤: 1.了解反序列化的概念:了解反序列化是将已经序列化的数据重新转换为原始的数据结构的过程。在PHP,通过反序列化可以将序列化的对象还原为PHP对象。 2.学习序列化和反序列化的基本语法:了解PHP的序列化函数`serialize()`和反序列化函数`unserialize()`的基本用法和语法。 3.检查可反序列化的数据源:了解在PHP可以被反序列化的数据源有哪些,例如字符串、文件等。同时要注意在反序列化时,要确保数据源的可靠性,避免恶意数据的注入。 4.了解PHP对象的序列化和反序列化:学习如何将PHP对象序列化为字符串,以及如何将序列化的字符串反序列化PHP对象。要了解序列化和反序列化的规则和约束,以确保数据的完整性和可用性。 5.研究PHP反序列化的安全问题:反序列化在应用有一定的安全风险,因为恶意的序列化数据可以导致代码执行漏洞。学习安全的反序列化技术,了解如何避免和防范反序列化攻击。 6.通过实际练习提升技能:通过实践,结合自己的开发经验,写一些简单的反序列化代码,并且测试不同的反序列化情况,加深对反序列化的理解和掌握。 7.学习相关的安全工具和技术:掌握一些常用的PHP反序列化漏洞检测工具和安全技术,以提高对反序列化漏洞的识别和修复能力。 总之,学习PHP反序列化需要理解概念、语法和安全问题,并通过实践不断提升自己的技能。通过不断学习和实践,可以掌握PHP反序列化的使用和安全开发技巧。 ### 回答3: PHP反序列化是指将序列化后的数据重新还原成原始的PHP对象或数组的过程。学习PHP反序列化主要需要掌握以下几个步骤: 1. 了解序列化和反序列化的概念:序列化是将PHP对象或数组转换成字符串的过程,而反序列化则是将字符串还原成原始对象或数组的过程。了解这两个概念对于学习PHP反序列化非常重要。 2. 了解PHP的序列化函数:PHP提供了一些序列化函数,如serialize()函数和unserialize()函数。serialize()函数用于将PHP对象或数组转换成字符串,unserialize()函数则用于将字符串还原成原始对象或数组。 3. 学习序列化格式:PHP的序列化格式是特定的,掌握序列化格式对于理解反序列化非常重要。其,序列化的格式可以通过序列化函数生成的字符串来进行分析,了解其的规律和特点。 4. 学习反序列化漏洞:了解反序列化漏洞是学习PHP反序列化的重要一环。反序列化漏洞是指恶意用户通过在反序列化时植入恶意代码来实现攻击的一种漏洞。了解反序列化漏洞的原理及如何预防和修复是学习PHP反序列化的关键。 5. 实践练习:通过编写PHP代码来进行反序列化的实践练习是学习的重要环节。可以尝试使用serialize()函数将PHP对象或数组序列化,并使用unserialize()函数将序列化后的字符串反序列化,验证反序列化是否成功。 总之,学习PHP反序列化需要了解序列化和反序列化的概念、掌握PHP的序列化函数、学习序列化格式、了解反序列化漏洞以及进行实践练习。通过不断学习和实践,可以提高对PHP反序列化的理解和应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值