java安全 反序列化(二)

java反序列化漏洞分析 Java反序列化漏洞(Java Deserialization Vulnerabilities)是一种常见的安全漏洞,其攻击方式是利用Java中的序列化和反序列化机制,通过在序列化数据中插入恶意代码,导致反序列化过程中执行恶意代码。Java反序列化漏洞是由于Java序列化机制本身的缺陷导致的。为了防止恶意序列化数据被反序列化,可以在程序中对未知的序列化数据进行拒绝,或者对序列化数据进行白名单或黑名单的过滤。Java反序列化漏洞的攻击方式主要有两种:基于本地文件的反序列化攻击和基于网络的反序列化攻击 阅读详情

java安全 反序列化(二)

前言

寻找反序列化链(Gadget)

  1. 在项目里找漏洞

    readObject里的漏洞一般比较少

  2. 寻找项目的依赖库类中的Gadget

    一些依赖也会有反序列化的操作,如果jar包中的某些类在进行反序列化时有可控的点,就可以利用jar包中存在的漏洞来构造调用链

ysoserial工具

ysoserial工具可以帮助我们在依赖库里面找到利用链。

git clone https://github.com/frohoff/ysoserial.git

进入ysoserial目录,编译jar包

mvn clean package -DskipTests

image-20221128161645257

出现BUILD SUCCESS表示编译成功,在target文件夹下

注意:要使用java 1.7+ 的jdk环境

最经典的反序列化利用链

Apache Commons Collections.jar中的一条pop链,这个类库使用广泛,所以很多大型的应用也存在着这个漏洞。

Commons Collections 在3.x < 3.2.2 以及4.0这些版本范围里,存在反序列化漏洞

当目标Java应用依赖库里包含存在漏洞的Commons Collections库,且对由攻击者可控的数据进行反序列化时,即会造成任意代码执行。

我们以ysoserial里CommonsCollections6这个payload为例,进行分析。

先使用ysoserial生成反序列化的payload

image-20221128161942308

使用maven导入commons-collections依赖

pom.xml

        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2.1</version>
        </dependency>

在创建测试代码

TestCC6

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.InvocationTargetException;

public class TestCC6 {
   
   
    public static void main(String[] args) throws IOException, ClassNotFoundException{
   
   
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("cc6.ser"));
        objectInputStream.readObject();
        objectInputStream.close();
    }
}

把生成的cc6.ser放在项目根目录下执行代码,弹出计算机

image-20221128172245115

运行环境为java11

要解析cc6链的结构代码要先学习下java反射相关,我们可以在很多java漏洞的POC中看到反射的利用,所以学习java安全是绕不开反射的。

java反射

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性(包括私有的方法和属性);这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

涉及到java中的几个类:

Class类	代表类的实体,在运行的java应用程序中表示类和接口

Field类:代表类的成员变量(成员变量也称为类的属性)

Method类:代表类的方法

Constructor类:代表类的构造方法

在Java中你看到的绝大部分成员,其实都可以称之为对象(除了普通数据类型和静态成员)。

类也是对象,类是java.lang.Class类的实例对象

Class类抽象出了java中类的特征并提供了一些方法

有三种方式获得Class类实例:

1.如果知道class的完整类名,可以调用Class类的静态方法Class.forName获取
Class clz = Class.forName("com.dong.User");

2.任何一个类都有一个隐含的静态成员class,这个属性就存储着这个类对应的Class类的实例:
Class clz = com.dong.User.class;

3.调用这个对象的getClass()方法:
Class clz = (new User()).getClass();

测试获取,调用方法

User

public class User {
   
   
        public void test(String name){
   
   
            System.out.println("Hello:"+name);
        }
    }
获取方法:

我们之前已经提到了Method这个类,java中所有的方法都是Method类型,所以我们通过反射机制获取到某个对象的方法也是Method类型的。通过Class对象获取某个方法:

方法的名称和方法的参数列表,两者信息才能确定某一个方法

clz.getMethod(方法名,这个方法的参数类型)
调用方法:

Method类中有一个invoke方法,就是用来调用特定方法的,用法如下:

public Object invoke(Object obj, Object... args)

第一个参数是调用该方法的对象,第二个参数是一个可变长参数,是这个方法的需要传入的参数

