欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > [Web安全 网络安全]-反序列化漏洞

[Web安全 网络安全]-反序列化漏洞

2025/2/6 4:36:23 来源:https://blog.csdn.net/liu17234050/article/details/142987134  浏览:    关键词:[Web安全 网络安全]-反序列化漏洞

文章目录:

一:前言

1.定义

2.原理

3.危害与影响

4.常见场景与案例

5.防御措施

6.魔术方法

7.基本数据类型

二:分类

1.PHP反序列化

例子1 

例子2

2.java反序列化

例子1 

例子2

三:靶场练习


一:前言

1.定义

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

简而言之

序列化与反序列化:按照特定的格式存储与读取的过程目的:为了方便对象的传递使用,反序列化攻击也可以理解为对象注入序列化:把剩菜存进冰箱反序列化:从冰箱拿出剩菜注入攻击:给你冰箱里的剩菜下毒

2.原理

  序列化:将对象转化为字符串进行存储            Serialization      序列化serialize()将对象的状态信息转换为可以存储或传输的形式的过程在序列化期间,对象将其当前状态写入到临时或持久性存储区反序列化:将字符串转化为对象                    UnSerialization    反序列化unserialize()从存储区中读取该数据,并将其还原为对象的过程,成为反序列化在反序列化过程中,如果恶意者可以对将要转换的字符串进行操控,从而达到任意代码执行的操作,就形成了反序列化漏洞
这主要是因为应用程序在反序列化过程中没有对传入的数据进行足够的验证和过滤

3.危害与影响

远程代码执行(RCE):攻击者可以利用反序列化漏洞在目标系统上执行恶意代码,如远程控制命令、窃取敏感数据、修改系统配置等拒绝服务攻击(DoS):攻击者可以构造大量的恶意序列化数据来消耗程序的资源,导致系统崩溃或服务不可用数据篡改和伪造:攻击者可以利用反序列化漏洞来篡改数据或伪造合法的用户会话,导致系统信任恶意构造的数据或执行未经授权的操作提升权限:如果攻击者成功利用反序列化漏洞执行了恶意代码,他们可能会尝试提升其在系统中的权限,获取更高的访问权限敏感信息泄露:反序列化漏洞有可能导致敏感信息泄露,例如通过序列化和反序列化操作中的错误处理机制或日志泄露出敏感数据

4.常见场景与案例

Java中的反序列化漏洞:Java中的ObjectInputStream.readObject()方法用于将序列化的对象数据还原成实际的对象实例如果未对传入的序列化数据进行充分验证和过滤,攻击者可以构造恶意的序列化数据来执行任意代码PHP中的反序列化漏洞:PHP中的unserialize()函数用于将序列化的字符串转换为PHP变量如果应用程序在接收用户输入后直接使用unserialize()函数进行反序列化操作,而没有对输入进行严格的验证和过滤,就可能存在反序列化漏洞.NET中的反序列化漏洞:在.NET Framework中,BinaryFormatter类的Deserialize()方法用于将二进制数据反序列化为对象如果应用程序在使用BinaryFormatter进行反序列化时没有实施有效的安全措施,就可能受到反序列化攻击

5.防御措施

输入验证和过滤:对于外部传入的序列化数据,应该进行严格的输入验证和过滤,确保数据的来源可信和完整应用程序安全配置:在应用程序的安全配置中,禁用或限制不必要的反序列化操作,只允许从受信任的源进行反序列化使用安全的序列化库:选择使用安全性较高的序列化库,这些库通常提供了更多的安全特性和保护机制持续更新和修补:及时更新和修补应用程序中使用的序列化库,以确保已知的反序列化漏洞得到修复检测和监控:实施日志记录和监控机制,及时检测和响应可能的反序列化攻击

6.魔术方法

__construct():当对象被创建时触发__destruct():当对象被销毁前触发__tostring():当对象被当作一个字符串使用时触发__sleep():序列化对象前调用(其返回需要是一个数组指定序列化哪些属性)__wakeup():反序列化恢复对象前调用__call():当调用对象中不存在的方法时调用__get():从不可访问的属性读取数据__callStatic():调用类不存在的静态方式方法时执行__set():用于将数据写入不可访问属性__invoke():调用函数的方式调用一个对象时的回应方法__isset():在不可访的属性上调用isset()或empty()触发__unset():在不可访的属性上使用unset()时触发

7.基本数据类型

布尔值(bool):b:value => b:0整数型 (int):i:value=>i:1字符串型 (str):s:length:"value";=>s:5:"abcde".数组型(array):a:<length>:{key,value pairs};=>a:1:{i:1;s:1:"a"}对象型(object):O:<class_name_length>浮点型(double):d:value=>d:10.8引用类型:R : R:value=> R:2null型:N

