反序列化漏洞

反序列化漏洞

XXXXXXXXXXXXXXX

2025-05-17 发布6 浏览 · 0 点赞 · 0 收藏

反序列化漏洞

反序列化漏洞(Deserialization Vulnerability)是一种安全漏洞,存在于应用程序中对数据进行反序列化操作的过程中。当应用程序接收到外部传递的恶意序列化数据并进行反序列化时,攻击者可以利用这个漏洞执行未经授权的代码或导致应用程序受到攻击。

反序列化漏洞原理

要了解反序列化漏洞,首先我们得知道什么是序列化和反序列化,简单来说序列化:就是将对象转化为字符串进行存储;反序列化:就是将字符串转化为对象;反序列化漏洞:就是在反序列化过程中,如果恶意者可以对将要转换的字符串进行操控,从而达到任意代码执行的操作,就是反序列化漏洞。

反序列化漏洞的主要原理是应用程序在反序列化过程中没有对传入的数据进行足够的验证和过滤,导致攻击者可以利用构造的恶意序列化数据来执行任意代码或远程代码执行攻击。

一般情况下,应用程序在接受到序列化数据后会使用反序列化操作将数据还原成对象。反序列化操作通常涉及到解析输入流,创建对象实例,读取对象属性等操作,在这个过程中,应用程序需要根据序列化的格式和规范来还原对象的状态。而攻击者可以通过构造特定的序列化数据来利用应用程序中的反序列化操作,从而实现代码注入和执行。

例如,攻击者可以构造恶意的Java序列化数据,其中包含可执行的Java代码,当应用程序使用反序列化操作将该数据还原成对象时,就会执行其中的恶意代码,造成安全威胁。

为了利用反序列化漏洞,攻击者需要了解目标应用程序所使用的序列化库和协议,以及应用程序如何处理序列化数据。攻击者可以通过手动构造序列化数据或利用已有的工具来生成恶意序列化数据。

类与对象的关系

1.类相当于设计出来的图纸,对象相当于产品**1.对象是现实中的对象在程序中的模拟。

2.类是同一类对象的抽象,对象是类的某一特定实体。

3.定义类的对象,才可以通过对象使用类中定义的功能。**

如何创建一个类?

创建类的作用

创建类实质上就是将抽象出的数据,代码封装在一起(类声明中的{}),形成类。

目的:增强安全性和简化编程,使用者不必了解具体细节,而只需要通过外部接口,以特定的访问权限,来使用类的成员。

语法形式

class 类名称

{

public:

       公有成员(类与外部的接口)

protected:

          保护型成员(类的继承)

privat:

       私有成员(辅助作用的数据或函数)

}
注意:
1.public修饰的成员,可以在外面直接被调用

2.protected和private是不能在外面直接调用的(在这里pritected和private是一样的。注意,public在外面和类里面都能调用)

3.访问限定符的作用域,直到遇到下一个访问限定符

4.如果没有遇到下一个,那就遇到类的}结束

5.class默认都是private,struct默认都是public(兼容c)
反序列化漏洞简单案例

以下以pikachu靶场中一个简单的反序列化漏洞案例来说明:

序列化serialize()

序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象:

class S{ public $test="pikachu";}
​public s=new S(); //创建一个对象 ​serialize($s); //把这个对象进行序列化 ​序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";} ​O:代表object ​1:表示该对象的类名的字节数(即类名长度为1) ​S:对象的名称 ​1:表示该对象有 1 个属性。 ​s:数据类型 ​4:变量名称的长度 ​test:变量名称 ​s:数据类型 ​7:变量值的长度 ​pikachu:变量值

反序列化unserialize()

就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");echo u->$test; //得到的结果为pikachu

序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题。

Php中的魔术方法

__construct()//创建对象时触发

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

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

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

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

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

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

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

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

__sleep ()

serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误。对象被序列化之前触发,返回需要被序列化存储的成员属性,删除不必要的属性。

__wakeup ()

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

预先准备对象资源,返回void,常用于反序列化操作中重新建立数据库连接或执行其他初始化操作。

__construct

__construct()被称为构造方法,也就是在创造一个对象时候,首先会去执行的一个方法。

__destruct ()

对象的所有引用都被删除或者当对象被显式销毁时执行__destruct()
pikachu内反序列化漏洞靶场页面如下:image.png
当我们输入序列化数据

O:1:"S":1:{s:4:"test";s:7:"pikachu";}

此时反序列化函数将输入的序列化数据还原为了对象。
image.png
如果攻击者在此输入页面中输入恶意代码,则会被该反序列化函数还原为对象,进行执行。

如结合XSS漏洞,在该输入框内输入:

O:1:"S":1:{s:4:"test";s:30:"<script>alert('haha')</script>";}

则会弹出XSS攻击页面
image.png

请前往 登录/注册 即可发表您的看法…