《Web安全基础》07. 反序列化漏洞

web

  • 1:基本概念
    • 1.1:序列化&反序列化
    • 1.2:反序列化漏洞
    • 1.3:POP 链
  • 2:PHP 反序列化
    • 2.1:序列化&反序列化
    • 2.2:魔术方法
  • 3:JAVA 反序列化
    • 3.1:序列化&反序列化
    • 3.2:反射机制
    • 3.3:相关资源


本系列侧重方法论,各工具只是实现目标的载体。
命令与工具只做简单介绍,其使用另见《安全工具录》。

靶场参考:pikachu,WebGoat。

1:基本概念

1.1:序列化&反序列化

序列化(Serialization),指将内存数据(数据结构或对象)转化为一种便于存储或传输的格式(字节序列)的过程。

反序列化(Deserialization),是序列化的逆过程,把字节序列恢复为原先的内存数据,以便在程序中进行进一步处理和使用。

在这里插入图片描述

作用

  • 将内存中的数据转化为字节序列,以便于数据传递和恢复。

用途

  • 把内存数据以字节序列形式永久保存到硬盘上,通常存放在一个文件中(序列化对象)。
  • 在网络上传送内存数据的字节序列(网络传输对象)。

不同语言,不同操作序列化生成的字节流格式一般不同。

1.2:反序列化漏洞

反序列化漏洞(Deserialization Vulnerability):用户可以控制或修改用来反序列化的数据,这可能使攻击者能够操纵序列化对象,将有害数据传递到应用程序中,从而产生安全问题。

漏洞成因
在身份验证,文件读写,数据传输等功能处,未对反序列化接口做访问控制,未对序列化数据做加密和签名,加密密钥使用硬编码(如Shiro 1.2.4),使用不安全的反序列化框架库(如Fastjson 1.2.24)或函数的情况下,由于序列化数据可被用户控制,攻击者可以精心构造恶意的序列化数据(执行特定代码或命令的数据)传递给应用程序,在应用程序反序列化对象时执行攻击者构造的恶意代码,达到攻击者的目的。

反序列化漏洞一般都可执行任意命令或代码。

某些漏洞无法回显,所以一般情况下需要反弹 shell。
黑盒测试可以通过 http 头发现反序列化利用处。

参考文章
常见的Web漏洞——反序列化漏洞

1.3:POP 链

POP(Property-Oriented Programing,面向属性编程),从现有运行环境中寻找一系列能够调用的代码或指令,然后根据需求将这些指令整合成有逻辑的、能实现需求的代码。称为 POP 链。

一般的 CTF 反序列化,存在漏洞的地方在魔术方法(或反射)中,可以通过自动调用魔术方法(或反射)来达到攻击效果。
但是当注入点存在普通的类方法中,通过自动调用的方法就失效了,此时需要找到普通类与魔术方法(或反射)之间的联系,理出一种逻辑思路,通过这种逻辑思路来构造一条 pop 链,从而达到攻击的目的。

参考文章

php反序列化-POP链的构造利用

php反序列化之pop链构造

【Java安全】反序列化-CC3反序列化漏洞POP链分析

2:PHP 反序列化

在这里插入图片描述

2.1:序列化&反序列化

PHP 中的序列化与反序列化:

  • serialize():序列化。
  • unserialize():反序列化。

示例

<?php class Stu {public $name = 'Bob';public $age = 18;public function demo() {echo "Hello";}}$stu = new Stu(); print_r($stu);echo "\n\n----------\n\n";// 进行序列化$stus = serialize($stu);print_r($stus);echo "\n\n----------\n\n";// 进行反序列化$stus = unserialize($stus);print_r($stus);echo "\n\n----------\n\n";
?>

在这里插入图片描述

序列化结果说明:

在这里插入图片描述

2.2:魔术方法

魔术方法是 PHP 面向对象中特有的特性,在特定的情况下被触发,然后在魔术方法中的命令代码就会被执行。

示例

<?phpclass Stu {public $name = 'Bob';public $age = 18;function __construct() {echo "\n对象被创建了__construct()";}function __wakeup() {echo "\n执行了反序列化__wakeup()\n";}function __toString() {echo "\n对象被当做字符串输出__toString\n";return 'asdsadsad';}function __sleep() {echo "\n执行了序列化__sleep\n";return array('name', 'age');}function __destruct() {echo "对象被销毁了__destruct()\n";}}$stu = new Stu();echo "\n";// 序列化$stu_ser = serialize($stu);echo "\n";print_r($stu_ser);echo "\n";// 当成字符串输出echo "$stu";echo "\n";// 反序列化$stu_unser = unserialize($stu_ser);print_r($stu_unser);echo "\n";
?>

