Java反序列化和PHP反序列化的区别

2023-09-18 13:56:52


反序列化存在的意义是为了数据传输,类是无法直接进行传输的。通过序列化后转换为字符串格式或者JSON格式进行传输

序列化与反序列化

  • seriallization 序列化 : 将对象转化为便于传输的格式, 常见的序列化格式:二进制格式,字节数组,json字符串,xml字符串。

  • deseriallization 反序列化:将序列化的数据恢复为对象的过程。

PHP反序列化漏洞

PHP反序列化

  • serialize()将对象序列化成字符串。

  • unserialize()将字符串反序列化回对象。

序列化

  • 对象转换成字符串

  • 方便传输

反序列化

  • 字符串转换成对象

  • O:object

<?php
    //创建类
    class Stu{
        public $name;
        public $age;
        public $sex;
    }
	
	//创建对象
    $stu1 = new Stu();
    $stu1->name = "wuhu";
    $stu1->age = 18;
    $stu1->sex = true;
    var_dump($stu1);
    echo "<hr />";
    echo serialize($stu1);

?>

image-20230915193800754

类中的魔术方法,在特定情况下会自动调用。即使魔术方法在类中没有被定义,也是真实存在的。

两个下划线:

  • __construct():在创建对象时自动调用。
  • __destruct()::在销毁对象时自动调用。
  • __wakeup()unserialize()时会自动调用这个函数
  • __sleep()serialize()时会自动调用这个函数

以_开头的函数,是PHP中的魔术方法,是为了更快的响应。__wakeup()和__sleep()方法在互联网上会被频繁调用。

反序列化漏洞不能通过黑盒测试来查找漏洞。只能通过白盒测试,也就是代码审计

反序列化漏洞攻击者是不可控的,因为功能代码全是开发者自己写的。

<?php

    class animal{
        public $name;
        public $age;

        public function __sleep(){
            if(@$_GET['cmd']=="abc"){
                a();
            }
        }

    }

    $an1=new animal;

    $an1->name="dog";
    $an1->age=3;

    //var_dump($an1);

    @serialize($an1);

?>

image-20230915095903605

什么是反序列化漏洞?

序列化和反序列化本身是为了实现数据在网络上完整高效的传输,但是由于反序列化过程中,对象的魔术方法会自动调用,魔术方法本身调用了别的方法,最终呈现一种链式调用,直到执行任意的代码或者命令。并且危险函数的参数可控

修改序列化后的数据,目的是什么?

为了满足一定的条件以后实现链式调用。

Java反序列化漏洞

序列化

ObjectOutputStream --> writeObject()

反序列化:

ObjectInputStream --> readObject() 

实验

Person类

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class Person implements Serializable {
    public int age;
    public String name;

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        Runtime.getRuntime().exec("calc");
        // 默认的反序列化操作
        in.defaultReadObject();
    }
}

注意:想让某个类执行序列化或者反序列化必须实现Serializable接口。

Test类

import java.io.*;

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Person p=new Person();
        p.age=18;
        p.name="wuhu";
		
        //将Person这个类的对象序列化后存放到wuhu.bin文件中
        //没有指定路径就表示存放到当前路径中
        serialize(p,"wuhu.bin");


        System.out.println("反序列化结果:" + deserialize("xiu.bin"));
    }
	
    //序列化
    public static void serialize(Object obj, String filePath) throws IOException {
        try (FileOutputStream fileOut = new FileOutputStream(filePath);
             ObjectOutputStream objectOut = new ObjectOutputStream(fileOut)) {
            objectOut.writeObject(obj);
        }
    }
	
    //反序列化
    public static Object deserialize(String filePath) throws IOException, ClassNotFoundException {
        try (FileInputStream fileIn = new FileInputStream(filePath);
             ObjectInputStream objectIn = new ObjectInputStream(fileIn)) {
            return objectIn.readObject();
        }
    }
}

序列化后的字符串

image-20230915200923576

说明:不同的编程语言的序列化和反序列化后的数据格式不一样。

那么漏洞点在哪里?

将Person类中的readObject方法注释了执行的时候,输出结果就是输出了反序列化后的结果。

image-20230915201540400

那么如果重写readObject方法后,在方法中添加一个Runtime.getRuntime().exec("calc"); 这行代码使用 Java 的 Runtime 类执行操作系统命令,即在 Windows 系统上运行计算器应用程序(calc)。执行结果如下:

image-20230915201716681

在实际的开发环境中,需要重写readObject()方法,例如:从前端传递的值是base64编码的,而系统的方法不识别base64,所以需要在重写的readObject()方法中先解码,将解码完的对象再去调用系统的方法。

漏洞成因

Java反序列漏洞的成因是函数的链式调用,满足链式调用的全部条件,并且参数可控制。以及重写了readObject()方法,才能造成Java反序列漏洞。(条件苛刻)。当然如果没有重写readObject()方法,执行的就是系统的反序列化方法,也就没有了反序列化漏洞了。

什么是反序列化漏洞?

PHP的反序列化和java的反序列化是两种不同的类型,序列化和反序列化本身没有漏洞点,只是为了实现数据的完整高效的传输。

