Web安全--反序列化漏洞(java篇)

这篇具有很好参考价值的文章主要介绍了Web安全--反序列化漏洞(java篇)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0x00 简介

序列化的意义就在于方便存储和传输,永久的保存到硬盘中,通常保存在一个文件中。

序列化:将java对象转换为字节序列的过程

反序列化:序列化的逆过程,从储存区读出字节序列还原成对象的过程

0x01 漏洞成因

java应用在对用户的输入没有进行严格的检查时,即传入了不可信的数据做反序列化操作,那么攻击者就可以传入恶意构造的输入,在进行反序列化时达到攻击者预想的效果。

0x02 实现

Java中的API实现:
位置:Java.io.ObjectOutputStream       java.io.ObjectlnputStream
序列化:ObjectOutputStream类-->writeObject()
注:该方法对参数指定的obj对象进行序列化,把字节序列写到一个目标输出流中按Java的标准约定是给文件一个.ser扩展名

反序列化:ObjectInoutStream类-->readObject()
注:该方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

00 Serializable接口

将要序列化的类实现Serializable接口,表明该类是可序列化(Serializable接口是一个标记接口,不用实现任何方法。)

package test1;

import java.io.Serializable;
public class user implements Serializable{
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    private String name;
}

序列化

package test1;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class UserSerializable {
    public static void main(String[] args) throws Exception {
        user user = new user();
        user.setName("biu");
        //序列化对象
        serialize(user);
    }
        public static void serialize(user user) throws Exception {
            FileOutputStream fout = new FileOutputStream("user.ser");
            ObjectOutputStream out = new ObjectOutputStream(fout);
            //利用ObjectOutputStream类的函数writeObject对对象进行序列化
            out.writeObject(user);
            out.close();
            fout.close();
            System.out.println("序列化完成.");
    }
}

序列化结果

java中存在不安全的反序列化操作,起直接将传入的file参数数据进行反序列化,未做任,java,开发语言

反序列化

package test1;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileInputStream;


public class UserSerializable {
    public static void main(String[] args) throws Exception {
        user user = new user();
        user.setName("biu");
        //序列化对象
        serialize(user);
        //反序列化
        user user1 = unserialize();
        user1.setName("biubiu");
        System.out.println(user1.getName());
    }
        //模拟序列化的自定义函数
        public static void serialize(user user) throws Exception {
            FileOutputStream fout = new FileOutputStream("user.ser");
            ObjectOutputStream out = new ObjectOutputStream(fout);
            out.writeObject(user);
            out.close();
            fout.close();
            System.out.println("序列化完成.");
    }
        //模拟反序列化的自定义函数
        public static user unserialize() throws Exception{
            //读取二进制文件
            FileInputStream fileIn = new FileInputStream("user.ser");
            //new一个ObjectInputStream对象
            ObjectInputStream in = new ObjectInputStream(fileIn);
            //利用ObjectInputStream类的readObject()方法对对象反序列化
            user user = (user) in.readObject();
            in.close();
            fileIn.close();
            System.out.println("反序列化完成.");
            return user;
        }
}

反序列化结果

将二进制文件反序列化为一个新的对象,重新对name进行赋值

java中存在不安全的反序列化操作,起直接将传入的file参数数据进行反序列化,未做任,java,开发语言

 01 Externalizable接口

实现Externalizable接口进行序列化和反序列化,必须实现writeExternal、readExternal方法,并且还要实现一个类的无参构造方法。

package test1;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class biu implements Externalizable {
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    private String name;
    //实现无参构造方法
    public biu(){
        System.out.println(this.getClass()+"无参构造方法被调用");
    }
    //实现writeExternal方法
    public void writeExternal(ObjectOutput out) throws IOException {}
    //实现readExternal方法
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {}
}

用法和Serializable接口一样,这里只展示结果

序列化结果

java中存在不安全的反序列化操作,起直接将传入的file参数数据进行反序列化,未做任,java,开发语言

java中存在不安全的反序列化操作,起直接将传入的file参数数据进行反序列化,未做任,java,开发语言