testUser

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class testUser {
   
   
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
   
   
        Class user = (new User()).getClass();
        //第二个参数要传class类,如果参数有多个传入:new Class[]{String.class,String.class} 
        Method test = user.getMethod("test",String.class);
        //如果第二个参数有多个传入:new Object[]{"1","2"}
        test.invoke((new User()),"liangBan");
    }
}
image-20221129140628374

修改变量

User

public class User {
   
   
    private String pass = "123321";
    @Override
    public String toString() {
   
   
        return "User{" +
                "pass='" + pass + '\'' +
                '}';
    }
}

testUser

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class testUser {
   
   
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
   
   
        Class user = (new User()).getClass();
        //获取私有属性对象
        Field pass = user.getDeclaredField("pass");
        //关闭java访问控制检查,就可以给private属性赋值调用
        pass.setAccessible(true);
        User u = new User();
		System.out.println(u);
        pass.set(u,"liangban");
        System.out.println(u);
        System.out.println(pass.get(u));
    }
}

常用方法

获取类:forName / getClass

获取类下的函数: getMethod/s / getDeclaredMethod/s

执行类下的函数: invoke

获取类构造方法: getConstructor/s / getDeclaredConstructor/s

Web安全--反序列化漏洞(java篇) java反序列化参考 阅读详情

相关推荐

java反序列漏洞原理分析及防御修复方法

Java反序列化漏洞原理 谈起java反序列化漏洞,相信很多人都不会陌生,这个在2015年首次被爆出的漏洞,几乎横扫了包括Weblogic、WebSphere、JBoss、Jenkins等在内的各大java web server,历经几年的发展变种,各种语言工具依次爆出存在可利用的反序列化漏洞。 具全网分析以及shodan扫描显示,时至今日,在全球范围内的公网上大约有136,818台服务器依...

m0_38103658的博客 1万+

Java 反序列化原理与基础,URLDNS攻击链分析

​ 序列化是指将对象转化为字节流,其目的是便于对象在内存、文件、数据库或者网络之间传递。反序列化则是序列化的逆过程,即字节流转化为对象的过程,通常是程序将内存、文件、数据库或者网络传递的字节流还原成对象。在 Java 原生的API 中,序列化的过程由 ObjectOutputStream 类的 writeObject()方法实现,反序列化过程由 ObjectInputStream 类的 readObject()方法实现。

weixin_49248030的博客 1069

Java反序列化漏洞深度剖析:从CC3链原理到实战攻防

Java反序列化机制允许将对象状态转换为字节流进行传输或存储,其核心原理是通过readObject等方法在反序列化过程中自动重建对象。这一机制在提升开发效率的同时,也引入了严重的安全风险——攻击者可通过精心构造的序列化数据触发特定方法链,最终实现任意代码执行。其技术价值在于揭示了JVM底层对象模型与动态类加载机制的潜在脆弱性,广泛应用于RPC通信、会话持久化、缓存存储等场景。本文聚焦于Apache Commons Collections 3(CC3)这一经典利用链,深入解析其基于TemplatesImpl和

weixin_30275415的博客 370

JAVA 反序列化攻击

