PHP反序列化漏洞


前言

序列化是将对象的状态信息转换为可以存储或传输得到形式的过程

序列化(Serialization)在计算机科学的数据处理中,是指将数据结构对象状态转换成可取用格式(例如存成文件,存于缓冲,或经由网络中发送),以留待后续在相同或另一台计算机环境中能恢复原先状态的过程。其作用主要体现在以下几个方面:

1、方便网络传输:在网络通信中,数据需要以特定的格式进行传输。序列化可以将对象转换为字节流,从而方便地在网络上传输。接收方再对这些字节流进行反序列化,即可恢复出原始的对象。这对于分布式系统和微服务架构中的数据传输尤为重要。
2、方便数据存储:序列化可以将对象转换为紧凑的字节流形式,从而节省存储空间。同时,通过将对象持久化到外部存储中(如数据库、文件系统等),可以在需要时通过反序列化恢复出对象,实现数据的长期保存和恢复。
3、实现对象的持久化:对象持久化是指将对象的状态保存到存储介质中,以便在程序重新启动或重新加载时能够恢复对象的状态。序列化是实现对象持久化的一种有效手段。通过将对象序列化为字节流并存储到磁盘或其他持久化存储介质中,可以在需要时通过反序列化恢复出对象。
4、方便协议解释:序列化中的“序”即有序的意思,有序的字符串序列可以供绝大多数的编程语言解释。例如,Protocol Buffers等序列化框架可以生成跨平台、跨语言的序列化代码,使得不同语言之间的数据传输和协议解释变得更加方便。
然而,序列化也存在一些不足和潜在的安全问题。例如,序列化过程可能会增加一定的性能开销;同时,反序列化过程中如果处理不当,可能会引发安全漏洞,如反序列化攻击等。因此,在使用序列化功能时,需要权衡其优缺点,并采取相应的安全措施来保障系统的稳定性和安全性。

一、反序列化

反序列化是将序列化得到的字符串转化为一个对象的过程
反序列化生成的对象的 成员属性值被反序列化字符串 决定,与 原来 类 预定义 的 值 无关(这句话说明我们可以通过修改序列化的字符来改变对象的属性值);
反序列化使用unserialize()函数将字符串转换为对象,序列化使用serialize()函数将对象转化为字符串;
反序列化不触发类的成员方法,需要调用方法后才能触发。

class demo{
   
	public $name = "12345";
	private $age;
	public function jr(){
   
		echo $thid->name;
	}
}
// 0:4:"demo":2:{s:4:"name";s:5:"12345";s:9:"%00demo%00age";N;}
echo serialize(new demo());

我们通过修改序列化后的字符串,然后将修改后的字符串进行反序列化就可以达到修改对象的目的。

二、反序列化漏洞利用

反序列化漏洞的原因:反序列化过程中,unserialize()接收的值可控
既然我们知道了,如果有一个接口或程序可以接受一个序列化字符串,然后会进行反序列化,那么我们是不是可以篡改这个序列化字符串,在其中加入一些我们要实现的指令,让他触发,从而达到我们的目的呢?
看到这里,我们又会发现一个问题,那就是我们要怎么去让篡改后的数据,让其在服务器中反序列化时会触发我们植入的命令呢?
下面就是在PHP中一些可以让命令触发的方法。

1.魔法方法

魔法方法是一个预定好的、在特定情况下自动触发的行为方法;
魔法方法的作用:魔术方法在特定条件下自动调用相关方法最终导致触发代码

__construct() //类的构造函数,创建对象时触发
__destruct() //类的析构函数,对象被销毁时触发
__call() //调用对象不可访问、不存在的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //调用不可访问、不存在的对象成员属性时触发
__set() //在给不可访问、不存在的对象成员属性赋值时触发
__isset() //当对不可访问属性调用isset()或empty()时触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //把对象当初函数调用时触发
__sleep() //执行serialize()时,先会调用这个方法
__wakeup() //执行unserialize()时,先会调用这个方法
__toString() //把对象当成字符串调用时触发
__clone() //使用clone关键字拷贝完一个对象后触发

2.构造POP链

下面是一个PHP靶场代码

class Modifier{
   
	private Svar; I
    // $var=flag.php
    public function append($value)
    {
   
        include($value);
        echo $flag;
    }
    public function __invoke(){
   
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Whoam_laowei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值