反序列化结果

 将二进制文件反序列化为一个新的对象,重新对name进行赋值

java中存在不安全的反序列化操作,起直接将传入的file参数数据进行反序列化,未做任,java,开发语言

0x03 readObject()方法

这个方法在反序列化漏洞中起到了重要的作用,因为在序列化过程中,JVM虚拟机会试图调用对象类里的 writeObject()readObject() 方法,进行用户自定义的序列化和反序列化,如果没有这样的方法,则默认调用是 ObjectOutputStreamdefaultWriteObject() 方法以及 ObjectInputStreamdefaultReadObject() 方法。

实现了Serializable接口可以执行的方法包括readObject()readObjectNoData()readResolve(),以及实现了Externalizable接口readExternal()方法。这些在找反序列化漏洞时都需要重点关注。

package test1;

import java.io.ObjectInputStream;
import java.io.Serializable;
public class user implements Serializable{
    public user(){
        System.out.println(this.getClass()+"无参构造方法被调用");
    }
    public user(String name){
        System.out.println(this.getClass()+"user(String name)构造方法被调用");
        this.name=name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String toString(){
        System.out.println(this.getClass() + "的toString()被调用");
        return "userclass{name="+getName()+"}";
    }
    private void readObject(ObjectInputStream in) throws Exception{
        //执行默认的readObject()方法
        in.defaultReadObject();
        System.out.println(this.getClass() + "的readObject()被调用");
        //windows重点
        Runtime.getRuntime().exec(new String[]{"cmd", "/c", name});
    }
    private String name;
}

在readObject()方法中存在Runtime.getRuntime().exec(new String[]{"cmd", "/c", name});name为执行命令参数,那么我们可以构造一个恶意的对象,将name赋值为我们想要执行的命令,那么当反序列化时就可以触发readObject()造成RCE。

00 序列化与反序列化

package test1;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.FileInputStream;


public class UserSerializable {
    public static void main(String[] args) throws Exception {
        user user = new user("calc");
        user.setName("calc");
        //序列化对象
        serialize(user);
        //反序列化
        user user1 = unserialize();
        System.out.println(user1);
    }
        public static void serialize(user user) throws Exception {
            FileOutputStream fout = new FileOutputStream("user.ser");
            ObjectOutputStream out = new ObjectOutputStream(fout);
            out.writeObject(user);
            out.close();
            fout.close();
            System.out.println("序列化完成.");
    }
        public static user unserialize() throws Exception{

            FileInputStream fileIn = new FileInputStream("user.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            user user = (user) in.readObject();
            in.close();
            fileIn.close();
            System.out.println("反序列化完成.");
            return user;
        }
}

01 结果

class test1.useruser(String name)构造方法被调用
class test1.user的setName()被调用
序列化完成.
class test1.user的readObject()被调用
反序列化完成.
class test1.user的toString()被调用
userclass{name=calc}

java中存在不安全的反序列化操作,起直接将传入的file参数数据进行反序列化,未做任,java,开发语言

可以看到在上图中不仅触发了重写的readObject()方法弹出calc程序,而且还触发了如toString()方法、setName()方法等,所以在实际寻找利用链时应该不局限于readObject()方法,其他方法中如果有执行命令的函数也可以进行利用。

当然,在实际情况中不可能会出现开发这样编写代码,这里是为了方便展示而进行编写,所以反序列化漏洞通常会需要Java的一些特性进行配合比如反射(invoke),然后就是利用链的寻找。

一般,java反序列化漏洞需要三个东西

1、反序列化入口

2、目标方法

3、利用链

0x04 补充知识点

00 下方的特征可以作为序列化的标志参考

数据以rO0AB开头,基本可以确定这串就是JAVA序列化base64加密的数据。

如果以aced开头,那么他就是这一段java序列化的16进制

01 利用工具

ysoserial是一个生成序列化payload数据的工具。

java -jar ysoserial-0.0.4-all.jar CommonsCollections1 '想要执行的命令' > payload.out

下载地址:发布 ·弗罗霍夫/伊索系列 (github.com) 

参考

初探Java反序列化漏洞(一)_51CTO博客_java 反序列化

清晰易懂java反序列化漏洞简介_1024zz的博客-CSDN博客_java反序列化漏洞文章来源地址https://www.toymoban.com/news/detail-704319.html

到了这里,关于Web安全--反序列化漏洞(java篇)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java反序列化:URLDNS的反序列化调试分析

