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

news2024/11/20 13:24:53

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 面向对象中特有的特性,在特定的情况下被触发,然后在魔术方法中的命令代码就会被执行。

示例

<?php
	class 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;
    }

    @Override
    public 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.coloradmin.cn/o/1010978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue移动端页面适配

页面的适配&#xff0c;就是一个页面能在PC端正常访问&#xff0c;同时也可以在移动端正正常访问。 现在我们可以通过弹性布局【Flexible布局】、媒体查询和响应式布局。除此之外&#xff0c;还可以通过rem和vw针对性地解决页面适配问题。 响应式布局 响应式布局的核心&…

【C++】day6学习成果

#include <iostream>using namespace std;template<typename T> class MyVector { private:T *p; //动态数组的首地址 用来保存数据int Size; //动态数组的元素个数int max1size; //动态数组的最大长度 public://无参数 - 构造一个空的ve…

react路由01——react-routerV6 中路由传递参数的几种方式

react路由01——react-routerV6 中路由传递参数的几种方式 1. 前言1.1 关于react- router&#xff0c;上官网1.2 react脚手架demo 2. 路由简单配置——无参数3. 路由传参方式3.1 params参数3.1.1 params参数——useParams钩子3.1.2 params参数——useMatch钩子 3.2 search参数3…

FFmpeg深入学习

文章目录 前言一、FFmpeg 基础指令二、FFmpeg 应用之视频播放器1、音视频播放流程2、音视频同步 三、FFplay 播放器1、FFmpeg 播放器的整体框架2、ffplay 的初体验及快捷键3、ffplay 模块划分4、ffplay 原理及流程 四、FFmpeg 编解码及转码1、FFmpeg 转码全流程简介2、FFmpeg 转…

某网站小说CSS反爬实战分析

由于是刚开始编写js逆向类型的文章&#xff0c;难免会有不详细之处&#xff0c;敬请谅解 本次的目标是hongshu网的小说接口&#xff0c;我们进入官网随意找到一篇小说后&#xff0c;打开网络请求&#xff0c;分析接口 如图&#xff0c;可以看到有个bookajax.do 的接口让人值得…

Postman使用_断言测试

断言测试可以在Collection、Folder和Request的 pre-request script 和 test script中编写&#xff0c;测试脚本可以检测请求响应的各个方面&#xff0c;包括正文、状态代码、头、cookie、响应时间等&#xff0c;只有测试符合自定义的要求后才能通过。 pm对象提供了测试相关功能…

STM32 CAN使用记录:bxCAN基础通讯

文章目录 目的关键配置与代码轮询方式中断方式收发测试 示例链接总结 目的 CAN是非常常用的一种数据总线&#xff0c;被广泛用在各种车辆系统中。这篇文章将对STM32中CAN的使用做个示例。 CAN的一些基础介绍可以参考下面文章&#xff1a; 《CAN基础概念》https://blog.csdn.n…

uniapp运行到IOS真机提示 错误:请查看是否设备未加入到证书列表或者确认证书类型是否匹配

参考文章&#xff1a;请查看是否设备未加入到证书列表或者确认证书类型是否匹配 ios开发描述文件必须绑定调试设备&#xff0c;只有授权的设备才可以直接安装基座&#xff0c;所以在申请开发描述文件之前&#xff0c;先添加调试的IOS设备。 前往网站https://developer.apple.…

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

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

【自动驾驶决策规划】POMDP之Introduction

文章目录 前言Markov PropertyMarkov ChainHidden Markov ModelMarkov Decision ProcessPartially Observable Markov Decision ProcessBackground on Solving POMDPsPOMDP Value Iteration Example 推荐阅读与参考 前言 本文是我学习POMDP相关的笔记&#xff0c;由于个人能力…

阿里云CDN缓存配置及优化-oss绑定CDN缓存自动刷新功能

参考阿里云官网文档&#xff1a;https://help.aliyun.com/practice_detail/603170 1.缓存时间配置 在缓存管理中&#xff0c;可以方便地指定目录和文件后缀名在CDN节点上的缓存时间&#xff0c;缓存时长配置的长短&#xff0c;取决于源站对该文件的变更频率。我们需要分析下业务…

前后端分离毕设项目之springboot同城上门喂遛宠物系统(内含文档+源码+教程)

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

项目:UDP聊天室

UDP UDP&#xff08;User Datagram Protocol&#xff09;是一种无连接、不可靠、面向数据报的传输协议。与TCP相比&#xff0c;UDP更加轻量级&#xff0c;不提供像TCP那样的可靠性和流控制机制&#xff0c;但具备较低的通信延迟和较少的开销。 UDP具有以下几个特点&#xff1…

数据中台基本概念

数据中台 数据中台&#xff08;Data Midway&#xff09;是一个用于集成、存储、管理和分析数据的中心化平台或架构。它的目标是将组织内散布在各个系统、应用程序和数据源中的数据整合到一个可统一访问和管理的中心位置&#xff0c;以支持数据驱动的决策制定和业务需求。 数据…

单片机第三季-第二课:STM32存储器、电源和时钟体系

目录 1&#xff0c;存储器 1.1&#xff0c;位带操作 2&#xff0c;启动模式 3&#xff0c;电源管理系统 4&#xff0c;复位和时钟 4.1&#xff0c;复位 4.2&#xff0c;时钟 1&#xff0c;存储器 ICode总线&#xff1a; 该总线将Cortex™-M3内核的指令总线与闪存指…

Flutter插件之阿里百川

上一篇&#xff1a;Flutter插件的制作和发布&#xff0c;我们已经了解了如何制作一个通用的双端插件&#xff0c;本篇就带领大家将阿里百川双端sdk制作成一个flutter插件供项目调用&#xff01; 目录 登录并打开控制台&#xff0c;创建应用&#xff1a;填写应用相关信息开通百川…

Vue--1.6计算属性

概念&#xff1a;基于现有的数据&#xff0c;计算出来的新属性。依赖的数据变化&#xff0c;自动重新计算。 语法&#xff1a; 1&#xff09;声明在computed配置项中&#xff0c;一个计算属性对应一个函数。 2&#xff09;使用起来和普通属性一样使用{{计算属性名}} <!do…

Java/ExecutorService中多线程服务ExecuteService的使用

什么是ExecutorService ExecutorService 是 Java 中的一个接口&#xff0c;它扩展了 Executor 接口&#xff0c;并提供了更多的方法来处理多线程任务。它是 Java 中用于执行多线程任务的框架之一&#xff0c;可以创建一个线程池&#xff0c;将多个任务提交到线程池中执行。Exe…

【深度学习】 Python 和 NumPy 系列教程(十五):Matplotlib详解:2、3d绘图类型(1):线框图(Wireframe Plot)

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 0. 设置中文字体 1. 线框图&#xff08;Wireframe Plot&#xff09; 一、前言 Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年创建。它以简洁、易读的语法而闻名&#xff0…

C++模版基础

代码地址 gitgithub.com:CHENLitterWhite/CPPWheel.git 专栏介绍 本专栏会持续更新关于STL中的一些概念&#xff0c;会先带大家补充一些基本的概念&#xff0c;再慢慢去阅读STL源码中的需要用到的一些思想&#xff0c;有了一些基础之后&#xff0c;再手写一些STL代码。 (如果你…