二:分类

1.PHP反序列化

例子1 

原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程从而导致代码执行,SQL 注入,目录遍历等不可控后果在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法函数serialize()         //将一个对象转换成一个字符串举例<?php$key='liu';echo serialize($key);?>输出:s:3:"liu";unserialize()       //将字符串还原成一个对象举例<?php$key='s:3:"liu";echo unserialize($key);?>输出:liu测试<?phpclass ABC{public $test;function __construct(){$test = 1;echo '调用了构造函数<br>';}function __destruct(){echo '调用了析构函数<br>';}function __wakeup(){echo '调用了苏醒函数<br>';}}echo '创建对象a<br>';$a = new ABC;echo '序列化<br>';$a_ser=serialize($a);echo '反序列化<br>';$a_unser=unserialize($a_ser);echo '对象快要死了!';?>运行结果创建对象a<br>调用了构造函数<br>序列化<br>反序列化<br>调用了苏醒函数<br>对象快要死了!调用了析构函数<br>调用了析构函数<br>

例子2

 序列化

<?phpclass  Person {var $name="varin";}$user1 = new Person();echo serialize($user1);
?>输出:O:6:"Person":1:{s:4:"name";s:5:"varin";}O:对象6:对象名称长度Person:对象名称1:表示有一个值s:字符串4:变量名长度name:变量名称5:变量名长度varin:变量名称

反序列化

<?phpclass  Person {var $name="varin";}$user2 = unserialize($user1_ser);print_r($user2);echo $user1->name;
?>输出Person Object([name]=> varin )varin

2.java反序列化

例子1 

Java 反序列化是将已序列化的对象状态恢复为对象的过程序列化是通过实现 java.io.Serializable 接口来完成的反序列化则是通过使用 ObjectInputStream 类来实现的以下是一个简单的 Java 反序列化示例:创建一个实现 Serializable 接口的类序列化该类的对象并将其写入文件从文件中读取并反序列化该对象运行步骤首先运行 SerializeDemo 类,将 Person 对象序列化并保存到 person.ser 文件中然后运行 DeserializeDemo 类,从 person.ser 文件中读取并反序列化 Person 对象,并打印到控制台输出Deserialized Person...  Person{name='Alice', age=30}输出表明成功从person.ser文件中读取了序列化数据数据被正确反序列化为Person对象反序列化后的Person对象的状态(即其name和age字段的值)与序列化时保持一致

1. 创建实现 Serializable 接口的类

import java.io.Serializable;  public class Person implements Serializable {  private static final long serialVersionUID = 1L; // 推荐定义这个UID,确保序列化的兼容性  private String name;  private int age;  public Person(String name, int age) {  this.name = name;  this.age = age;  }  @Override  public String toString() {  return "Person{name='" + name + "', age=" + age + '}';  }  // Getter 和 Setter 方法(可选)  public String getName() {  return name;  }  public void setName(String name) {  this.name = name;  }  public int getAge() {  return age;  }  public void setAge(int age) {  this.age = age;  }  
}

2. 序列化对象并写入文件

import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.ObjectOutputStream;  public class SerializeDemo {  public static void main(String[] args) {  Person person = new Person("Alice", 30);  try (FileOutputStream fileOut = new FileOutputStream("person.ser");  ObjectOutputStream out = new ObjectOutputStream(fileOut)) {  out.writeObject(person);  System.out.println("Serialized data is saved in person.ser");  } catch (IOException i) {  i.printStackTrace();  }  }  
}

3. 从文件中读取并反序列化对象

import java.io.FileInputStream;  
import java.io.IOException;  
import java.io.ObjectInputStream;  public class DeserializeDemo {  public static void main(String[] args) {  Person person = null;  try (FileInputStream fileIn = new FileInputStream("person.ser");  ObjectInputStream in = new ObjectInputStream(fileIn)) {  person = (Person) in.readObject();  } catch (IOException i) {  i.printStackTrace();  } catch (ClassNotFoundException c) {  System.out.println("Person class not found");  c.printStackTrace();  }  System.out.println("Deserialized Person...");  System.out.println(person);  }  
}

例子2

序列化 

class S{public $test="pikachu";
}
$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:变量值

反序列化

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

三:靶场练习

当我们输入序列化数据:O:1:"S":1:{s:4:"test";s:7:"pikachu";}此时反序列化函数将输入的序列化数据还原为了对象如果攻击者在此输入页面中输入恶意代码,则会被该反序列化函数还原为对象,进行执行比如O:1:"S":1:{s:4:"test";s:30:"<script>alert('haha')</script>";}O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";} 则会弹出XSS攻击页面

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com