在这里插入图片描述

参考文章:

PHP反序列化漏洞详解
https://blog.csdn.net/LJH1999ZN/article/details/123338591

PHP反序列化与魔术方法
https://www.cnblogs.com/20175211lyz/p/11403397.html

php反序列化完整总结
https://xz.aliyun.com/t/12507#toc-15

3:JAVA 反序列化

在这里插入图片描述

3.1:序列化&反序列化

Java 中的序列化与反序列化:

  • 序列化:ObjectOutputStream -> writeObject()
  • 反序列化:ObjectInputStream -> readIObject()

序列化方法对参数指定的 obj 对象进行序列化,把字节序列写到目标输出流中,按 Java 的标准约定文件扩展名为 .ser。

反序列化方法从一个源输入流中读取字节序列,再把字节序列反序列化为一个对象,并将其返回。

示例:以下代码写在 Test.java 文件。
1、javac Test.java
2、java Test

import java.io.*;public class Test {public static void main(String[] args) {try {// 序列化serialize();// 反序列化deserialize();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();}}public static void serialize() throws IOException {Student student = new Student();student.setName("Bob");student.setAge(18);student.setScore(1000);ObjectOutputStream objectOutputStream =new ObjectOutputStream(new FileOutputStream(new File("student.txt")));objectOutputStream.writeObject(student);objectOutputStream.close();System.out.println("序列化成功!已经生成 student.txt 文件");System.out.println("==============================================");}public static void deserialize() throws IOException, ClassNotFoundException {ObjectInputStream objectInputStream =new ObjectInputStream(new FileInputStream(new File("student.txt")));Student student = (Student) objectInputStream.readObject();objectInputStream.close();System.out.println("\n反序列化结果为:");System.out.println(student);}
}class Student implements Serializable {private String name;private Integer age;private Integer score;public void setName(String name) {this.name = name;}public void setAge(Integer age) {this.age = age;}public void setScore(Integer score) {this.score = score;}@Overridepublic String toString() {return "Student:" + '\n' +"name = " + this.name + '\n' +"age = " + this.age + '\n' +"score = " + this.score + '\n';}
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Java 序列化的结果不可读。

Java 序列化的标志特征参考:

  • 数据以 aced 开头,那么这是一段 16 进制的 Java 序列化数据。
  • 数据以 rO0 开头,基本可以确定这是一段 base64 编码的 Java 序列化数据。

3.2:反射机制

Java 中没有魔术方法,但是有反射(Reflection)机制。

Java 反射机制是一种动态获取信息以及动态调用对象方法的功能。即在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个类的成员变量和方法,可以了解任意一个对象所属的类,可以调用任意一个对象的属性和方法。

Java 反射机制允许在运行时获取和操作类、对象、方法、字段等信息,而不需要在编译时知道这些信息的确切类型。反射机制为开发者提供了一种动态获取和操作类的能力,使得编写更灵活、通用和可扩展的代码成为可能。

一般利用反射机制来构造一个执行命令的对象或直接调用一个具有命令/代码执行功能的方法,以此实现任意代码执行。

示例
1、javac Person.java ReflectionExample.java
2、java ReflectionExample

Person.java 文件:

public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public void introduce() {System.out.println("My name is " + name + " and I am " + age + " years old.");}
}

ReflectionExample.java 文件:

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;public class ReflectionExample {public static void main(String[] args) throws Exception {// 使用反射创建 Person 类的实例Class<?> personClass = Class.forName("Person");Constructor<?> constructor = personClass.getConstructor(String.class, int.class);Object personObject = constructor.newInstance("John Doe", 30);// 使用反射调用 Person 类的 introduce 方法Method introduceMethod = personClass.getMethod("introduce");introduceMethod.invoke(personObject);}
}

在这里插入图片描述

3.3:相关资源

参考文章
JAVA反序列化-反射机制

Java 反序列化工具 ysoserial
https://github.com/frohoff/ysoserial

Java 反序列化工具 SerializationDumper
https://github.com/NickstaDB/SerializationDumper/tree/1.12


非鬼亦非仙,一曲桃花水。

——《生查子 · 独游雨岩》(宋)辛弃疾

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/108963.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何获取美团的热门商品和服务

导语 美团是中国最大的生活服务平台之一&#xff0c;提供了各种各样的商品和服务&#xff0c;如美食、酒店、旅游、电影、娱乐等。如果你想了解美团的热门商品和服务&#xff0c;你可以使用爬虫技术来获取它们。本文将介绍如何使用Python和BeautifulSoup库来编写一个简单的爬虫…

MFC-GetSystemFirmwareTable获取系统固件表

获取ACPI表格 void CgetSystemFirmwareTableDlg::OnBnClickedButton1() {//UINT bufferSize GetSystemFirmwareTable(ACPI, 0, NULL, 0);//获取系统固件表/*【参数3和参数4为NULL和0&#xff0c;只是为了返回真实大小】这个函数可以用来获得系统中的各种固件信息&#xff0c;如…

微博情绪分类

引自&#xff1a;https://blog.csdn.net/no1xiaoqianqian/article/details/130593783 友好借鉴&#xff0c;总体抄袭。 所需要的文件如下&#xff1a;https://download.csdn.net/download/m0_37567738/88340795 import os import torch import torch.nn as nn import numpy a…

举例说明用 easylanguage 语言,编写抄底公式

EasyLanguage 语言在金融领域被广泛使用&#xff0c;尤其是用于编写交易策略和算法。以下是一个简单的抄底公式示例&#xff1a; swift 复制 // 定义变量和参数 Dim StopLossPrice As Double Dim TakeProfitPrice As Double Dim InitialPosition As Double Dim SafetyZon…

kafkaStream实时流式计算

2 实时流式计算 2.1 概念 一般流式计算会与批量计算相比较。在流式计算模型中&#xff0c;输入是持续的&#xff0c;可以认为在时间上是无界的&#xff0c;也就意味着&#xff0c;永远拿不到全量数据去做计算。同时&#xff0c;计算结果是持续输出的&#xff0c;也即计算结果…

帧结构的串行数据接收器——Verilog实现

用Verilog 实现一个帧结构的串行数据接收器&#xff1b; 串行数据输入为&#xff1a;NRZ数据加位时钟&#xff08;BCL&#xff09;格式&#xff0c;高位在前 帧结构为&#xff1a;8位构成一个字&#xff0c;64字构成一个帧。每帧的第一个字为同步字。同步字图案存储在可由CPU读…

docker学习1

Docker jar包环境镜像&#xff0c;镜像存在docker仓库中&#xff0c;随用随取&#xff0c;无需现配环境 docker通过隔离机制&#xff0c;各个镜像之间互不干扰 docker比vm轻量化&#xff0c;每次只需运行镜像即可&#xff0c;镜像占内存小启动快&#xff0c;虚拟机启动慢&…

合宙Air724UG LuatOS-Air LVGL API控件-图片(Gif)

图片&#xff08;Gif&#xff09; GIF图片显示&#xff0c;core版本号要>3211 示例代码 方法一 -- 创建GIF图片控件 glvgl.gif_create(lvgl.scr_act()) -- 设置显示的GIF图像 lvgl.gif_set_src(g,"/lua/test.gif") -- gif图片居中 lvgl.obj_align(g, nil, lvgl…

基于SpringBoot蜗牛兼职网的设计与实现【附PPT|万字文档(LW)和搭建文档】

主要功能 前台界面&#xff1a; ①首页、兼职信息推荐、查看更多等 ②职位申请、申请日期、上传简历、点击下载简历、留言反馈等 ③个人中心、上传图片、更新信息等 后台登录&#xff1a; ①用户登录&#xff1a; 个人中心、修改密码、个人信息、职位申请管理 ②企业登录&…

Redis混合模式下的持久化原理

前言 前面文章中我们也介绍过Redis的持久化方式有两种&#xff1a;rdb持久化和aof持久化&#xff0c;具体详情可查看之前文章redis持久化。rdb持久化还是aof持久化它们都有各自的缺点。 rdb和aof缺点 rdb持久化&#xff1a;由于是定期对内存数据快照进行持久化&#xff0c;因此…

ARM架构-伪指令、伪操作、ATPCS协议

汇编中的符号&#xff1a; 1.指令&#xff1a;能够编译生成一条32位的机器码且能被CPU识别和执行 2.伪指令&#xff1a;本身不是指令&#xff0c;编译器可以将其替换成若千条指令 3.伪操作:不会生成代码&#xff0c;只是在编译阶段告诉编译器怎么编译&#xff08;例如&#x…

STM32WB55开发(4)----配置串口打印Debug调试信息

STM32WB55开发----4.配置串口打印Debug调试信息 概述硬件准备视频教学样品申请选择芯片型号配置时钟源配置时钟树RTC时钟配置查看开启STM32_WPAN条件配置HSEM配置IPCC配置RTC启动RF开启蓝牙开启串口调试配置蓝牙参数设置工程信息工程文件设置Keil工程配置代码配置结果演示 概述…