IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Java反序列化 -> 正文阅读

[Java知识库]Java反序列化

在这里插入图片描述

Java反序列化概念

在说反序列化之前,先说说序列化

序列化就是将对象转化为字节流,利于存储和被引用

反序列化与序列化恰恰相反,是将字节流转化为对象

序列化的格式:json序列化,xml序列化,二进制序列化,SOAP序列化

序列化调用的函数

  • 序列化:java.io.ObjectOutputStream 类中的 writeObject()
  • 实现 Serializable 和 Externalizable 接口的类才能被序列化

反序列化调用的函数

  • 反序列化:java.io.ObjectInputStream 类中的 readObject()

漏洞原理

思考:为什么在反序列化的时候会产生漏洞呢,下面这两个点是关键的

  • 某个函数的参数输入可控
  • 输入的命令被反序列化(也就是被执行)

漏洞原理

原理:在 Java中,重写的方法会优先执行。如果重写了readObject(),并且函数中某个参数的输入可控,那么攻击者就可以输入任意命令(代码)。在反序列化过程中调用readObject()方法时,就会执行恶意命令,造成攻击。

关键:输入的数据进行了反序列化操作

漏洞危害

由于上述介绍说到输入可控,因此可以结合远程命令执行(RCE),也可以通过RCE进行webshell上传(写文件)等

漏洞出现点

漏洞经常存在于一些 web组件中。例如 weblogic,Fastjson,JBoss,WebSphere,Jenkins,OpenNMS,Shiro

需要了解以下知识

  • HTTP请求的参数cookie,Parameters
  • RMI协议,完全基于序列化
  • JNDI
  • JMX 协议,用于处理序列化对象

RMI 协议(Remote Method Protocol):远程方法调用。在JAVA 中,只要一个类 extends了 java.rmi.Remote接口,这个类就可以被客户端远程访问,并提供服务。

RMI协议默认端口1099,基于socket协议

JNDI(Java Naming and Directory Interface,Java命名和目录接口):是一个接口,能够查找和访问各种命名和目录服务。比如LDAP,DNS,RMI,CORBA。

JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI 服务供应接口(SPI)的实现,由管理者将JNDI API 映射为特定的命名服务和目录系统,使得 Java 应用程序可以和这些命名服务和目录服务直接进行交互。

漏洞挖掘

  1. 确定反序列化的输入点

    首先再出readObject()方法的调用,找到之后进行下一步的注入操作

    查找方法

    • 源码审计:寻找可以利用的靶点,确定调用反序列化函数readObject() 的调用点

    • 流量抓包:一般都有固定的流量特征

      黑盒流量分析(奇安信秋招面试题)

      在 Java反序列化传送的包中,一般有两种传送方式

      1. TCP 传输,在TCP报文中,一般是二进制流的方式。流量特征:aced0005,这个16进制流基本上意味着Java反序列化的开始
      2. HTTP 传输,在HTTP报文中,大多以base64传输。流量特征:rO0AB,其实是 aced0005的base64编码的结果

      流量中有以上特征,意味着存在Java反序列化,可尝试构造payload

      白盒代码审计

      1. 观察实现了Serializable 接口的类是否存在问题
      2. 观察重写了readObject方法的函数逻辑是否存在问题
  2. 再考察应用的Class Path中是否包含Apache Commons Collections库

  3. 生成反序列化 payload

  4. 执行payload

漏洞防御

  1. 类的白名单校验机制

    • 传入的的数据在反序列化之前,对类型名做一个检测,不符合白名单的类不进行反序列化操作。
    • 例如:Runtime 肯定不会在白名单中
  2. 禁止JVM执行外部命令 Runtime.exec

    这个举措可以通过扩展 SecurityManager 可以实现

序列化与反序列化代码

Fun.java

package com.test;

import java.io.*;

public class Fun {

    public static void main(String args[]) throws IOException, ClassNotFoundException {
        Fun f = new Fun();
        f.ser();
        f.unser();
            //System.out.println(f);
    }

	//序列化
    public void ser() throws IOException {
        FileOutputStream fos = new FileOutputStream("test.txt");       //实例化文件输出流
        ObjectOutputStream oos = new ObjectOutputStream(fos);                //实例化对象输出流,输出到fos对象
        Stu stu1= new Stu();
        stu1.setId(1);
        stu1.setName("Alice");
        oos.writeObject(stu1);      //将stu1 写入对象流,存储在本地
        oos.close();                //关闭对象输出流
        //fos.close();                //关闭文件输出流
        System.out.println("Serializable Success");

    }

    //反序列化
    public void unser() throws IOException, ClassNotFoundException {
        FileInputStream ins = new FileInputStream("test.txt");          //实例化文件输入流
        ObjectInputStream ois = new ObjectInputStream(ins);                   //实例化对象输入流,从ins对象中获取数据
        Stu stu2 = (Stu) ois.readObject();
        System.out.println("Unserializbale Success");
        System.out.println(stu2.getName());

    }
}

Stu.java

package com.test;

import java.io.Serializable;

public class Stu implements Serializable {
    int id;
    String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

参考文章

浅谈Java反序列化漏洞原理

JAVA反序列化漏洞浅析

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-06 11:02:26  更:2021-09-06 11:03:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:25:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码