Java 反序列化攻击漏洞由 FoxGlove 的最近的一篇博文爆出,该漏洞可以被黑客利用向服务器上传恶意脚本,或者远程执行命令。 由于目前发现该漏洞存在于 Apache commons-collections, Apache xalan 和 Groovy 包中,也就意味着使用了这些包的服务器(目前发现有WebSphere, WebLog...

weixin_33962621的博客 577

[Java安全入门].序列化与反序列化

Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。将程序中的对象,放入文件中保存就是序列化,将文件中的字节码重新转成对象就是反序列化

qq_34942239的博客 1558

Serializable()-Java SE安全编码指南(序列化和反序列化)

摘要:Java SE安全编码指南(序列化和反序列化) 在Java开发中,序列化可能带来严重的安全风险,特别是对安全敏感类。序列化会暴露类的私有字段,并引入隐藏的公共构造函数,可能绕过安全检查。安全敏感类应避免实现Serializable接口,或显式阻止序列化(如抛出NotSerializableException)。此外,需注意Lambda表达式可能无意中捕获敏感数据,若可序列化则会导致数据泄露。建议使用组合而非继承避免意外的序列化,并通过安全的数据传输对象(DTO)传递必要信息。对于密钥等敏感数据,应使用

m0_57392857的博客 1127

IO流之反序列化

这就导致如果你通过序列化流将对象边写到本地,修改javabean类后版本号改变,再使用反序列化流读取时会出现异常。javabean类中,java会根据成员方法自动生成一个版本号,如果你修改了其中的方法,版本号也会改变。解决该问题的方法为,手动设置该javabean类的版本号。解决方案:使用transient关键字。

buith9879的博客 115

java安全(五)java反序列化

序列化 在调用RMI时,发现接收发送数据都是反序列化数据. 例如JSON和XML等语言,在网络上传递信息,都会用到一些格式化数据,大多数处理方法中,JSON和XML支持的数据类型就是基本数据类型,整型、浮点型、字符串、布尔等,如果开发者希望在传输数据的时候直接传输一个对象,那么就不得不想办法扩展基础的JSON(XML)语法。比如,Jackson和Fastjson这类序列化库,在JSON(XML)的基础上进行改造,通过特定的语法来传递对象. RMI使用java语言内置的序列化方法,将一个对象转化成一串进制

weixin_45694388的博客 6610

JAVA反序列化安全

微信公众号:DebugPwn 新浪微博: http://weibo.com/u/2275304001/home?wvr=5 漏洞简介: 反序列化漏洞有十年的历史,存在于不同的编程语言中,最为明显的当属Java、PHP、Python、Ruby。漏洞的本质就是反序列化机制打破了数据和对象的边界,导致攻击者注入的恶意序列化数据在反序列化过程中被还原成对象,

c0c0cf的专栏 6349

6-java安全——java反序列化漏洞利用链

本篇将学习java反序列化漏洞原理,然后结合一个apache commons-collections组件反序列化漏洞来学习如何构造利用链。 我们知道序列化操作主要是由ObjectOutputStream类的 writeObject()方法来完成,反序列化操作主要是由ObjectInputStream类的readObject()方法来完成。当可序列化对象重写了readObject方法后,在反序列化时一般会调用序列化对象的readObject方法。 在Student类中重写ObjectInputSt

网络安全 5148

漫谈Java反序列化

Java反序列化漏洞探索出了Java安全的新纪元。开发人员为什么要反序列化呢?

Summer's blog 5666

Java 反序列化

反序列化基础 Java 的序列化(Serialization)和反序列化(Deserialization)是将对象的状态转换为字节流并恢复的过程。这个过程使对象可以保存到文件、通过网络传输或保存到数据库中,并在稍后恢复成对象。 序列化(Serialization):将 Java 对象的状态转换为字节流的过程。这使得对象可以保存到文件、发送到其他 JVM 甚至通过网络传输。 反序列化(Deserialization):将字节流转换回 Java 对象的过程。这允许恢复先前序列化的对象状态。 序列化条件 要使

sky123博客 3806

Java反序列化攻击通俗讲解

想象一下,你把一只猫放进冰箱(序列化),需要时再拿出来(反序列化)。但黑客偷偷把冰箱里的猫换成了老虎(恶意代码),当你打开冰箱时——砰!老虎跳出来咬你一口!这就是Java反序列化攻击的可怕之处。

weixin_43172311的博客 2277

Java 反序列化漏洞

在各种编程语言反序列化漏洞中,Java是最引人瞩目的,因为Java开发生态中各种第三方库组件相互依赖,经常出现开发中常用的基础底层组件出现安全问题时,会引发核弹式反应,进而影响到上层得操作系统。

qq_61553520的博客 5906

[JAVA安全]JACKSON反序列化

JACKSON反序列化原理

snowlyzz的博客 2347

安全反序列化(Insecure Deserialization)深度解析与 Java 防护实践

反序列化是将进制数据转换为对象的过程,在 Java 中广泛用于 RMI、JMX、网络通信等场景。不安全反序列化(Insecure Deserialization)指应用在反序列化不可信数据时,未对输入进行严格校验,导致攻击者可通过构造恶意序列化数据,执行任意代码、获取系统权限或发起拒绝服务攻击。重写方法,添加输入验证和安全检查:java// 自定义反序列化方法// 验证数据完整性throw new InvalidObjectException("数据长度超出限制");

ruanjiananquan99的博客 1271

Java安全—原生反序列化&重写方法&链条分析&触发类

虽然今天的内容看起来有点复杂,但总结起来就一件事,想办法调用其它的readObject,而不是去调用原本的readObject。最后还是要声明一下,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。

2301_76227305的博客 1299
上一篇: java安全 反序列化(一)
下一篇: CVE-2020-1938
助安社区
博客等级 码龄4年 30粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值