PHP反序列漏洞是由于类里面的魔术方法调用了某个函数,该危险函数又调用了别的函数,最终执行到了危险函数的位置。

JAVA反序列化漏洞是由于开发者重写了readObject方法,该readObject方法方法调用了别的方法,最终执行到了例如Transfrom方法的危险方法(链式调用)。

shiro :爆破密钥,找寻CC利用链

更多推荐

【python百炼成魔】Python循环语句:嵌套循环

前言文章目录前言嵌套循环嵌套的用途嵌套循环案例1.输出一个三行四列的矩形2.打印直角三角形3.写一个九九乘法表总结嵌套循环Python中的嵌套循环是指在一个循环体内部包含另一个循环。通过嵌套循环,我们可以在外部循环的每次迭代中,执行内部循环的所有迭代。嵌套循环可以帮助我们处理一些复杂的问题。嵌套循环的逻辑:forxin

算法leetcode|76. 最小覆盖子串(rust重拳出击)

文章目录76.最小覆盖子串:样例1:样例2:样例3:提示:进阶:分析:在这里插入图片描述题解:rust:go:c++:python:java:76.最小覆盖子串:给你一个字符串s、一个字符串t。返回s中涵盖t所有字符的最小子串。如果s中不存在涵盖t所有字符的子串,则返回空字符串""。注意:对于t中重复字符,我们寻找的子

外包干了2个月,技术退步明显...

先说一下自己的情况,大专生,19年通过校招进入湖南某软件公司,干了接近4年的功能测试,今年8月份,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试,已经让我变得不思进取,谈了2年的女朋友也因为我的心态和工资和我分手了。于是,我决定要改变现状,冲击下大厂。刚开始准备

[C/C++]天天酷跑超详细教程-中篇

个人主页:北·海🎐CSDN新晋作者🎉欢迎👍点赞✍评论⭐收藏✨收录专栏:C/C++🤝希望作者的文章能对你有所帮助,有不足的地方请在评论区留言指正,大家一起学习交流!🤗天天酷跑,一款童年游戏,主要是进行跳跃操作,和躲避障碍物,中篇主要实现人物的下蹲,随机障碍物的生成以及优化main函数里面的sleep(30)一.

Python操作Excel教程(图文教程,超详细)Python xlwings模块详解,

「作者主页」:士别三日wyx「作者简介」:CSDNtop100、阿里云博客专家、华为云享专家、网络安全领域优质创作者「推荐专栏」:小白零基础《Python入门到精通》xlwings模块详解1、快速入门1、打开Excel2、创建工作簿2.1、使用工作簿2.2、操作工作簿3、创建工作表3.1、使用工作表3.2、操作工作表3

C语言练习题解析:挑战与突破,开启编程新篇章!(3)

💓博客主页:江池俊的博客⏩收录专栏:C语言刷题专栏👉专栏推荐:✅C语言初阶之路✅C语言进阶之路💻代码仓库:江池俊的代码仓库🎉欢迎大家点赞👍评论📝收藏⭐文章目录🌴选择题🌴编程题📌记负均正📌旋转数组的最小数字🎈前言:本专栏每篇练习将包括5个选择题+2个编程题,将涵盖C语言的不同方面,包括基础语法、数据

Linux:工具(vim,gcc/g++,make/Makefile,yum,git,gdb)

目录---工具功能1.vim1.1vim的模式1.2vim常见指令2.gcc/g++2.1预备知识2.2gcc的使用3.make,Makefilemake.Makefile的使用4.yum--yum三板斧5.git--git三板斧--Linux下提交代码到远程仓库6.gdb6.1gdb的常用指令学习目标:1.知道这些工

C语言:选择+编程(每日一练)

目录选择题:题一:题二:题三:题四:题五:编程题:题一:珠玑妙算思路一:题二:两数之和思路一:本人实力有限可能对一些地方解释和理解的不够清晰,可以自己尝试读代码,或者评论区指出错误,望海涵!感谢大佬们的一键三连!感谢大佬们的一键三连!感谢大佬们的一键三连!选择题:题一:1、有以下函数,该函数的功能是()intfun(c

python-wordcloud词云

导入模块fromwordcloudimportWordCloudimportjiebaimportimageioimportmatplotlib.pyplotaspltfromPILimportImageGrabimportnumpyasnpwordcloud以空格为分隔符号,来将文本分隔成单词PILpillow模块i

网络安全(黑客)自学

前言一、什么是网络安全网络安全可以基于攻击和防御视角来分类,我们经常听到的“红队”、“渗透测试”等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面性,例如Web安全技术,既有Web渗透,也有Web防御技术(WAF)。作为一个合格的网络安全

Spring WebSocket 认证与授权:掌控安全通道,迈向巅峰之旅!

一、需要了解的事项http和WebSocket的安全链和安全配置是完全独立的。SpringAuthenticationProvider根本不参与Websocket身份验证。将要给出的示例中,身份验证不会发生在HTTP协商端点上,因为JavaScriptSTOMP(websocket)库不会随HTTP请求一起发送必要的身

热文推荐