    URLDNS链子是Java反序列化分析的第0课,网上也有很多优质的分析文章。 笔者作为Java安全初学者,也从0到1调试了一遍,现在给出调试笔记。 Java原生链序列化:利用Java.io.ObjectInputStream对象输出流的writerObject方法实现Serializable接口,将对象转化成字节序列。 Java原生链反序列化

    2024年02月15日
    浏览(37)
  • Java反序列化(0):URLDNS的反序列化调试分析

    URLDNS链子是Java反序列化分析的第0课,网上也有很多优质的分析文章。 笔者作为Java安全初学者,也从0到1调试了一遍,现在给出调试笔记。 Java原生链序列化:利用Java.io.ObjectInputStream对象输出流的writerObject方法实现Serializable接口,将对象转化成字节序列。 Java原生链反序列化

    2024年02月16日
    浏览(49)
  • owasp top10之不安全的反序列化

    ​ 更多网络安全干货内容: 点此获取 ——————— Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。 将序列化对象写入文件之后,可以从文件中读取

    2024年01月22日
    浏览(48)
  • 【java安全】FastJson反序列化漏洞浅析

    0x00.前言 前面我们学习了RMI和JNDI知识,接下来我们就可以来了解一下FastJson反序列化了 0x01.FastJson概述 FastJson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持 将JavaBean序列化为JSON字符串,也可以将JSON字符串反序列化到JavaBean 0x02.FastJson使用 首先我们需要使用

    2024年02月11日
    浏览(51)
  • 漏洞预警|Apache Linkis 存在反序列化漏洞

    近日网上有关于开源项目Apache Linkis 存在反序列化漏洞,棱镜七彩威胁情报团队第一时间探测到,经分析研判,向全社会发起开源漏洞预警公告,提醒相关安全团队及时响应。 Apache Linkis 在上层应用程序和底层引擎之间构建了一层计算中间件。通过使用Linkis 提供的REST/WebSoc

    2023年04月15日
    浏览(39)
  • 由Django-Session配置引发的反序列化安全问题

    漏洞成因位于目标配置文件settings.py下 关于这两个配置项 SESSION_ENGINE: 在Django中, SESSION_ENGINE  是一个设置项,用于指定用于存储和处理会话(session)数据的引擎。 SESSION_ENGINE  设置项允许您选择不同的后端引擎来存储会话数据,例如: 数据库后端  ( django.contrib.sessions.b

    2024年02月08日
    浏览(50)
  • 38-WEB漏洞-反序列化之PHP&JAVA全解(下)

    序列化(Serialization):将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。 反序列化:从存储区中读取该数据,并将其还原为对象的过程,成为反序列化。 1、主函数: 调用序列化方法 将反序列化的的结果

    2024年01月25日
    浏览(47)
  • 37-WEB漏洞-反序列化之PHP&JAVA全解(上)

    未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL 注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。 2.1.1、本地 unserialize2.php flag.

    2024年01月22日
    浏览(44)
  • Java安全研究——反序列化漏洞之CC链

    apache commons-collections组件下的反序列化漏洞,自从该组件被爆出漏洞后,许多安全研究员相继挖掘到java多种组件的漏洞,危害严重。本人也是初学Java审计不久,技术薄弱,所以在此做一个cc链的学习总结,如有错误还请大佬指出。 若本文有侵权行为,请立即私信,将全面修

    2024年02月04日
    浏览(59)
  • 【java安全】Log4j反序列化漏洞

    关于Apache Log4j Log4j是Apache的开源项目,可以实现对System.out等打印语句的替代,并且可以结合spring等项目,实现把日志输出到控制台或文件等。而且它还可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码,满足了大多数要求。 就是用来打印日志的 漏洞成因

    2024年02月11日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包